DioDocs for Excel
DioDocs for Excel
数式の解析
機能 > 数式 > 数式の解析

DioDocs for Excelは、数式を解析できるGrapeCity.Documents.Excel.Expressionsライブラリを提供します。数式はセマンティックモデルのレベルで公開されるため、構文ツリーを使用して数式を作成、アクセス、および変更できます。FormulaSyntaxTree クラスは数式を表し、数式APIのエントリポイントとなります。

構文ツリー

構文ツリーは、数式のセマンティックモデルを表します。テキストから構文ツリーを取得するには、FormulaSyntaxTreeクラスのParseメソッドを使用できます。ただし、「=」で始めるテキストや「{=}」で囲んだテキストを解析できません。FormulaSyntaxTreeクラスのRootプロパティを使用して、構文ツリーのルート要素を取得できます。FormulaSyntaxTreeコンストラクタを使用して空の構文ツリーを作成できます。

次のサンプルコードは、構文ツリーで数式を生成する方法を示します。

C#
コードのコピー
//新しいワークブックを作成します
var workbook = new GrapeCity.Documents.Excel.Workbook();

//構文ツリーをビルドします
var multiply = new OperatorNode(OperatorKind.Multiply);
var a1 = new Reference
{
    Row = 0,
    Column = 0
};
var a2 = new Reference
{
    Row = 1,
    Column = 0
};
multiply.Children.Add(new ReferenceNode(a1));
multiply.Children.Add(new ReferenceNode(a2));

var tree = new FormulaSyntaxTree { Root = multiply };

//A1*A2を生成します
workbook.ActiveSheet.Range["A1"].Value = "'=" + tree.ToString();

//xlsxファイルに保存します
workbook.Save("generateformula.xlsx");

構文ノード

SyntaxNodeクラスは構文ツリーのノードを表します。Childrenプロパティは、非終端ノードの子を取得するために使用されます。構文ノードのタイプがターミナルノードの場合、このコレクションは読み取り専用です。構文ツリーと同様に、テキストから構文ノードを取得するにはSyntaxNodeクラスのParseメソッドを使用できます。SyntaxNodeコンストラクタを使用して空の構文ノードを作成できます。

次のサンプルコードは、数式を解析し、構文ノードの子を置き換えて構文ツリーを変更し、それを文字列に変換する方法を示します。

C#
コードのコピー
//新しいワークブックを作成します
var workbook = new GrapeCity.Documents.Excel.Workbook();

const string Formula = "RAND()>0.5+0.001";

//構文ツリーを取得します
var syntaxTree = FormulaSyntaxTree.Parse(Formula);

//ノードを平板化します
var displayItems = new List<(string TypeName, int IndentLevel, string Content)>();

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

flatten(syntaxTree.Root, 0);

//出力
var sheet1 = workbook.Worksheets["Sheet1"];
sheet1.ShowRowOutline = false;
sheet1.OutlineColumn.ColumnIndex = 1;
sheet1.OutlineColumn.CollapseIndicator = new ImageSource(File.Open("decreaseIndicator.png", FileMode.Open), ImageType.PNG);
sheet1.OutlineColumn.ExpandIndicator = new ImageSource(File.Open("increaseIndicator.png", FileMode.Open), ImageType.PNG);

//ヘッダ
sheet1.Range["A1"].Value = "Formula";
sheet1.Range["B1"].Value = "Syntax node";
sheet1.Range["C1"].Value = "Part";

//値
sheet1.Range["A2"].Value = "'=" + Formula;
for (var i = 0; i < displayItems.Count; i++)
{
    var item = displayItems[i];
    var text = "'" + item.TypeName;

    sheet1.Range[i + 1, 1].Value = text;
    sheet1.Range[i + 1, 1].IndentLevel = item.IndentLevel;
    sheet1.Range[i + 1, 2].Value = "'" + item.Content;
}

//調整
sheet1.Range["A:C"].EntireColumn.AutoFit();
sheet1.Range["B:B"].EntireColumn.ColumnWidthInPixel += 40;

//xlsxファイルに保存します
workbook.Save("printformulasyntax.xlsx");

解析および解析解除オプション

ParseContextクラスには、文字列をFormulaSyntaxTreeに変換するためのオプションが含まれ、UnparseContextクラスには、FormulaSyntaxTreeを文字列に変換するオプションが含まれます。BaseRowプロパティとBaseColumnプロパティを使用して数式の位置を指定し、IsR1C1プロパティを使用して参照スタイルを指定できます。

次のサンプルコードは、オプションでベース行、ベース列、およびR1C1参照スタイルを指定する方法を示します。

C#
コードのコピー
//新しいワークブックを作成します
var workbook = new GrapeCity.Documents.Excel.Workbook();

//R1C1をA1に変換します
var r1c1Formula = "R1C:R8C[4]*9";
var formulaRow = 1;
var formulaColumn = 7;

//解析 
var r1c1Option = new ParseContext { IsR1C1 = true };
var syntaxTree = FormulaSyntaxTree.Parse(r1c1Formula, r1c1Option);

//ToString
//a1OptionでBaseRowとBaseColumnを指定します
//行と列はA1形式の絶対インデックスです
var a1Option = new UnParseContext
{
    BaseColumn = formulaColumn,
    BaseRow = formulaRow
};
var converted = syntaxTree.ToString(a1Option);

