Skip to content

Commit 88785fd

Browse files
authored
Update FormulaParser.cs
Add support for array formulae in arguments. Ex: =SomeFunction({1,2}, {3,
1 parent 449b594 commit 88785fd

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

Source/ExcelDna.IntelliSense/UIMonitor/FormulaParser.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,32 @@ static class FormulaParser
1717
internal static bool TryGetFormulaInfo(string formulaPrefix, out string functionName, out int currentArgIndex)
1818
{
1919
Debug.Assert(formulaPrefix != null);
20-
20+
21+
// Hide the strings, in order to ignore the commas, parenthesis and curly brackets which might be inside.
22+
// Ex: =SomeFunction("a", "b,c(d,{e,f,
23+
// In the example above, the function is SomeFunction, and the index is 2
24+
25+
// If editing a string, then close the double-quotes
2126
if (formulaPrefix.Count(c => c == '\"') % 2 != 0)
2227
{
2328
formulaPrefix = string.Concat(formulaPrefix, '\"');
2429
}
2530

26-
formulaPrefix = Regex.Replace(formulaPrefix, "(\"[^\"]*\")|(\\([^\\(\\)]*\\))| ", string.Empty);
31+
// Remove the strings.
32+
// Note: in Excel, in order to put a double-quotes in a string, one has to double the double-quotes.
33+
// For instance, "a""b" for a"b. Since we only want to hide the strings in order to count the commas,
34+
// the regex below still applies.
35+
formulaPrefix = Regex.Replace(formulaPrefix, "(\"[^\"]*\")", string.Empty);
36+
37+
// Remove sub-formulae
38+
formulaPrefix = Regex.Replace(formulaPrefix, "(\\([^\\(\\)]*\\))| ", string.Empty);
2739

2840
while (Regex.IsMatch(formulaPrefix, "\\([^\\(\\)]*\\)"))
2941
{
3042
formulaPrefix = Regex.Replace(formulaPrefix, "\\([^\\(\\)]*\\)", string.Empty);
3143
}
3244

45+
// Find the function name and the argument index
3346
int lastOpeningParenthesis = formulaPrefix.LastIndexOf("(", formulaPrefix.Length - 1, StringComparison.Ordinal);
3447

3548
if (lastOpeningParenthesis > -1)
@@ -38,7 +51,24 @@ internal static bool TryGetFormulaInfo(string formulaPrefix, out string function
3851
if (match.Success)
3952
{
4053
functionName = match.Groups[functionNameGroupName].Value;
41-
currentArgIndex = formulaPrefix.Substring(lastOpeningParenthesis, formulaPrefix.Length - lastOpeningParenthesis).Count(c => c == ListSeparator);
54+
55+
string argumentsPart = formulaPrefix.Substring(lastOpeningParenthesis, formulaPrefix.Length - lastOpeningParenthesis);
56+
57+
// Hide array formulae
58+
// Ex: =SomeFunction("a", {"a", "b", "c"
59+
// In the example above the index is 2
60+
61+
// If editing an array, then close the curly bracket.
62+
// Since we already removed the strings, there won't be any curly brackets within a string.
63+
if (argumentsPart.Count(c => c == '{') > argumentsPart.Count(c => c == '}'))
64+
{
65+
argumentsPart = string.Concat(argumentsPart, '}');
66+
}
67+
68+
// Remove the arrays.
69+
argumentsPart = Regex.Replace(argumentsPart, "(\\{[^\\}]*\\})", string.Empty);
70+
71+
currentArgIndex = argumentsPart.Count(c => c == ListSeparator);
4272
return true;
4373
}
4474
}

0 commit comments

Comments
 (0)