This walkthrough demonstrates the implementation of cross-sheet referencing using CalcEngine in a WinForms App. Here, CalcEngine is used to parse and compute algebraic expressions, mathematical functions, and formulas using variables and across multiple spreadsheets or controls. In this walkthrough, you understand how to use a bound FlexGrid and an unbound custom FlexGrid as the datasource for CalcEngine. The former FlexGrid control has been bound to a custom DataTable which implements the IDataSheet interface. And the latter, custom FlexGrid, has been defined by implementing the IDataSheet interface.
The walkthrough generates a list of type IDataSheet. Each element in the list is an instance of either C1FlexGrid or custom C1FlexGrid. This list is used as a data source for C1CalcEngine and each element of the list acts as a sheet for C1CalcEngine. The expressions evaluated by the CalcEngine use these sheets and the sheet names to implement cross-sheet referencing.
using C1.CalcEngine;
using C1.Win.C1FlexGrid;
C# |
コードのコピー
|
---|---|
//IDataSheet を実装するカスタム FlexGrid。 public class ExcelFlexGrid : C1FlexGrid, IDataSheet { public object GetValue(int col, int row) => Rows[row + 1][col + 1]; } |
Create a custom DataTable that implements the IDataSheet interface, used as the datasource for FlexGrid. This generates a bound FlexGrid control to be used as a datasource for CalcEngine.
C# |
コードのコピー
|
---|---|
//IDataSheet を実装するカスタム DataTable。 public class SheetTable : DataTable, IDataSheet { public string Name { get => TableName; set => TableName = value; } public object GetValue(int col, int row) { return Rows[row][col]; } } |
C# |
コードのコピー
|
---|---|
private C1CalcEngine _calcEngine; private const string Abc = "ABCDEF"; |
C# |
コードのコピー
|
---|---|
//FlexGrid のデータソースとして使用する DataTable を生成します。 public SheetTable GetDataTable(string sheetName) { var table = new SheetTable(); table.Name = sheetName; foreach (var c in Abc) table.Columns.Add(c.ToString(), typeof(int)); for (int i = 0; i < 80; i++) table.Rows.Add(new object[] { i * 2, i * 3, i * 4, i * 5, i * 6, i * 7 }); return table; } |
Add the following method to populate ExcelFlexGrid with unbound data.
C# |
コードのコピー
|
---|---|
//非連結のデータを使用して ExcelFlexGrid を設定します。 private void LoadUnboundGrid(C1FlexGrid grid) { grid.Rows.Count = 81; grid.Cols.Count = 7; for (int i = 1; i <= Abc.Length; i++) grid.Rows[0][i] = Abc[i - 1]; for (int i = 0; i < 80; i++) for (int j = 1; j <= Abc.Length; j++) grid.Rows[i + 1][j] = i * j; } |
C# |
コードのコピー
|
---|---|
//グリッドの選択を取得し、Excel 式を作成します。 private void grid_SelChange(object sender, System.EventArgs e) { textBox1.Text = string.Format("=Sum(sheet1!{0}) + Sum(sheet2!{1})", GetMark(c1FlexGrid1), GetMark(sheet2)); } |
C# |
コードのコピー
|
---|---|
private string GetMark(C1FlexGrid grid) { var sel = grid.Selection; return string.Format("{0}{1}:{2}{3}", Abc[sel.LeftCol - 1], sel.TopRow, Abc[sel.RightCol - 1], sel.BottomRow); } |
C# |
コードのコピー
|
---|---|
//作成された Excel 式を評価します。 private void button1_Click(object sender, EventArgs e) { _calcEngine.Expression = textBox1.Text; if (_calcEngine.TryEvaluate(out object result)) textBox2.Text = (result ?? "").ToString(); else textBox2.Text = _calcEngine.GetErrors().FirstOrDefault()?.FullMessage ?? ""; } |
using C1.CalcEngine.ExcelEngine;
C# |
コードのコピー
|
---|---|
private void Form1_Load(object sender, EventArgs e) { //C1FlexGrid を初期化し、カスタム DataTable(SheetTable) を設定します。 var sheet1 = GetDataTable("Sheet1"); c1FlexGrid1.DataSource = sheet1; //カスタム FlexGrid(ExcelFlexGrid) を初期化し、非連結のデータを設定します。 LoadUnboundGrid(sheet2); //C1CalcEngine を初期化し、データソースを割り当てます。 _calcEngine = new C1CalcEngine(new ExcelEngine()); _calcEngine.DataSource = new List<IDataSheet> { sheet1, sheet2 }; //FlexGrid/ExcelFlexGrid でデフォルトの選択を実行します。 c1FlexGrid1.Select(1, 1, 2, 2); sheet2.Select(3, 2, 5, 3); } |