Skip to content

Commit 728e211

Browse files
authored
Merge pull request #181 from spreadsheetlab/fix-issue-180
Fix: invalid parser reference for range with reference in function
2 parents 93835aa + 0141667 commit 728e211

2 files changed

Lines changed: 25 additions & 32 deletions

File tree

src/XLParser.Tests/FormulaAnalysisTest.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,18 @@ public void ReferenceFunctionAsArgument()
12241224
}
12251225

12261226
[TestMethod]
1227-
public void RangeWithReferenceFunction()
1227+
public void RangeWithReferenceInFunction()
1228+
{
1229+
List<ParserReference> references = new FormulaAnalyzer("SUM(F13:OFFSET(E13,0,12))").ParserReferences().ToList();
1230+
1231+
//no reference for the range with the offset function
1232+
Assert.AreEqual(2, references.Count);
1233+
Assert.AreEqual("F13", references.First().LocationString);
1234+
Assert.AreEqual("E13", references.Last().LocationString);
1235+
}
1236+
1237+
[TestMethod]
1238+
public void RangeWithReferencesInFunction()
12281239
{
12291240
List<ParserReference> references = new FormulaAnalyzer("SUM(A1:INDEX(A:A,1,1:1))").ParserReferences().ToList();
12301241

@@ -1275,7 +1286,6 @@ public void MultiAreaRangeFormula()
12751286
Assert.AreEqual("Sheet1!$A$1", references[0].LocationString);
12761287
Assert.AreEqual("Sheet1!$B$2", references[1].LocationString);
12771288
}
1278-
12791289
#endregion
12801290

12811291
#region Depth() and ConditionalComplexity()

src/XLParser/ExcelFormulaParser.cs

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text;
54
using Irony.Parsing;
65

76
namespace XLParser
@@ -425,57 +424,41 @@ public static IEnumerable<ParserReference> GetParserReferences(this ParseTreeNod
425424
default:
426425
if (node.IsRange())
427426
{
428-
var rangeStart = GetParserReferences(node.ChildNodes[0].SkipToRelevant()).ToArray();
429-
var rangeEnd = GetParserReferences(node.ChildNodes[2].SkipToRelevant()).ToArray();
430-
if (IsCellReference(rangeStart) && IsCellReference(rangeEnd))
427+
var rangeStart = GetParserReferences(node.ChildNodes[0].SkipToRelevant()).First();
428+
var rangeEnd = GetParserReferences(node.ChildNodes[2].SkipToRelevant()).First();
429+
if (rangeStart.ReferenceType == ReferenceType.Cell && rangeEnd.ReferenceType == ReferenceType.Cell)
431430
{
432-
ParserReference range = rangeStart.First();
433-
range.MaxLocation = rangeEnd.First().MinLocation;
431+
ParserReference range = rangeStart;
432+
range.MaxLocation = rangeEnd.MinLocation;
434433
range.ReferenceType = ReferenceType.CellRange;
435434
range.ReferenceNode = node;
436435
range.LocationString = node.Print();
437436
list.Add(range);
437+
break;
438438
}
439-
else if (IsTableReference(rangeStart) && IsTableReference(rangeEnd) && rangeStart.First().Name == rangeEnd.First().Name && rangeStart.First().TableColumns.Length == 1 && rangeEnd.First().TableColumns.Length == 1)
439+
if (rangeStart.ReferenceType == ReferenceType.Table && rangeEnd.ReferenceType == ReferenceType.Table && rangeStart.Name == rangeEnd.Name && rangeStart.TableColumns.Length == 1 && rangeEnd.TableColumns.Length == 1)
440440
{
441-
ParserReference range = rangeStart.First();
442-
range.TableColumns = rangeStart.First().TableColumns.Concat(rangeEnd.First().TableColumns).ToArray();
443-
range.TableSpecifiers = rangeStart.First().TableSpecifiers.SequenceEqual(rangeEnd.First().TableSpecifiers) ? range.TableSpecifiers : new string[0];
441+
ParserReference range = rangeStart;
442+
range.TableColumns = rangeStart.TableColumns.Concat(rangeEnd.TableColumns).ToArray();
443+
range.TableSpecifiers = rangeStart.TableSpecifiers.SequenceEqual(rangeEnd.TableSpecifiers) ? range.TableSpecifiers : new string[0];
444444
range.ReferenceNode = node;
445445
range.LocationString = node.Print();
446446
list.Add(range);
447-
}
448-
else
449-
{
450-
list.AddRange(rangeStart);
451-
list.AddRange(rangeEnd);
447+
break;
452448
}
453449
}
454-
else
455-
{
456-
list.AddRange(node.GetReferenceNodes().SelectMany(x => x.GetParserReferences()));
457-
}
450+
list.AddRange(node.GetReferenceNodes().SelectMany(x => x.GetParserReferences()));
458451
break;
459452
}
460453
return list;
461454
}
462455

463-
private static bool IsCellReference(IList<ParserReference> references)
464-
{
465-
return references.Count == 1 && references.First().ReferenceType == ReferenceType.Cell;
466-
}
467-
468-
private static bool IsTableReference(IList<ParserReference> references)
469-
{
470-
return references.Count == 1 && references.First().ReferenceType == ReferenceType.Table;
471-
}
472-
473456
/// <summary>
474457
/// Whether or not this node represents a range
475458
/// </summary>
476459
public static bool IsRange(this ParseTreeNode input)
477460
{
478-
return input.IsBinaryReferenceOperation() && input.ChildNodes[1].Is(":");
461+
return input.IsBinaryReferenceOperation() && input.ChildNodes[1].Is(":") && input.ChildNodes[0].ChildNodes.Last().Type() == input.ChildNodes[2].ChildNodes.Last().Type();
479462
}
480463

481464
/// <summary>

0 commit comments

Comments
 (0)