SPREAD

ユースケースデモの[実績分析]画面を使って、SPREADのチャート機能を活用したデータの視覚化について解説していきます。


プロジェクトをダウンロードする

ClickOnceデモで動作を見る


[実績分析]画面について

[実績分析]画面は、「売り上げ分析システム」に取り込んだ販売実績データの分析結果をチャートで確認する画面です。年度ごとの販売実績や占有率をグラフ化し、データとともにSPREAD上に表示します。1シート上に販売実績の推移(折れ線グラフ)、カテゴリ別売り上げの割合(円グラフ)、エディションによる売り上げの割合(円グラフ)の3つのチャートを生成します。各チャートはそれぞれ異なるデータソースと連結し、経営ダッシュボード※的な画面に仕上げています。

※ 経営ダッシュボード : 複数の情報ソースから導き出した経営指標を、1画面にまとめて表示するシステム

フローチャート
画像「フローチャート」拡大して見る
実績分析画面
画像「実績分析画面」拡大して見る

この画面に実装している機能は次のとおりです。

  • 年度ごとの月別販売実績をデータとともにチャートで表示
  • シート上の複数のセル範囲に対して、それぞれ異なるデータソースと連結しデータを表示
  • シート上の各連結データからチャートオブジェクトを生成し、ダッシュボード風に表示
  • 画面上のデータおよびチャートは印刷、Excelファイル、PDFの各媒体で出力可能

[実績分析]画面で使われている
SPREADの機能

この画面で使われているSPREADの設定について、ユーザーインタフェース構築の目線で説明していきます。

数値データから傾向や全体像を判断する時に適した画面とは?

チャートは、ある事象に対して何らかの実測を行って得られた数値データから傾向や特徴を直感的に把握し、予測を立てるために最も適しているユーザーインタフェースです。業務システムでは、販売目標設定のための売上データや財務データ、品質管理データのチャート化などがよく求められます。
事象の把握と理解のためにはいろいろな角度から得たデータが用いられるため、チャートも複数必要になる場合が多いです。また複数データの関連や比較のため、関連するチャートは1画面にまとまっているほうがエンドユーザーによって便利なユーザーインタフェースとなります。

SPREADの1シートにソースの異なるデータを配置

ユースケースデモでは、[実績分析]画面にてSPREADでデータを視覚化しています。通常、データグリッドにデータを連結させる際には、グリッド全体に対して1つのデータソースが接続されます。しかし、SPREADでは任意のセル範囲に対してデータソースを連結することができます。この機能を利用し、デモでは異なる3つのテーブル[製品別売上実績]、[カテゴリ別売上割合]、[エディション別売上割合]を1シートに接続しています。フォーム上に複数のSPREADを配置して1つの画面にすることももちろん可能ですが、関連するデータとチャートをまるごと1つのExcelシートにエクスポートしたいといった要望に応えるには、今回紹介する方法が最適です。

3つの任意のセル範囲にそれぞれ異なる
データソースを接続
画像「3つの任意のセル範囲にそれぞれ異なるデータソースを接続」拡大して見る

チャートオブジェクト生成の解説は後に譲ることにして、セル範囲に対してのデータ接続は、SPREADのSpreadDataBindingAdapterクラスを使用して行います。このクラスを使用する際には1つだけ注意点があります。

SPREADのSpreadDataBindingAdapterクラスは.NET FrameworkのSystem.ComponentModel.Componentクラスを継承しています。このクラスは暗黙的なリソースの解放を行わないため、Dispose メソッドを呼び出して明示的にリソースを解放する必要があります。

MSDN:System.ComponentModel.Componentクラスの解説からの引用

Component では、Finalize メソッドの暗黙的な呼び出しによる自動メモリ管理を待たずに、Dispose メソッドを呼び出して明示的にリソースを解放する必要があります。 Container が破棄された場合は、Container 内のすべてのコンポーネントも破棄されます。

