Skip to content

Commit fa20564

Browse files
authored
Add the ability to access registered variables from expressions within tables (#37)
* Added the ability to access registered variables from expressions within tables * Added test
1 parent f4e926b commit fa20564

File tree

6 files changed

+25
-10
lines changed

6 files changed

+25
-10
lines changed

ClosedXML.Report/RangeInterpreter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public virtual void EvaluateValues(IXLRange range, params Parameter[] pars)
134134
continue;
135135

136136
var items = datas as object[] ?? datas.Cast<object>().ToArray();
137-
var tplt = RangeTemplate.Parse(nr, _errors);
137+
var tplt = RangeTemplate.Parse(nr, _errors, _variables);
138138
var nrng = nr.Ranges.First();
139139
using (var buff = tplt.Generate(items))
140140
{

ClosedXML.Report/RangeTemplate.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Collections;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Linq;
54
using System.Linq.Dynamic.Core.Exceptions;
65
using ClosedXML.Excel;
@@ -30,43 +29,45 @@ public class RangeTemplate
3029
private IXLConditionalFormat[] _condFormats;
3130
private IXLConditionalFormat[] _totalsCondFormats;
3231
private bool _isSubrange;
32+
private IDictionary<string, object> _globalVariables;
3333

3434
public string Source { get; private set; }
3535
public string Name { get; private set; }
3636

37-
internal RangeTemplate(IXLNamedRange range, TempSheetBuffer buff, TemplateErrors errors)
37+
internal RangeTemplate(IXLNamedRange range, TempSheetBuffer buff, TemplateErrors errors, IDictionary<string, object> globalVariables)
3838
{
3939
_rowRange = range.Ranges.First();
4040
_cells = new TemplateCells(this);
4141
_tagsEvaluator = new TagsEvaluator();
4242
var wb = _rowRange.Worksheet.Workbook;
4343
_buff = buff;
4444
_errors = errors;
45+
_globalVariables = globalVariables;
4546
_tags = new TagsList(_errors);
4647
_rangeTags = new TagsList(_errors);
4748
Name = range.Name;
4849
Source = range.Name;
4950
wb.NamedRanges.Add(range.Name + "_tpl", range.Ranges);
5051
}
5152

52-
internal RangeTemplate(IXLNamedRange range, TempSheetBuffer buff, int rowCnt, int colCnt, TemplateErrors errors) : this(range, buff, errors)
53+
internal RangeTemplate(IXLNamedRange range, TempSheetBuffer buff, int rowCnt, int colCnt, TemplateErrors errors, IDictionary<string, object> globalVariables) : this(range, buff, errors, globalVariables)
5354
{
5455
_rowCnt = rowCnt;
5556
_colCnt = colCnt;
5657
}
5758

5859

59-
public static RangeTemplate Parse(IXLNamedRange range, TemplateErrors errors)
60+
public static RangeTemplate Parse(IXLNamedRange range, TemplateErrors errors, IDictionary<string, object> globalVariables)
6061
{
6162
var wb = range.Ranges.First().Worksheet.Workbook;
62-
return Parse(range, new TempSheetBuffer(wb), errors);
63+
return Parse(range, new TempSheetBuffer(wb), errors, globalVariables);
6364
}
6465

65-
private static RangeTemplate Parse(IXLNamedRange range, TempSheetBuffer buff, TemplateErrors errors, RangeTemplate parent = null)
66+
private static RangeTemplate Parse(IXLNamedRange range, TempSheetBuffer buff, TemplateErrors errors, IDictionary<string, object> globalVariables)
6667
{
6768
var prng = range.Ranges.First();
6869
var result = new RangeTemplate(range, buff,
69-
prng.RowCount(), prng.ColumnCount(), errors);
70+
prng.RowCount(), prng.ColumnCount(), errors, globalVariables);
7071

7172
var innerRanges = GetInnerRanges(prng).ToArray();
7273

@@ -109,9 +110,10 @@ private static RangeTemplate Parse(IXLNamedRange range, TempSheetBuffer buff, Te
109110

110111
result._subranges = innerRanges.Select(rng =>
111112
{
112-
var tpl = Parse(rng, buff, errors, result);
113+
var tpl = Parse(rng, buff, errors, globalVariables);
113114
tpl._buff = result._buff;
114115
tpl._isSubrange = true;
116+
tpl._globalVariables = globalVariables;
115117
return tpl;
116118
}).ToArray();
117119

@@ -143,6 +145,10 @@ public IReportBuffer Generate(object[] items)
143145
{
144146
var evaluator = new FormulaEvaluator();
145147
evaluator.AddVariable("items", items);
148+
foreach (var v in _globalVariables)
149+
{
150+
evaluator.AddVariable("@"+v.Key, v.Value);
151+
}
146152
_rangeTags.Reset();
147153

148154
if (IsHorizontal)
@@ -321,7 +327,6 @@ private void RenderSubrange(object item, FormulaEvaluator evaluator, TemplateCel
321327

322328
private void HorizontalTable(object[] items, FormulaEvaluator evaluator)
323329
{
324-
var rangeStart = _buff.NextAddress;
325330
var tags = _tags.CopyTo(_rowRange);
326331
for (int i = 0; i < items.Length; i++)
327332
{

tests/ClosedXML.Report.Tests/FormulaEvaluatorTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public void ParseExceptionMessageShouldBeUnknownIdentifier()
5757
.Message.Should().Be("Unknown identifier 'item'");
5858
}
5959

60+
[Fact]
61+
public void EvalExpressionVariableWithAt()
62+
{
63+
var eval = new FormulaEvaluator();
64+
eval.AddVariable("@a", 1);
65+
eval.Evaluate("{{@a+@a}}").Should().Be(2);
66+
}
67+
6068
class Customer
6169
{
6270
public int Id { get; set; }

tests/ClosedXML.Report.Tests/GroupTagTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public GroupTagTests(ITestOutputHelper output) : base(output)
2020
InlineData("tLists2_sum.xlsx"),
2121
InlineData("tLists3_options.xlsx"),
2222
InlineData("tLists4_complexRange.xlsx"),
23+
InlineData("tLists5_GlobalVars.xlsx"),
2324
InlineData("tPage1_options.xlsx"),
2425
]
2526
public void Simple(string templateFile)
@@ -32,6 +33,7 @@ public void Simple(string templateFile)
3233
var cust = db.customers.LoadWith(x => x.Orders).OrderBy(c => c.CustNo).First(x=>x.CustNo == 1356);
3334
tpl.AddVariable(cust);
3435
}
36+
tpl.AddVariable("Tax", 13);
3537
},
3638
wb =>
3739
{

tests/Gauges/tLists5_GlobalVars.xlsx

22.7 KB
Binary file not shown.
21.9 KB
Binary file not shown.

0 commit comments

Comments
 (0)