Skip to content

Commit 58b8f86

Browse files
committed
LOG10 function is not a cell func
Parser accepts cell references as functions, e.g. $A$1(45). When formula is converted between A1 and R1C1, make sure the LOG10 is *not* interpreted as a cell function. That would cause all sorts of problems with shifting or deleting areas. Example: LOG10 would be turned to R1C1, the reference would shift and then be turned back.
1 parent 225f201 commit 58b8f86

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/ClosedXML.Parser.Tests/RefModVisitorTests.cs

+15
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ public void Bang_references_is_modified(string formula, string reference, string
7171
AssertChangesA1(formula, factory, modifiedFormula);
7272
}
7373

74+
[Fact]
75+
public void Log10_is_not_interpreted_as_cell_function()
76+
{
77+
var factory = new ShiftReferenceVisitor { ReferenceMap = { { "LOG10", "A1"} } };
78+
AssertChangesA1("LOG10(LOG10)", factory, "LOG10(A1)");
79+
}
80+
7481
private static void AssertChangesA1(string formula, RefModVisitor visitor, string expected)
7582
{
7683
var ctx = new ModContext(formula, "Sheet", 1, 1, isA1: true);
@@ -99,5 +106,13 @@ private class ShiftReferenceVisitor : RefModVisitor
99106

100107
return reference;
101108
}
109+
110+
internal override RowCol? ModifyCellFunction(ModContext ctx, RowCol cell)
111+
{
112+
if (ReferenceMap.TryGetValue(cell.GetDisplayStringA1(), out var replacement))
113+
return replacement is not null ? ReferenceParser.ParseA1(replacement).First : null;
114+
115+
return cell;
116+
}
102117
}
103118
}

src/ClosedXML.Parser/RefModVisitor.cs

+9
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ public TransformedSymbol ExternalFunction(ModContext ctx, SymbolRange range, int
193193
/// <inheritdoc />
194194
public TransformedSymbol CellFunction(ModContext ctx, SymbolRange range, RowCol cell, IReadOnlyList<TransformedSymbol> arguments)
195195
{
196+
// Parser doesn't detect LOG10 as a function (there is no list of functions),
197+
// but as a cell function. Make sure not to transform it.
198+
var functionName = ctx.Formula.AsSpan(range.Start, ctx.Formula.IndexOf('(', range.Start) - range.Start);
199+
if (functionName.Equals("LOG10".AsSpan(), StringComparison.OrdinalIgnoreCase))
200+
{
201+
var modifiedName = ModifyFunction(ctx, functionName);
202+
return s_copyVisitor.Function(ctx, range, modifiedName, arguments);
203+
}
204+
196205
var modifiedCell = ModifyCellFunction(ctx, cell);
197206
if (modifiedCell is null)
198207
return TransformedSymbol.ToText(ctx.Formula, range, REF_ERROR);

0 commit comments

Comments
 (0)