Skip to content

Commit

Permalink
LOG10 function is not a cell func
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jahav committed Dec 26, 2024
1 parent 225f201 commit 58b8f86
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/ClosedXML.Parser.Tests/RefModVisitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ public void Bang_references_is_modified(string formula, string reference, string
AssertChangesA1(formula, factory, modifiedFormula);
}

[Fact]
public void Log10_is_not_interpreted_as_cell_function()
{
var factory = new ShiftReferenceVisitor { ReferenceMap = { { "LOG10", "A1"} } };
AssertChangesA1("LOG10(LOG10)", factory, "LOG10(A1)");
}

private static void AssertChangesA1(string formula, RefModVisitor visitor, string expected)
{
var ctx = new ModContext(formula, "Sheet", 1, 1, isA1: true);
Expand Down Expand Up @@ -99,5 +106,13 @@ private class ShiftReferenceVisitor : RefModVisitor

return reference;
}

internal override RowCol? ModifyCellFunction(ModContext ctx, RowCol cell)
{
if (ReferenceMap.TryGetValue(cell.GetDisplayStringA1(), out var replacement))
return replacement is not null ? ReferenceParser.ParseA1(replacement).First : null;

return cell;
}
}
}
9 changes: 9 additions & 0 deletions src/ClosedXML.Parser/RefModVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ public TransformedSymbol ExternalFunction(ModContext ctx, SymbolRange range, int
/// <inheritdoc />
public TransformedSymbol CellFunction(ModContext ctx, SymbolRange range, RowCol cell, IReadOnlyList<TransformedSymbol> arguments)
{
// Parser doesn't detect LOG10 as a function (there is no list of functions),
// but as a cell function. Make sure not to transform it.
var functionName = ctx.Formula.AsSpan(range.Start, ctx.Formula.IndexOf('(', range.Start) - range.Start);
if (functionName.Equals("LOG10".AsSpan(), StringComparison.OrdinalIgnoreCase))
{
var modifiedName = ModifyFunction(ctx, functionName);
return s_copyVisitor.Function(ctx, range, modifiedName, arguments);
}

var modifiedCell = ModifyCellFunction(ctx, cell);
if (modifiedCell is null)
return TransformedSymbol.ToText(ctx.Formula, range, REF_ERROR);
Expand Down

0 comments on commit 58b8f86

Please sign in to comment.