表計算データグリッドコンポーネント「SPREAD for Windows Forms(スプレッド)」の新バージョン「15.0J」では、Microsoft Excel®と互換性のあるテーブルをデータソースに連結することができます。
今回は、この新しいテーブルバインディング機能の使い方をご紹介したいと思います。
はじめに
本記事では、JavaScriptスプレッドシートライブラリ「SpreadJS(スプレッドJS)」でのテーブルバインディングについて解説した以下の記事で作成した請求書を、SPREAD for Windows Formsで作成してみます。
同じテーブルバインディングですが、実装方法はSpreadJSとかなり異なっているので、そのあたりも見ていただければと思います。
テーブルの作成
SPREADでテーブルを作成する方法は2つあります。1つはSheetViewクラスのAddTableメソッドを使う方法で、もう1つは今回ご紹介するIWorksheetクラスのCreateTableメソッドを使う方法です。
テーブルバインディング機能を使う場合は、IWorksheetクラスのCreateTableメソッドの方でテーブルを作成する必要があります。
var sheet = fpSpread1.Sheets[0];
var iTable = sheet.AsWorksheet().Range("B2:E5").CreateTable(true);
このコードを実行すると、指定したセル範囲(B2:E5)にテーブルが作成されます。
テーブルバインディング
テーブルをデータソースに連結する方法として、ITable.AutoGenerateColumnsプロパティをtureに設定する自動連結と、falseに設定する手動連結があります。このあたりはシートのデータ連結と同じですね。
※ テーブルバインディングの動作と制約については製品ヘルプもご覧ください。
自動連結
最初に、連結するデータソースを作成しておきます。
// データソースの作成
var dt = new DataTable();
dt.Columns.AddRange(new DataColumn[]
{
new DataColumn("品名", typeof(string)),
new DataColumn("数量", typeof(int)),
new DataColumn("単価", typeof (int))
});
dt.Rows.Add("OAモニタ", 2, 29800);
dt.Rows.Add("SDDユニット", 2, 25000);
dt.Rows.Add("出張点検費", 1, 18400);
dt.AcceptChanges();
// データソースの変更
dt.Columns.Add(new DataColumn("金額", typeof(int)));
dt.Columns["金額"].Expression = "[数量] * [単価]";
dt.AcceptChanges();
ここでは、「品名、数量、単価」の3つのDataColumnを持つDataTableを作成し、その後で「数量×単価」を計算した「金額」用のDataColumnを追加します。この計算はDataColumnクラスのExpressionプロパティを使って行います。
後は、作成したデータソースをITableのDataSourceプロパティに設定するだけでテーブルバインディングが完了です。
// シートの設定
var sheet = fpSpread1.Sheets[0];
sheet.SetColumnWidth(1, 100);
// テーブルの作成と設定
var iTable = sheet.AsWorksheet().Range("B2:E5").CreateTable(true);
iTable.AutoGenerateColumns = true;
iTable.DataSource = dt;
このコードを実行したときの画面は次のようになります。
手動連結
次にITable.AutoGenerateColumnsプロパティをfalseに設定して列単位で連結する方法を紹介します。ここでは、前述のデータソースの「金額」用のDataColumnを追加しないで「品名、数量、単価」の3つだけを使います。4つ目の「金額」列は非連結列として作成し、この後の項目で解説するテーブルの数式機能を使って「数量×単価」を計算します。
// シートの設定
var sheet = fpSpread1.Sheets[0];
sheet.Columns[1, 4].Width = 100;
// テーブルの作成と設定
var iTable = sheet.AsWorksheet().Range("B2:E5").CreateTable(true);
iTable.Name = "table";
iTable.AutoGenerateColumns = false;
iTable.TableColumns[0].DataField = "品名";
iTable.TableColumns[1].DataField = "数量";
iTable.TableColumns[2].DataField = "単価";
iTable.TableColumns[3].Header.Value = "金額";
iTable.DataSource = dt;
連結するDataColumnのColumnNameに設定されている文字列をiTable.TableColumnの
DataFieldプロパティに設定することで、テーブルの列を対応するDataColumnに連結します。また、非表示列のキャプションはiTable.TableColumnのHeader.Valueプロパティで設定できます。
以下は、このコードを実行したときの画面です。
テーブル内の数式設定
この状態では、まだ「金額」列が空白のままなので、数式で「数量×単価」を計算して「金額」列に表示しましょう。数式の設定は、ITableクラスではなくTableViewクラスの機能を使って下記のようにします。
var table = sheet.GetTable("table");
table.SetDataColumnFormula(3, "[@単価]*[@数量]");
ついでに「単価」列と「金額」列の数値書式も設定します。
iTable.DataBodyRange.Columns[2].NumberFormat = "\\#,##0";
iTable.DataBodyRange.Columns[3].NumberFormat = "\\#,##0";
最後に合計金額を表示する行を追加すると明細らしくなります。
iTable.ShowTotals = true;
iTable.TableColumns[0].Total.Value = "合計";
iTable.TableColumns[3].Total.Formula = "SUM([金額])";
iTable.TableColumns[3].Total.NumberFormat = "\\#,##0";
以上のコードを実行したときの画面は次のようになります。
テーブルを作成および設定するコードの全体は次のようになります。
// シートの設定
var sheet = fpSpread1.Sheets[0];
sheet.Columns[1, 4].Width = 100;
// テーブルの作成と設定
var iTable = sheet.AsWorksheet().Range("B2:E5").CreateTable(true);
iTable.Name = "table";
iTable.AutoGenerateColumns = false;
iTable.TableColumns[0].DataField = "品名";
iTable.TableColumns[1].DataField = "数量";
iTable.TableColumns[2].DataField = "単価";
iTable.TableColumns[3].Header.Value = "金額";
iTable.DataBodyRange.Columns[2].NumberFormat = "\\#,##0";
iTable.DataBodyRange.Columns[3].NumberFormat = "\\#,##0";
iTable.ShowTotals = true;
iTable.TableColumns[0].Total.Value = "合計";
iTable.TableColumns[3].Total.Formula = "SUM([金額])";
iTable.TableColumns[3].Total.NumberFormat = "\\#,##0";
iTable.DataSource = dt;
var table = sheet.GetTable("table");
table.SetDataColumnFormula(3, "[@単価]*[@数量]");
請求書を仕上げる(概要)
最後に、テーブルバインディング機能で実現した明細部に請求先などの顧客情報を追加して請求書アプリ的なものにします。実装後の画面は次のようになります。
明細部に関連付けられた顧客情報を表示するために「セル範囲との連結」を使います。この機能は、SPREADのセル範囲をデータソースに連結できるとても柔軟性のあるものですが、データソース内の特定のDataColumnを指定する機能がないため、データソース側で工夫する必要があります。
具体的には次のような手順でデータソースを加工してからセル範囲に連結します。
- DataColumnAとDataColumnBで構成されたDataTable1を作成
- DataTable1からDataView1を取得
- DataView1のToTableメソッドを使って指定した列だけを持ったDataTable2を作成
- SpreadDataBindingAdapterのDataSourceにDataTable2を設定
詳細につきましては、以下のサンプルプロジェクトをご覧ください。
さいごに
テーブルのデータ連結機能はいかがでしたでしょうか。従来からあるセル範囲のデータ連結機能と組み合わせることで、アプリケーション開発の可能性がさらに広がりそうです。
Webサイトでは製品の機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。新バージョンの「15.0J」から、トライアル版の試用期間が30日に拡大していますので、ExcelライクなUIがさらに充実したSPREADの機能をぜひお試しください。
また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。