MSDN : System.ComponentModel.Componentクラス

この処理を行わないと、データを読み込むたびに処理時間が遅くなるなどレスポンスに影響をおよぼします。デモではusingステートメントを利用して、リソースの解放を行っています。

コード(C#)
// このコードで使用されている変数
// データ列
private int _SPR_RDATA_RH = 0;
// データ開始行
private int _SPR_RDATA_START_ROW = 2; 

// セル範囲データ連結用クラス
using (FarPoint.Win.Spread.Data.SpreadDataBindingAdapter Sdba = new
FarPoint.Win.Spread.Data.SpreadDataBindingAdapter()){
  // 連結対象のデータテーブル
    Sdba.DataSource = ds.Tables["fyeardata"];
    // 連結対象のSPREADコントロール
    Sdba.Spread = fpSpread1;
    // 連結対象のシート
    Sdba.SheetName = fpSpread1.ActiveSheet.SheetName;
    // 行の自動生成なし
    Sdba.AutoGenerateRow = false;
    Sdba.DataAutoCellTypes = false;

    // 連結対象範囲
    Sdba.MapperInfo = new FarPoint.Win.Spread.Data.MapperInfo(_SPR_RDATA_START_ROW + 1,
    _SPR_RDATA_RH + 1, ds.Tables["fyeardata"].Rows.Count,
    ds.Tables["fyeardata"].Columns.Count);
    // セル範囲に連結
    Sdba.FillSpreadDataByDataSource();
}
コード(VB)
' このコードで使用されている変数
' データ列
Private _SPR_RDATA_RH As Integer = 0
' ヘッダ開始行
Private _SPR_RDATA_START_ROW As Integer = 2

'  セル範囲データ連結用クラス
Using Sdba As New FarPoint.Win.Spread.Data.SpreadDataBindingAdapter()
    ' 連結対象のデータテーブル
    Sdba.DataSource = ds.Tables("fyeardata")
    ' 連結対象のSPREADコントロール
    Sdba.Spread = FpSpread1
    ' 連結対象のシート
    Sdba.SheetName = FpSpread1.ActiveSheet.SheetName
    ' 行の自動生成なし
    Sdba.AutoGenerateRow = False
    Sdba.DataAutoCellTypes = False

    ' 連結対象範囲
    Sdba.MapperInfo = New
    FarPoint.Win.Spread.Data.MapperInfo(_SPR_RDATA_START_ROW + 1,
    _SPR_RDATA_RH + 1, ds.Tables("fyeardata").Rows.Count,
    ds.Tables("fyeardata").Columns.Count)
    ' セル範囲に連結
    Sdba.FillSpreadDataByDataSource()
End Using

MSDN : using ステートメント(C#)
MSDN : Using ステートメント(VB)

豊富なチャート種でデータを視覚表示

SPREADにはExcelと互換性のあるチャートオブジェクトを生成する機能があります。チャートはデータの動的な変更に対応し、またデータの種類に応じたさまざまなチャート種が用意されています。

チャートはオブジェクトとして生成するためデータの動的な変更に対応
画像「チャートはオブジェクトとして生成するためデータの動的な変更に対応」拡大して見る

チャートのデザインはGUIデザイナで行えます。チャート種や色、ラベルなどの設定をXMLとして外部保存できますので再利用性にも優れています。

多彩なSPREADのチャート
画像「多彩なSPREADのチャート」拡大して見る
チャートデザイナ
画像「チャートデザイナ」拡大して見る

ユースケースデモではシートに連結した3つのデータから、それぞれチャートを生成しています。対象データのセル範囲を指定し、AddChartメソッドでチャートを追加しています。
SPREAD上に表示されたチャートは、Excelと同様にプロットエリアやデータシリーズをクリックすると、対象データ範囲が罫線で囲われます。この罫線をドラッグするとチャートが動的に変更されます。

データ範囲などを画面上で動的に変更可能
画像「データ範囲などを画面上で動的に変更可能」拡大して見る
コード(C#)
// ◆チャート関連
//---------------------------------------------------------
// 最終行の座標
Rectangle rmaxrow = fpSpread1.GetCellRectangle(0, 0,
_SPR_RDATA_START_ROW + 1 + ds.Tables["fyeardata"].Rows.Count, 0);

// データ領域およスタイルを指定してチャートを設定
FarPoint.Win.Spread.Model.CellRange range = new
FarPoint.Win.Spread.Model.CellRange(_SPR_RDATA_START_ROW,
_SPR_RDATA_product, ds.Tables["fyeardata"].Rows.Count + 1,
ds.Tables["fyeardata"].Columns.Count - 1);

fpSpread1.Sheets[0].AddChart(range,
typeof(FarPoint.Win.Chart.LineSeries),_CHT_RDATA_WIDTH, _CHT_RDATA_HIGHT,
0, rmaxrow.Y + 20, FarPoint.Win.Chart.ChartViewType.View2D,true);
FarPoint.Win.Spread.Chart.SpreadChart spreadChart =
fpSpread1.Sheets[0].Charts[0];

// 行・列入れ替え
spreadChart.SwitchRowColumn();
// プロットエリアの位置調整
spreadChart.Model.PlotAreas[0].Location = new PointF(0.1f, 0.1f);
// プロットエリアのサイズ調整
spreadChart.Model.PlotAreas[0].Size = new SizeF(0.6f, 0.8f);
// Y軸ラベルのフォーマット設定
FarPoint.Win.Chart.YPlotArea yp =
(FarPoint.Win.Chart.YPlotArea)spreadChart.Model.PlotAreas[0];
FarPoint.Win.Spread.Model.GeneralFormatter axisfmt = new
FarPoint.Win.Spread.Model.GeneralFormatter("#,##0", false);
yp.YAxes[0].LabelFormatter = axisfmt;

// シリーズ設定
FarPoint.Win.Chart.LineSeries ls;
for (int i = 0; i < yp.Series.Count; i++)
    {
        ls = (FarPoint.Win.Chart.LineSeries)yp.Series[i];
        // マーカーなし
        ls.PointMarker = new FarPoint.Win.Chart.NoMarker();
    }
// 色
spreadChart.Model.Fill = new FarPoint.Win.Chart.SolidFill(Color.Black);
yp.BackWall.Fill = new FarPoint.Win.Chart.SolidFill(Color.Gray);
yp.YAxes[0].LabelTextFill = new FarPoint.Win.Chart.SolidFill(Color.White);
yp.YAxes[0].MajorGridLine = new
FarPoint.Win.Chart.SolidLine(Color.White);
yp.XAxis.LabelTextFill = new FarPoint.Win.Chart.SolidFill(Color.White);
spreadChart.Model.LegendAreas[0].TextFill = new
FarPoint.Win.Chart.SolidFill(Color.White);
//---------------------------------------------------------
コード(VB)
' ◆チャート関連
'---------------------------------------------------------
' 最終行の座標
Dim rmaxrow As Rectangle = fpSpread1.GetCellRectangle(0, 0,
_SPR_RDATA_START_ROW + 1 + ds.Tables("fyeardata").Rows.Count, 0)

' データ領域およスタイルを指定してチャートを設定
Dim range As New
FarPoint.Win.Spread.Model.CellRange(_SPR_RDATA_START_ROW,
_SPR_RDATA_product, ds.Tables("fyeardata").Rows.Count + 1,
ds.Tables("fyeardata").Columns.Count - 1)

fpSpread1.Sheets(0).AddChart(range,
GetType(FarPoint.Win.Chart.LineSeries), _CHT_RDATA_WIDTH,
_CHT_RDATA_HIGHT, 0, rmaxrow.Y + 20, _
FarPoint.Win.Chart.ChartViewType.View2D, True)
Dim spreadChart As FarPoint.Win.Spread.Chart.SpreadChart =
fpSpread1.Sheets(0).Charts(0)

' 行・列入れ替え
spreadChart.SwitchRowColumn()
' プロットエリアの位置調整
spreadChart.Model.PlotAreas(0).Location = New PointF(0.1F, 0.1F)
' プロットエリアのサイズ調整
spreadChart.Model.PlotAreas(0).Size = New SizeF(0.6F, 0.8F)
' Y軸ラベルのフォーマット設定
Dim yp As FarPoint.Win.Chart.YPlotArea =
DirectCast(spreadChart.Model.PlotAreas(0), FarPoint.Win.Chart.YPlotArea)
Dim axisfmt = New FarPoint.Win.Spread.Model.GeneralFormatter("#,##0",
False)
yp.YAxes(0).LabelFormatter = axisfmt

' シリーズ設定
Dim ls As FarPoint.Win.Chart.LineSeries
For i As Integer = 0 To yp.Series.Count - 1
    ls = DirectCast(yp.Series(i), FarPoint.Win.Chart.LineSeries)
    ' マーカーなし
    ls.PointMarker = New FarPoint.Win.Chart.NoMarker()
    Next
' 色
spreadChart.Model.Fill = New FarPoint.Win.Chart.SolidFill(Color.Black)
yp.BackWall.Fill = New FarPoint.Win.Chart.SolidFill(Color.Gray)
yp.YAxes(0).LabelTextFill = New FarPoint.Win.Chart.SolidFill(Color.White)
yp.YAxes(0).MajorGridLine = New FarPoint.Win.Chart.SolidLine(Color.White)
yp.XAxis.LabelTextFill = New FarPoint.Win.Chart.SolidFill(Color.White)
spreadChart.Model.LegendAreas(0).TextFill = New FarPoint.Win.Chart.SolidFill(Color.White)
'---------------------------------------------------------

名前付きスタイル

エンドユーザーにとってパフォーマンスは良いに越したことはありません。そのための方法の1つとしてコード量の削減があります。ここでは、「名前付きスタイル」を利用してセルの外観設定用のコードを減らす方法を紹介します。

この機能は特にSPREADデザイナで大量のデザインを設定する場合に必須です。SPREADデザイナはExcelとよく似た操作性を持っているので、セルごとに背景色やフォントの設定などを行えます。設定情報はDesigner.vb/Designer.csファイルにコードで出力されるのですが、たくさんのセルにそれぞれデザイン情報を与えてしまうとDesigner.vb/Designer.csに大量のコードが書き込まれることになります。起動時の読み込みに時間がかかるのはもちろんですが、あまりに大量のデザイン情報を出力すると.NET Frameworkの仕様によりInitializeComponent()内で無効なプログラムと判断され、例外が発生することもあります。
そこで、「名前付きスタイル」を使ってセルのデザインをスタイルオブジェクトとして定義し、共通化することでコード量を削減することをお勧めします。

ユースケースデモの画面では「各ブロックのタイトル」・「行ヘッダ」・「明細データの交互行」を共通化しています。

名前付きスタイルでデザイン定義情報を
共通化
画像「名前付きスタイルでデザイン定義情報を共通化」拡大して見る

セルのロックと背景色、文字色を設定する場合、名前付きスタイルを使用しない場合では1セルに対してロックするコードと背景色を設定するコードの3行が出力されます。

コード(C#)
this.fpSpread1.ActiveSheet.Cells[0, 0].BackColor = System.Drawing.Color.Yellow;
this.fpSpread1.ActiveSheet.Cells[0, 0].ForeColor = System.Drawing.Color.Blue;
this.fpSpread1.ActiveSheet.Cells[0, 0].Locked = true;
コード(VB)
Me.FpSpread1.ActiveSheet.Cells(0, 0).BackColor = System.Drawing.Color.Yellow
Me.FpSpread1.ActiveSheet.Cells(0, 0).ForeColor = System.Drawing.Color.Blue
Me.FpSpread1.ActiveSheet.Cells(0, 0).Locked = True

名前付きスタイルを使用すると、1行で出力することができます。

コード(C#)
this.fpSpread1.ActiveSheet.Cells[0, 0].StyleName = "Style1";
コード(VB)
Me.FpSpread1.ActiveSheet.Cells(0, 0).StyleName = "Style1"

10×.ivfno.s54daa10の設定の場合、名前付きスタイルを使用しない場合は約200行、名前付きスタイルを使用した場合はスタイル設定のコード(5行)を合わせても約105行で出力することができます。設定するセル数やスタイル情報が多い場合はさらにコードの軽減率がアップします。デザイナにはスタイル設定用のエディタがありますので、視覚的なデザインも可能です。
なお、交互行のスタイルについては、ここでは指定のセル範囲に対して適用しているため、名前付きスタイルを使用していますが、シート全体に適用する場合には、SheetViewクラスから参照できるAlternatingRowクラスの機能を使うと、もっと簡単に設定することができます。詳細については製品ヘルプの「1行おきに背景色を設定」で解説しています。

スタイルエディタ
画像「スタイルエディタ」拡大して見る

以下は、ユースケースデモのコードから名前付きスタイルを利用しているところを抽出したものです。

コード(C#):スタイル作成部分
// タイトル用スタイル作成
FarPoint.Win.Spread.NamedStyle titlestyle = new
FarPoint.Win.Spread.NamedStyle("title");
titlestyle.BackColor = Color.DarkBlue;
titlestyle.Font = new Font("メイリオ", 11f, FontStyle.Italic | FontStyle.Bold);
titlestyle.ForeColor = Color.White;
titlestyle.VerticalAlignment = CellVerticalAlignment.Center;
// ヘッダ用スタイル作成
FarPoint.Win.Spread.NamedStyle headstyle = new
FarPoint.Win.Spread.NamedStyle("head");
headstyle.BackColor = Color.SeaGreen;
headstyle.ForeColor = Color.White;
headstyle.HorizontalAlignment = CellHorizontalAlignment.Center;
headstyle.VerticalAlignment = CellVerticalAlignment.Center;
// 交互行用スタイル作成
FarPoint.Win.Spread.NamedStyle altrow1 = new
FarPoint.Win.Spread.NamedStyle("altRow1");
altrow1.BackColor = Color.AliceBlue;
altrow1.ForeColor = Color.Black;
FarPoint.Win.Spread.NamedStyle altrow2 = new
FarPoint.Win.Spread.NamedStyle("altRow2");
altrow2.BackColor = Color.White;
altrow2.ForeColor = Color.Black;
// 作成したスタイルを追加
fpSpread1.NamedStyles.Add(titlestyle);
fpSpread1.NamedStyles.Add(altrow1);
fpSpread1.NamedStyles.Add(altrow2);
fpSpread1.NamedStyles.Add(headstyle);
コード(C#):スタイル適用部分
// このコードで使用されている変数
// タイトル部
private int _SPR_RDATA_TITLE_ROW = 0;
private int _SPR_RDATA_TITLE_COL = 0;
// ヘッダ開始行
private int _SPR_RDATA_START_ROW = 2;
// データ列
private int _SPR_RDATA_RH = 0;
private int _SPR_m3 = 14;

// タイトル関連
fpSpread1.ActiveSheet.Cells[_SPR_RDATA_TITLE_ROW,
_SPR_RDATA_TITLE_COL].StyleName = "title";
// 行ヘッダ
fpSpread1.ActiveSheet.Cells[_SPR_RDATA_START_ROW, _SPR_RDATA_RH,
_SPR_RDATA_START_ROW, _SPR_RDATA_m3].StyleName = "head";
for (int i = 0; i < ds.Tables["fyeardata"].Rows.Count; i++)
{
    fpSpread1.ActiveSheet.SetValue(_SPR_RDATA_START_ROW + i + 1, _SPR_RDATA_RH, i + 1);
    // 交互行のスタイル
    if (i % 2 == 0)
    {
         stylenm = "altRow1";
    } else {
        stylenm = "altRow2";
    }
    fpSpread1.ActiveSheet.Cells[_SPR_RDATA_START_ROW + i + 1, _SPR_RDATA_RH,
    _SPR_RDATA_START_ROW + i + 1, _SPR_RDATA_m3].StyleName = stylenm;
}
コード(VB):スタイル作成部分
' タイトル用スタイル作成
Dim titlestyle As New FarPoint.Win.Spread.NamedStyle("title")
titlestyle.BackColor = Color.DarkBlue
titlestyle.Font = New Font("メイリオ", 11.0F, FontStyle.Italic Or FontStyle.Bold)
titlestyle.ForeColor = Color.White
titlestyle.VerticalAlignment = CellVerticalAlignment.Center
' ヘッダ用スタイル作成
Dim headstyle As New FarPoint.Win.Spread.NamedStyle("head")
headstyle.BackColor = Color.SeaGreen
headstyle.ForeColor = Color.White
headstyle.HorizontalAlignment = CellHorizontalAlignment.Center
headstyle.VerticalAlignment = CellVerticalAlignment.Center
' 交互行用スタイル作成
Dim altrow1 As New FarPoint.Win.Spread.NamedStyle("altRow1")
altrow1.BackColor = Color.AliceBlue
altrow1.ForeColor = Color.Black
Dim altrow2 As New FarPoint.Win.Spread.NamedStyle("altRow2")
altrow2.BackColor = Color.White
altrow2.ForeColor = Color.Black
' 作成したスタイルを追加
FpSpread1.NamedStyles.Add(titlestyle)
FpSpread1.NamedStyles.Add(altrow1)
FpSpread1.NamedStyles.Add(altrow2)
FpSpread1.NamedStyles.Add(headstyle)
コード(VB):スタイル適用部分
' このコードで使用されている変数
' タイトル部
Private _SPR_RDATA_TITLE_ROW As Integer = 0
Private _SPR_RDATA_TITLE_COL As Integer = 0
' ヘッダ開始行
Private _SPR_RDATA_START_ROW As Integer = 2
' データ列
Private _SPR_RDATA_RH As Integer = 0
Private _SPR_m3 As Integer = 14

' タイトル関連
FpSpread1.ActiveSheet.Cells(_SPR_RCAT_TITLE_ROW,
_SPR_RCAT_TITLE_COL).StyleName = "title"
' 行ヘッダ
FpSpread1.ActiveSheet.Cells(_SPR_RED_START_ROW, _SPR_RED_RH,
_SPR_RED_START_ROW, _SPR_RED_CDT).StyleName = "head"
For i As Integer = 0 To ds.Tables("fyeardata").Rows.Count - 1
    FpSpread1.ActiveSheet.SetValue(_SPR_RDATA_START_ROW + i + 1,
    _SPR_RDATA_RH, i + 1)
    ' 交互行のスタイル
    If i Mod 2 = 0 Then
        stylenm = "altRow1"
    Else
        stylenm = "altRow2"
    End If
    FpSpread1.ActiveSheet.Cells(_SPR_RDATA_START_ROW + i + 1, _SPR_RDATA_RH,
    _SPR_RDATA_START_ROW + i + 1, _SPR_RDATA_m3).StyleName = stylenm
 Next


かんたん・多機能・安心のサポート
SPREADで楽々アプリケーション開発

まずは評価版ダウンロードから

今すぐ評価版を無料で入手する


製品・サービスに関する
ご質問・ご相談など、
お気軽にお問合せください。

電話でお問合せ

048-222-3001

(平日 9:00~12:00、13:00~17:30)

s