Skip to content

Commit 5234893

Browse files
authored
Merge pull request #160 from spreadsheetlab/merge-table-references
Merge intersection of table references
2 parents a70802e + 9fcbc24 commit 5234893

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

src/XLParser.Tests/FormulaAnalysisTest.cs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Collections.ObjectModel;
1+
using System.Collections.Generic;
42
using System.Linq;
53
using Microsoft.VisualStudio.TestTools.UnitTesting;
64
using Irony.Parsing;
7-
using System.Globalization;
8-
using XLParser;
95

106
namespace XLParser.Tests
117
{
@@ -410,17 +406,11 @@ public void StructuredTableReferenceMultipleRows()
410406
{
411407
List<ParserReference> references = new FormulaAnalyzer("=SUM([@Jan]:[@Feb])").ParserReferences().ToList();
412408

413-
Assert.AreEqual(2, references.Count);
414-
415-
Assert.AreEqual(ReferenceType.Table, references[0].ReferenceType);
416-
Assert.AreEqual(null, references[0].Name);
417-
CollectionAssert.AreEqual(new[] {"@"}, references[0].TableSpecifiers);
418-
CollectionAssert.AreEqual(new[] {"Jan"}, references[0].TableColumns);
419-
420-
Assert.AreEqual(ReferenceType.Table, references[1].ReferenceType);
421-
Assert.AreEqual(null, references[1].Name);
422-
CollectionAssert.AreEqual(new[] {"@"}, references[1].TableSpecifiers);
423-
CollectionAssert.AreEqual(new[] {"Feb"}, references[1].TableColumns);
409+
Assert.AreEqual(1, references.Count);
410+
Assert.AreEqual(ReferenceType.Table, references.First().ReferenceType);
411+
Assert.AreEqual(null, references.First().Name);
412+
CollectionAssert.AreEqual(new[] {"@"}, references.First().TableSpecifiers);
413+
CollectionAssert.AreEqual(new[] {"Jan", "Feb"}, references.First().TableColumns);
424414
}
425415

426416
[TestMethod]
@@ -449,17 +439,54 @@ public void StructuredTableReferenceMultipleHeaders()
449439
{
450440
List<ParserReference> references = new FormulaAnalyzer("=COUNTA(Sales_5[[#Headers],[Jan]]:Sales_5[[#Headers],[Mar]])").ParserReferences().ToList();
451441

452-
Assert.AreEqual(2, references.Count);
442+
Assert.AreEqual(1, references.Count);
453443

454444
Assert.AreEqual(ReferenceType.Table, references[0].ReferenceType);
455445
Assert.AreEqual("Sales_5", references[0].Name);
456446
CollectionAssert.AreEqual(new[] {"#Headers"}, references[0].TableSpecifiers);
447+
CollectionAssert.AreEqual(new[] {"Jan", "Mar"}, references[0].TableColumns);
448+
}
449+
450+
[TestMethod]
451+
public void StructuredTableReferenceIntersectColumns()
452+
{
453+
List<ParserReference> references = new FormulaAnalyzer("=SUM(Sales_2[Jan]:Sales_2[Feb])").ParserReferences().ToList();
454+
455+
Assert.AreEqual(1, references.Count);
456+
Assert.AreEqual(ReferenceType.Table, references.First().ReferenceType);
457+
Assert.AreEqual("Sales_2", references.First().Name);
458+
CollectionAssert.AreEqual(new string[] {}, references.First().TableSpecifiers);
459+
CollectionAssert.AreEqual(new[] {"Jan", "Feb"}, references.First().TableColumns);
460+
}
461+
462+
[TestMethod]
463+
public void StructuredTableReferenceIntersectDifferentSpecifiers()
464+
{
465+
List<ParserReference> references = new FormulaAnalyzer("=COUNTA(Sales_2[[#Headers],[Jan]]:Sales_2[[#Data],[Feb]])").ParserReferences().ToList();
466+
467+
Assert.AreEqual(1, references.Count);
468+
Assert.AreEqual(ReferenceType.Table, references.First().ReferenceType);
469+
Assert.AreEqual("Sales_2", references.First().Name);
470+
CollectionAssert.AreEqual(new string[] {}, references.First().TableSpecifiers);
471+
CollectionAssert.AreEqual(new[] {"Jan", "Feb"}, references.First().TableColumns);
472+
}
473+
474+
[TestMethod]
475+
public void StructuredTableReferenceIntersectDifferentTables()
476+
{
477+
List<ParserReference> references = new FormulaAnalyzer("=COUNTA(Sales_2[Jan]:Sales_4[Feb])").ParserReferences().ToList();
478+
479+
Assert.AreEqual(2, references.Count);
480+
481+
Assert.AreEqual(ReferenceType.Table, references[0].ReferenceType);
482+
Assert.AreEqual("Sales_2", references[0].Name);
483+
CollectionAssert.AreEqual(new string[] {}, references[0].TableSpecifiers);
457484
CollectionAssert.AreEqual(new[] {"Jan"}, references[0].TableColumns);
458485

459486
Assert.AreEqual(ReferenceType.Table, references[1].ReferenceType);
460-
Assert.AreEqual("Sales_5", references[1].Name);
461-
CollectionAssert.AreEqual(new[] {"#Headers"}, references[1].TableSpecifiers);
462-
CollectionAssert.AreEqual(new[] {"Mar"}, references[1].TableColumns);
487+
Assert.AreEqual("Sales_4", references[1].Name);
488+
CollectionAssert.AreEqual(new string[] {}, references[1].TableSpecifiers);
489+
CollectionAssert.AreEqual(new[] {"Feb"}, references[1].TableColumns);
463490
}
464491

465492
[TestMethod]

src/XLParser/ExcelFormulaParser.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,13 @@ public static IEnumerable<ParserReference> GetParserReferences(this ParseTreeNod
435435
range.LocationString = node.Print();
436436
list.Add(range);
437437
}
438+
else if (IsTableReference(rangeStart) && IsTableReference(rangeEnd) && rangeStart.First().Name == rangeEnd.First().Name && rangeStart.First().TableColumns.Length == 1 && rangeEnd.First().TableColumns.Length == 1)
439+
{
440+
ParserReference range = rangeStart.First();
441+
range.TableColumns = rangeStart.First().TableColumns.Concat(rangeEnd.First().TableColumns).ToArray();
442+
range.TableSpecifiers = rangeStart.First().TableSpecifiers.SequenceEqual(rangeEnd.First().TableSpecifiers) ? range.TableSpecifiers : new string[0];
443+
list.Add(range);
444+
}
438445
else
439446
{
440447
list.AddRange(rangeStart);
@@ -455,13 +462,17 @@ private static bool IsCellReference(IList<ParserReference> references)
455462
return references.Count == 1 && references.First().ReferenceType == ReferenceType.Cell;
456463
}
457464

465+
private static bool IsTableReference(IList<ParserReference> references)
466+
{
467+
return references.Count == 1 && references.First().ReferenceType == ReferenceType.Table;
468+
}
469+
458470
/// <summary>
459471
/// Whether or not this node represents a range
460472
/// </summary>
461473
public static bool IsRange(this ParseTreeNode input)
462474
{
463-
return input.IsBinaryReferenceOperation() &&
464-
input.ChildNodes[1].Is(":");
475+
return input.IsBinaryReferenceOperation() && input.ChildNodes[1].Is(":");
465476
}
466477

467478
/// <summary>

0 commit comments

Comments
 (0)