# 如何在C#中解析Excel公式

• 低於 2500：低於目標
• 超過 3000：達到目標
• 超過 5000：高於目標

=IF(ISNUMBER(FILTER(A2:D19,A2:A19="Fritz")),IFS(FILTER(A2:D19,A2:A19="Fritz")>5000,"Above Target",FILTER(A2:D19,A2:A19="Fritz")>3000,"On Target",FILTER(A2:D19,A2:A19="Fritz")<2500,"Below Target"),FILTER(A2:D19,A2:A19="Fritz"))

1、使用示例數據初始化工作簿

``````//Create a new workbook
var workbook = new GrapeCity.Documents.Excel.Workbook();
//Load sample data from excel file
workbook.Open("SampleData.xlsx");
//Enable dynamic array formula
workbook.AllowDynamicArray = true;
``````

2、提取公式

GcExcel API 提供的公式解析器希望傳遞的公式不帶“=”（等於）運算符，以便成功進行公式解析。因此，請注意如何在不使用“=”運算符的情況下提取公式。

``````//Fetch worksheet
var worksheet = workbook.Worksheets[0];
//Fetch the original formula which needs to be parsed.
var originalFormula = worksheet.Range["H3"].Formula.Substring(1);
``````

3、解析公式

``````//Method to parse a formula and print the syntax tree
public static void ParseAndPrint(IWorksheet worksheet, string formula)
{
// Get syntax tree
var syntaxTree = FormulaSyntaxTree.Parse(formula);

// Flatten nodes
var displayItems = new List<(string TypeName, int IndentLevel, string Content)>();

void flatten(SyntaxNode node, int level)
{
foreach (var child in node.Children)
{
flatten(child, level + 1);
}
}

flatten(syntaxTree.Root, 0);

// Output
worksheet.ShowRowOutline = false;
worksheet.OutlineColumn.ColumnIndex = 1;

worksheet.Range["A1"].Value = "Formula";
worksheet.Range["A3"].Value = "Syntax node";
worksheet.Range["B3"].Value = "Part";

// Values
worksheet.Range["B1"].Value = "'=" + formula;
for (var i = 0; i < displayItems.Count; i++)
{
var item = displayItems[i];
var text = "'" + item.TypeName;

worksheet.Range[i + 4, 0].Value = text;
worksheet.Range[i + 4, 0].IndentLevel = item.IndentLevel;
worksheet.Range[i + 4, 1].Value = "'" + item.Content;
}

//Apply styling
worksheet.Range["A1:B3"].Interior.Color = System.Drawing.Color.FromArgb(68, 114, 196);
worksheet.Range["A1:B3"].Font.Color = System.Drawing.Color.White;
worksheet.Range["A1:B3"].Borders.Color = System.Drawing.Color.FromArgb(91, 155, 213);
worksheet.Range["A1:B3"].Borders.LineStyle = BorderLineStyle.Thin;
worksheet.Range["A1,A3,B3"].Font.Size = 14;
worksheet.Range["A1,A3,B3"].Font.Bold = true;
worksheet.Range["A:C"].EntireColumn.AutoFit();
}
``````

4、修改公式

1. 了替換公式中的銷售代表姓名，我們從他們的姓名列表開始。我們使用 UNIQUE 函數從原始數據中過濾掉唯一名稱列表。然後使用這個 UNIQUE 函數的結果來解析和修改所有銷售代表的銷售分析公式。
2. 我們使用 TextNode 類修改銷售代表姓名。下面的代碼初始化 TextNode 類的實例，並將要在公式中搜索的銷售代表姓名作爲參數傳遞。該實例可以稱爲查找節點。
3. 接下來，我們初始化 TextNode 類的另一個實例，並將公式中要替換的銷售代表姓名作爲參數傳遞。該實例可以稱爲替換節點。
4. 下面的代碼中定義了一個遞歸函數 replaceNode，用於遍歷語法樹的所有子節點，並將每個出現的 Find 節點替換爲 Replace 節點。每個銷售代表都會重複此操作。
5. 修改公式後，新公式將分配給工作表中的單元格以生成預期的銷售報告。

``````//Method to parse and modify the formula
public static void ModifyFormula(IWorksheet worksheet, string originalFormula)
{
//Apply UNIQUE formula to get unique sales representatives list
worksheet.Range["F1"].Value = "Unique Rep";
worksheet.Range["F2"].Formula = "=UNIQUE(A2:A19)";
var uniqueRep = worksheet.Range["F2#"];
// Apply Styling
worksheet.Range["F:F"].EntireColumn.AutoFit();
worksheet.Range["F1"].Interior.Color = System.Drawing.Color.FromArgb(68, 114, 196);
worksheet.Range["F1"].Font.Color = System.Drawing.Color.White;
worksheet.Range["F2#"].Borders.Color = System.Drawing.Color.FromArgb(91, 155, 213);
worksheet.Range["F2#"].Borders.LineStyle = BorderLineStyle.Thin;

//Get syntax tree
var syntaxTree = FormulaSyntaxTree.Parse(originalFormula);

//Find
var findText = new TextNode("Fritz");

//Replacement
var replaceText = new TextNode("");

//Loop through names list to modify the formula for each sales representative
for (int r = 0, resultRow = 3; r < uniqueRep.Cells.Count; r++, resultRow = resultRow + 4)
{
//Get name to be replaced in the formula
var cval = uniqueRep.Cells[r].Value.ToString();

if (findText.Value != cval)
{
//Assign name to be replaced to Replace TextNode
replaceText.Value = cval;

//Invoke the recursive method to perform find and replace operation
replaceNode(syntaxTree.Root, findText, replaceText);

//Assign the modified formula to a cell in the worksheet
var resultRange = "H" + resultRow.ToString();
worksheet.Range[resultRange].Formula = "=" + syntaxTree.ToString();
worksheet.Range[resultRange + "#"].Borders.Color = System.Drawing.Color.FromArgb(91, 155, 213);
worksheet.Range[resultRange + "#"].Borders.LineStyle = BorderLineStyle.Thin;

//Update the value of Find node to perform find and replace operation for next sales representative name
findText = replaceText;
}
}

//Find and replace
void replaceNode(SyntaxNode lookIn, SyntaxNode find, SyntaxNode replacement)
{
var children = lookIn.Children;

for (var i = 0; i < children.Count; i++)
{
var child = children[i];
if (child.Equals(find))
{
children[i] = replacement;
}
else
{
replaceNode(child, find, replacement);
}
}
}
}
``````

=IF(ISNUMBER(FILTER(A2:D19,A2:A19="Xi")),IFS(FILTER(A2:D19,A2:A19="Xi")>5000,"Above Target",FILTER(A2:D19,A2:A19="Xi")>3000,"On Target",FILTER(A2:D19,A2:A19="Xi")<2500,"Below Target"),FILTER(A2:D19,A2:A19="Xi"))

5、保存 Excel 文件

``````//Save modified Excel file
workbook.Save("ModifiedFormula.xlsx", SaveFileFormat.Xlsx);
``````