//出力
var sheet1 = workbook.ActiveSheet;
sheet1.Range["A1"].Value = "Original formula (at H2)";
sheet1.Range["A2"].Value = "'=" + r1c1Formula.ToString();
sheet1.Range["A3"].Value = "Converted";
sheet1.Range["A4"].Value = "'=" + converted.ToString();

//調整
sheet1.Range["A:A"].EntireColumn.AutoFit();

//xlsxファイルに保存します
workbook.Save("parseandformatoptions.xlsx");

次のサンプルコードは、数式を解析して構文ツリーを印刷する方法を示します。

C#
コードのコピー
//新しいワークブックを作成します
var workbook = new GrapeCity.Documents.Excel.Workbook();

const string Formula = "RAND()>0.5+0.001";

//構文ツリーを取得します
var syntaxTree = FormulaSyntaxTree.Parse(Formula);

//ノードを平板化します
var displayItems = new List<(string TypeName, int IndentLevel, string Content)>();

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

flatten(syntaxTree.Root, 0);

//出力
var sheet1 = workbook.Worksheets["Sheet1"];
sheet1.ShowRowOutline = false;
sheet1.OutlineColumn.ColumnIndex = 1;
sheet1.OutlineColumn.CollapseIndicator = new ImageSource(GetResourceStream("decreaseIndicator.png"), ImageType.PNG);
sheet1.OutlineColumn.ExpandIndicator = new ImageSource(GetResourceStream("increaseIndicator.png"), ImageType.PNG);

//ヘッダ
sheet1.Range["A1"].Value = "Formula";
sheet1.Range["B1"].Value = "Syntax node";
sheet1.Range["C1"].Value = "Part";

//値
sheet1.Range["A2"].Value = "'=" + Formula;
for (var i = 0; i < displayItems.Count; i++)
{
    var item = displayItems[i];
    var text = "'" + item.TypeName;

    sheet1.Range[i + 1, 1].Value = text;
    sheet1.Range[i + 1, 1].IndentLevel = item.IndentLevel;
    sheet1.Range[i + 1, 2].Value = "'" + item.Content;
}

//調整
sheet1.Range["A:C"].EntireColumn.AutoFit();
sheet1.Range["B:B"].EntireColumn.ColumnWidthInPixel += 40;

//xlsxファイルに保存します
workbook.Save("printformulasyntax.xlsx");

GrapeCity.Documents.Excel.Expressionsライブラリの他のクラス

ReferenceNodeクラスは構文ツリーの参照式を表します。

Referenceクラスは数式内の範囲参照を表します。参照は、セル、範囲、クロスワークシート、クロスワークシート3D、またはクロスワークブックにまたがることができます。

メモ: 行や列は相対インデックスの場合、BaseRowBaseColumnプロパティを使用して絶対インデックスに変換する必要があります。

WorkbookReferenceクラスは、名前またはローカルファイルパスによって外部ワークブックへの参照を表す不変のクラスです。ワークブック参照がファイルパスからのものである場合、BaseDirectoryプロパティにはディレクトリ情報が含まれます。

メモ: パス区切り文字はプラットフォームに依存し、ワークブック参照の結果を影響します。例えば:Windowsでは「'C:\Temp\[Book1.xlsx]Sheet1'!A2」は有効な参照ですが、Linuxでは有効ではありません。

例えば、名前([Book1]Sheet1!A2)で参照されるワークブックの解析したオブジェクトは次のようになります。

C#
コードのコピー
new ReferenceNode(
    new Reference {
        Workbook=WorkbookReference.FromName("Book1"),
        WorksheetName="Sheet1",
        Row=1,
        Column=0
    }
);

ファイルパス('C:\Temp\[Book1.xlsx]Sheet1'!A2)で参照されるワークブックの解析したオブジェクトは次のようになります。

C#
コードのコピー
new ReferenceNode(
    new Reference {
        Workbook=WorkbookReference.FromFilePath(@"C:\Temp\Book1.xlsx"),
        WorksheetName="Sheet1",
        Row=1,
        Column=0
    }
)

FunctionNodeクラスは、構文ツリー内の関数呼び出し式を表します。

例えば、Excel数式「COUNTIF(A:A,"*?")」の解析したオブジェクトは次のようになります。

C#
コードのコピー
new FunctionNode("COUNTIF") {
    Children = {
        new ReferenceNode(
            new Reference {
                HasRow=false, LastColumn=0
            }
        ),
        new TextNode("*?")
    }
};

NameNodeクラスは構文ツリー内の名前を表します。

例えば、名前「'[BuildingSales]JanIn2021'!RawData」で参照されるワークブックの解析したオブジェクトは次のようになります。

C#
コードのコピー
new NameNode("RawData", WorkbookReference.FromName("BuildingSales"), "JanIn2021", null);

ファイルパス「'E:\[BuildingSales.xlsx]JanIn2021'!RawData 」で参照されるワークブックの解析したオブジェクトは次のようになります。

C#
コードのコピー
new NameNode("RawData", WorkbookReference.FromFilePath(@"E:\BuildingSales.xlsx"), "JanIn2021", null);

ErrorNodeクラスは構文ツリー内のエラーリテラルノードを表します。次のエラーの種類がサポートされていません。

ArrayNodeクラスは構文ツリー内の配列リテラルを表します。次は配列に関する制約があります。

クラスの詳細については、GrapeCity.Documents.Excel.Expressions<link> API製品ヘルプを参照してください。

使用制限