CodeZine(コードジン)

特集ページ一覧

データベースのデータを小計つきで表示する.NETアプリケーションを作る

「PowerTools ComponentOne Studio 2012J」のC1FlexGridコントロールを使った.NETアプリケーションの作成

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2012/11/15 14:00

 「PowerTools ComponentOne Studio 2012J」のC1FlexGridコントロールは、同じフィールドのデータをグループ化し自動的に小計を算出する機能を持っています。そこで今回はこの機能を使って、Accessデータベースのデータから、野菜の収穫量を地方別・都道府県別の2段階に分けて小計を算出するアプリケーションを作成してみました。

はじめに

 「PowerTools ComponentOne Studio 2012J」のC1FlexGridコントロールは、データベースからデータを読み込んで表示する機能を持っていますが、単純にテーブルのデータを表示するだけでなく、同じフィールドのデータをグループ化し自動的に小計を算出する機能も持っています。

 これだけならSQL文でも同様のことを実現できますが、C1FlexGridコントロールはさらに階層ツリーで小計結果を表示する機能を持っています。しかも、これらの機能は集計列を指定してメソッドを実行するだけです。

 そこで今回はこの自動小計機能を使って、データベースのデータから、野菜の収穫量を地方別・都道府県別の2段階に分けて小計を算出するアプリケーションを作成してみました(今回はAccessデータベースファイルを使用しています)。

対象読者

 Visual Basic 2005/2008/2010、またはVisual C# 2005/2008/2010を使ってプログラムを作ったことがある人。

必要な環境

 Visual Basic 2005/2008/2010、Visual C# 2005/2008/2010、Visual Studio 2005/2008/2010のいずれかでプログラムが作れる環境。

 なお、本プログラムはWindows 7上で動作するVisual Studio 2010を使用して作成し、動作確認を行っています。

プログラム実行時の注意事項

 「PowerTools ComponentOne Studio 2012J」を使って作成したアプリケーションを配布する場合、「PowerTools ComponentOne Studio 2012J」のアセンブリファイルを添付する必要があります。これは、Common Language RuntimeのDLLをアプリケーションと一緒に配布するのと同じです。

 本記事のサンプルアプリケーションを正常に動作させるためには、次のファイルをインストールする必要があります。

サンプルファイルの実行に必要なファイル(※は.NET Framework 4でのみ利用可)
ファイル名 説明
C1.Win.C1FlexGrid.2.dll 本体アセンブリ
C1.Win.C1FlexGrid.4.dll 本体アセンブリ(※)

 このファイルを、プログラムを実行するフォルダに格納します。

 .NET Framework 2.0から追加されたクラスやメンバを使用しているので、.NET Framework 2.0以上のバージョンの.NET Frameworkがインストールされていることが必須条件です。

コンポーネントのインストール

 「PowerTools ComponentOne Studio 2012J」を使用する方は、Visual Studio、Visual Basic、Visual C#の開発環境に、「PowerTools ComponentOne Studio 2012J」をインストールする必要があります。

 インストーラは、グレープシティのWebページからダウンロードできます。

 ダウンロードしたい製品にチェックを付け[申込フォーム]ボタンを押すと、「トライアル版申込フォーム」ページに移動しますので、「個人情報の収集および使用に同意する」にチェックを入れ「同意する」ボタンをクリックします。

 トライアル申込フォームが表示されますので、必要情報を登録すると添付トライアルライセンスキーファイルとダウンロードサイトを記載したE-Mailが送られてきます。ここからダウンロードします。ダウンロードファイルは圧縮ファイルになっていますので、解凍してインストーラを起動します。

 制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。

コントロールの追加

 「PowerTools ComponentOne Studio 2012J」をインストールしたら、プロジェクトにコントロールを追加します。

 ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントはアセンブリ名が「C1.Win.C1FlexGrid.4」の「C1FlexGrid」コントロールです。

追加するコントロール
コントロール アセンブリ
C1FlexGrid C1.Win.C1FlexGrid.4
アセンブリ名が「C1.Win.C1FlexGrid.4」の「C1FlexGrid」コントロール
アセンブリ名が「C1.Win.C1FlexGrid.4」の「C1FlexGrid」コントロール

C1FlexGridコントロールの小計機能

 C1FlexGridコントロール全体の機能の概要、およびデータ連結機能については、記事『データベースのデータからバブルチャートを作成する.NETアプリケーションを作る』で紹介していますので、こちらを参照してください。

 ここでは、C1FlexGridコントロールの小計機能について説明します。

アウトラインとデータの集計

 C1FlexGridコントロールには、データを集計して階層表示するためのメソッドとプロパティが用意されています。

 オリジナルのグリッドに、指定した列のデータを集計し小計行を追加します。小計は複数の階層に分けて行うことができ、その階層をツリー表示することができます。

 例えば、営業成績を集計する場合、都道府県別・営業所別・担当者別にそれぞれ小計を出します。C1FlexGridコントロールはこれを自動的に行い、しかも階層順にツリー表示してくれます。

 次の画面は、ヘルプファイルで紹介している小計の実行例ですが、売り上げの合計を「総計」「楽器の種類別」「地区別」に分けて行っています。売上合計は、まず楽器の種類別に行い、その内訳をさらに地区別に集計しています。これらは、すべてC1FlexGridコントロール側で行っています。グリッドにはこれらの小計用行が追加され、さらに階層データはツリーで表示されます。ユーザーはツリーの記号「+」「-」をクリックして、ツリーを展開・縮小することができます。

小計の実行例(ヘルプファイルより)
小計の実行例(ヘルプファイルより)

Subtotalメソッドの機能と書式

 小計を実行するには、C1FlexGridクラスの「Subtotal」メソッドを実行します。このメソッドは7つのオーバーロードメソッドが存在し、もっとも代表的な引数を持ったメソッドは次のメソッドです。

Subtotal(AggregateEnum, Int32, Int32, Int32, String)

 引数は5つで、それぞれ次の値を指定します。

Subtotalメソッドの書式

Visual Basic (宣言)
Public Sub Subtotal ( _
    aggType As AggregateEnum, _
    level As Integer, _
    groupOn As Integer, _
    totalOn As Integer, _
    caption As String _
)
C#
public void Subtotal(
    AggregateEnum aggType,
    int level,
    int groupOn,
    int totalOn,
    string caption
)
aggType

 計算する集計の種類をAggregateEnum列挙体の値で指定します。

level

 新しい小計行に割り当てるアウトラインレベル(階層レベル)を数値で指定します。このパラメータを使用すると複数レベルの小計を作成でき、アウトラインツリーの表示に反映されます。指定する数値はトップレベルの階層が「0」で、以降階層が深くなるほど数字が大きくなります。

groupOn

 グループ化する列を番号で指定します。例えば、先頭列でグループ化し小計を出したい場合は「0」を指定します。「-1」を指定すると、全体を集計するよう指示することになります。

totalOn

 集計したい値(通常は数値)のある列を番号で指定します。

caption

 グリッドに追加される小計行に、ヘッダ代わりに挿入するテキストを指定します。直接文字列を指定しますが、「"{0}"」と指定するとグループ化したデータを元にテキストを作成します。例えば、次の例は「地方名」「都道府県名」ごとにグループ化し、テキストに"{0}計"と指定したので小計行の列見出しにそれぞれグループ化したデータが使用されています。

小計行の列見出しにそれぞれグループ化したデータが使用されている
小計行の列見出しにそれぞれグループ化したデータが使用されている

Subtotalメソッドで行える集計の種類

 小計は合計計算だけでなく、平均値や最大値など12種類の集計値を計算できます。これらは、AggregateEnum列挙体のメンバを指定します。

AggregateEnum列挙体のメンバ
メンバ 機能
None 集計なし。この設定は、数値集計なしでアウトラインツリーを作成するために、
Subtotal(AggregateEnum, Int32, Int32, Int32, Int32, String) メソッドで使用されます。
Clear 既存の集計をクリアします。この設定は、通常、新しい小計を計算する前に既存の小計をクリアするため、Subtotal(AggregateEnum, Int32, Int32, Int32, Int32, String) メソッドで使用されます。
Sum 範囲内のすべての値の合計を返します。
Percent 総計に対する割合(百分率)。この設定は、各サブグループの総計に対する割合を計算するために、Subtotal(AggregateEnum, Int32, Int32, Int32, Int32, String) メソッドで使用されます。この設定は、Aggregate(AggregateEnum, CellRange, AggregateFlags) メソッドでは使用できません。
Count 範囲内の空でないセルの数を返します。 
Average 範囲内の空でないセルの平均値を返します。
Max 範囲内の最大値を返します。
Min 範囲内の最小値を返します。
Std 範囲内の値の標本標準偏差を返します( n-1 に基づく式を使用)。
Var 範囲内の値の標本分散を返します( n-1 に基づく式を使用)。
StdPop 範囲内の値の母標準偏差を返します( n に基づく式を使用)。
VarPop 範囲内の値の母分散を返します( n に基づく式を使用)。

 各引数は、値をそのまま指定しても構いませんが、名前付き引数を使うこともできます。

Visual Basic
C1FlexGrid1.Subtotal(agree_enum, level:=-1, groupOn:=-1, totalOn:=3, caption:="総計")
C#
c1FlexGrid1.Subtotal(agree_enum, level:-1, groupOn:-1, totalOn:3, caption:"総計");

 Visual BasicとC#で少し書式が違いますので注意してください。

小計行のスタイルとアウトラインツリー表示

 Subtotalメソッドによって小計行が追加されると、その行には自動的に小計行用のスタイルが割り当てられます。

 設計時にスタイルエディタを使用するか、もしくは実行時にコードを使用してアウトラインスタイルのプロパティを変更すると、小計行の外観をカスタマイズできます。

 また、CellStyleクラスを使用してグリッドのセルスタイルを変更することで、独自のスタイルを作成することもできます。このCellStyleクラスには、CellStyleEnum列挙体のメンバを使用して5レベルまでの小計行用の組み込みスタイルを使うこともできます。

 ツリー表示を行う際の、階層を結ぶラインやシンボルの表示についてもカスタマイズすることができます。これらは、グリッド内のアウトラインツリーの位置と外観を制御するGridTreeクラスを使用します。

 GridTreeクラスのStyleプロパティは、アウトラインツリーのスタイルを取得または設定するプロパティで、引数にTreeStyleFlags列挙体のメンバを指定することで、アウトラインツリーの表示/非表示や折りたたみ記号、ツリー線の表示/非表示を設定することができます。

 次のコードは、アウトラインツリーに折りたたみ記号とツリー線を表示するように設定します。

Visual Basic
C1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf
C#
c1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf;
アウトラインツリーに折りたたみ記号とツリー線を表示する
アウトラインツリーに折りたたみ記号とツリー線を表示する
TreeStyleFlags列挙体のメンバ
メンバ名 説明
None アウトラインツリーを表示しません。
Lines ノード行の横にツリーの線を表示します。
Symbols ノード行に展開/折りたたみ記号を表示します。
ButtonBar 上端の固定行にアウトラインボタンを並べて表示します。
Leaf すべての行(ノードとデータ)の横にツリーの線を表示します。
Complete Lines、Symbols、およびButtonBarの組み合わせ。
Simple LinesおよびSymbolsの組み合わせ。
CompleteLeaf Lines、Symbols、ButtonBar、およびLeafの組み合わせ。
SimpleLeaf Lines、Symbols、およびLeafの組み合わせ。

ノードの部分展開

 アウトラインツリー表示を設定した場合、デフォルトではプログラム実行時はすべてのツリーが展開した状態で表示されます。

デフォルトではすべてのツリーが展開した状態で表示される
デフォルトではすべてのツリーが展開した状態で表示される

 これを指定した階層レベル以下を折りたたみ、それより上位のレベルを展開するように設定することも可能です。これは、GridTreeクラスのShowメソッドを使用します。メソッドの引数には表示するレベルを数値で指定し、これより下位のLevelのノードは折りたたまれ、上位のレベルのノードは展開されます。

 次のコードは、最初のツリーレベルだけを展開し、2番目以下のレベルは折りたたむように指定しています。

Visual Basic
C1FlexGrid1.Tree.Show(1)
C#
c1FlexGrid1.Tree.Show(1);
最初のツリーレベルだけを展開
最初のツリーレベルだけを展開

列幅の自動調整

 デフォルトでは、列幅はグリッドのデザイン時のサイズのままになっていますから、データのサイズに関係なく表示されてしまいます。これだとデータの表示が途中で途切れたり、スクロールしないと表示されない状態になってしまいます。データを見るたびに、ユーザーが列幅を調整したりスクロールしたりと面倒です。

デフォルトでは列幅はデータに関係なく設定されてしまう
デフォルトでは列幅はデータに関係なく設定されてしまう
ツリーを展開しても列幅はそのまま
ツリーを展開しても列幅はそのまま

 小計やツリーの展開・縮小などを行った際に、列幅をセル内容に合わせて自動調節するように設定しておくと、表が見やすくなります。

 この処理を行うには、1つはC1FlexGridコントロールのAutoResizeプロパティをTrueにセットします。これで、列幅の自動調節が可能になります。

Visual Basic
C1FlexGrid1.AutoResize = True
C#
c1FlexGrid1.AutoResize = true;

 データベースからデータを読み込む前にこのプロパティをTrueにしておくと、グリッドの列幅は読み込んだデータに合わせて調節されます。

 ただし、これはデータを読み込んだ時にだけ実行されますので、小計やアウトラインツリーを展開・縮小した時にも列幅の自動調節を行うには、AutoSizeColsメソッドを実行します。このメソッドを実行するとその時点ですべての列幅を自動調節してくれます。

Visual Basic
C1FlexGrid1.AutoSizeCols()
C#
c1FlexGrid1.AutoSizeCols();

 アウトラインツリーを展開・縮小すると、C1FlexGridコントロールにはAfterCollapseイベントが発生しますので、このイベントハンドラを使うとツリーの展開・縮小のタイミングに合わせて、列幅を自動調節することができます。

Visual Basic
Private Sub C1FlexGrid1_AfterCollapse(sender As System.Object, e As C1.Win.C1FlexGrid.RowColEventArgs) Handles C1FlexGrid1.AfterCollapse
    'ツリーの展開・縮小のたびに列幅の自動調整を行う
    C1FlexGrid1.AutoSizeCols()
End Sub
C#
private void c1FlexGrid1_AfterCollapse(object sender, RowColEventArgs e)
{
    //ツリーの展開・縮小のたびに列幅の自動調整を行う
    c1FlexGrid1.AutoSizeCols();
}

GUIのデザイン

 では、さっそくプログラムを作成しましょう。

 作成するプログラムは、Accessで作成したサンプルデータベース「平成23年度秋冬野菜収穫量.mdb」から、テーブル「収穫量一覧」にあるデータをすべて取出し、フィールド「ID」以外のフィールドデータをC1FlexGridコントロールで表示するというものです。

サンプルデータベース「平成23年度秋冬野菜収穫量.mdb」のデータ
サンプルデータベース「平成23年度秋冬野菜収穫量.mdb」のデータ

 「合計」「平均」「対総計比」のいずれかを選び「小計を実行」ボタンを押すと、それぞれの小計を計算し、結果をグリッドに挿入します。小計計算は「地方名」と「都道府県名」の2階層で行い、結果をアウトラインツリーで表示します。

 なお、小計を実行する際は集計単位でデータをソートしておく必要があります。あらかじめデータベース側で行っておくか、C1FlexGridクラスのSortメソッドでデータをソートしてから小計を実行するようにします。

 今回は、データベース側で「地方名」と「都道府県名」をそれぞれ順番に並べています。

フォームのデザイン

 フォームには、C1FlexGridコントロールと、Button、GroupBox、RadioButton、OpenFileDialogの各コントロールを配置します。「データベース読み込み」ボタンで「ファイルを開く」ダイアログボックスを表示し、データベースファイルを読み込みます。クエリ文の入力は、コードからInputBoxを表示して入力してもらうようにします。

 OpenFileDialogコントロールは、Filterプロパティを設定しAccessデータベースファイルを選べるようにします。

プロパティ 設定値
FileName (空白)
Filter Accessファイル(*.mdb)|*.mdb

 RadioButtonコントロールは、「合計」だけCheckedプロパティをTrueにしておきます。

フォームのレイアウト
フォームのレイアウト

C1FlexGridコントロールのデザイン

 C1FlexGridコントロールは、1行おきにセルの背景色が変わるようなスタイルを設定します。

 (1)C1FlexGridコントロールのタスクトレイから「スタイルエディタ」を選びます。

タスクトレイから「スタイルエディタ」を選ぶ
タスクトレイから「スタイルエディタ」を選ぶ

 (2)「オートフォーマット」ボタンをクリックします。

「オートフォーマット」ボタンをクリック
「オートフォーマット」ボタンをクリック

 (3)ここには、あらかじめ組み込まれているグリッドのスタイルが一覧表示されます。リストからフォーマットを選ぶだけで、グリッドの装飾が簡単に行えます。ここでは「Professional2」を選びます。

「Professional2」を選ぶ
「Professional2」を選ぶ

 (4)もう一度タスクトレイを表示し、「VisualStyle」から「Office2010Blue」を選びます。

「VisualStyle」から「Office2010Blue」を選ぶ
「Visual Style」から「Office2010Blue」を選ぶ

C1FlexGridコントロールのデータベース連結処理

 まずは、グリッドをデータベースに連結する処理を作成します。この処理は、ボタン「データベースの読み込み」のClickイベントハンドラに作成します。

 なお、手順の詳細は記事『データベースのデータからバブルチャートを作成する.NETアプリケーションを作る』で紹介している手順とほぼ同様なので、こちらを参照してください。

 また今回も、クエリ文の入力にインプットボックスを使用します。これは、Visual BasicのInputBoxメソッドを使用しますので、C#で使う場合はプロジェクトの参照設定に「Microsoft.VisualBasic」を追加しておいてください。

C#は「Microsoft.VisualBasic」への参照を追加しておく
C#は「Microsoft.VisualBasic」への参照を追加しておく

 なお、今回はクエリ文の入力用インプットボックスに、あらかじめサンプルデータベース用のクエリ文を表示するようにし、データを読み込んだ時点でAutoResizeプロパティをTrueに設定して列幅の自動調節を行っています。

Visual Basic
Imports System.Data.OleDb
Imports C1.Win.C1FlexGrid

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        'DBファイル名の取得と接続文字の作成
        Dim dbname As String = ""
        If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            dbname = OpenFileDialog1.FileName
        Else
            Exit Sub
        End If

        Dim conn As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & dbname

        'SQL文の入力()
        Dim sqlstr As String = InputBox("クエリのSQL文字列を入力してください", "テーブルの取り込み", _
                                        "SELECT 収穫量一覧.* FROM 収穫量一覧;") 
        If sqlstr = "" Then
            Exit Sub
        End If

        'クエリを実行しDataSetにデータを取り込む
        Dim data_adap As OleDbDataAdapter = New OleDbDataAdapter(sqlstr, conn)
        Dim data_sset As DataSet = New DataSet()

        data_adap.Fill(data_sset)

        'グリッドにデータを接続
        C1FlexGrid1.AutoResize = True
        C1FlexGrid1.DataSource = data_sset.Tables(0)
        C1FlexGrid1.Cols.Remove(1)   'キー列を削除

    End Sub
C#
using System.Data.OleDb;
using C1.Win.C1FlexGrid;

namespace FG_subtotal_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //DBファイル名の取得と接続文字の作成
            string dbname = "";
            if(openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                dbname = openFileDialog1.FileName;
            }
            else
            {
                return;
            }
            string conn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + dbname;

            //SQL文の入力
            string sqlstr = Microsoft.VisualBasic.Interaction.InputBox(
                                        "クエリのSQL文字列を入力してください", "テーブルの取り込み", 
                                        "SELECT 収穫量一覧.* FROM 収穫量一覧;", 200, 100);
            if(sqlstr == "")
            {
                return;
            }

            //クエリを実行しDataSetにデータを取り込む
            OleDbDataAdapter data_adap = new OleDbDataAdapter(sqlstr, conn);
            DataSet data_sset = new DataSet();

            data_adap.Fill(data_sset);

            //グリッドにデータを接続
            c1FlexGrid1.AutoResize = true;
            c1FlexGrid1.DataSource = data_sset.Tables[0];
            c1FlexGrid1.Cols.Remove(1);   //キー列を削除
        }

小計とアウトラインツリーの実行処理

 データベースを読み込んだら、小計を実行する処理を作成します。

 小計は全部で3種類の計算ができるようにしますので、独自のプロシージャ(メソッド)を作成し、引数にAggregateEnum列挙体のメンバを指定して計算の種類を切り替えるようにします。

小計計算の種類を切り替える処理

 最初に、小計計算の種類を切り替える処理を作成します。これは、独自のプロシージャ(メソッド)「run_subtotal」を作成し、呼び出す際に引数にAggregateEnum列挙体のメンバを指定して、3種類の計算ができるようにします。

 (1)小計とツリー用の列を作成します。1つは固定列で、もう一つはツリーを展開表示したときの追加の列です。これらは、あらかじめ列を用意しておくだけで、あとはC1FlexGridコントロールが自動的の操作してくれます。

 (2)ツリーの展開/折りたたみ記号とツリー線を表示するように設定します。

 (3)Subtotalメソッドを使用して、3つの小計を作成します。集計するデータは列「収穫量」で、1つは収穫量すべての「総計」を算出します。総計を出す場合、Subtotalメソッドの引数「level」と「groupOn」には、値「-1」を指定します。引数「level」はアウトラインツリーのレベルで「-1」を指定すると、階層レベルとは関係なく最上位に小計を作成します。

 引数「groupOn」はグループ化する列番号を指定しますが、これも「-1」を指定すると全データをグループ化し小計を計算するようになります。

 引数「totalOn」は、集計するデータのある列番号を指定し、「caption」は行見出しを指定する文字列です。

 (4)次に、階層のトップレベルに当たる「地方名」の小計を作成します。階層レベルは「0」で、グループ化する列は「地方名」の列番号「0」、集計列は「3」のままで、行見出しにはグループ化する列名に「計」という文字を結合して作成しますので、「"{0}計"」を指定します。

 2番目の階層となる「都道府県」で小計を作成します。階層レベルは「1」を指定し、グループ化する列は「都道府県名」の列番号「1」、集計列は「3」のままで、行見出しにはグループ化する列名に「計」という文字を結合して作成しますので、「"{0}計"」を指定します。

 (5)そして、最初のレベルだけツリーを展開するようにShowメソッドを実行します。

小計作成前のグリッドの状態。列「地方名」と「都道府県」でグループ化し小計を算出する
小計作成前のグリッドの状態。列「地方名」と「都道府県」でグループ化し小計を算出する
Visual Basic
Private Sub run_subtotal(ByVal agree_enum As AggregateEnum)
    '(1)小計とツリー用の列の作成
    C1FlexGrid1.Cols.Fixed = 0
    C1FlexGrid1.Tree.Column = 0

    '(2)すべての行(ノードとデータ)の横にツリーの線を表示し
    'ノード行に展開/折りたたみ記号を表示
    C1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf

    '(3)総計の作成
     C1FlexGrid1.Subtotal(agree_enum, level:=-1, groupOn:=-1, totalOn:=3, caption:="総計")

    '(4)地方名で小計を作成
    C1FlexGrid1.Subtotal(agree_enum, level:=0, groupOn:=0, totalOn:=3, caption:="{0}計")

    '都道府県名で小計を作成
    C1FlexGrid1.Subtotal(agree_enum, level:=1, groupOn:=1, totalOn:=3, caption:="{0}計")

    '(5)最初のツリーレベルだけを展開
    C1FlexGrid1.Tree.Show(1)
End Sub
C#
private void run_subtotal(AggregateEnum agree_enum)
{
    //(1)小計とツリー用の列の作成
    c1FlexGrid1.Cols.Fixed = 0;
    c1FlexGrid1.Tree.Column = 0;

    //(2)すべての行(ノードとデータ)の横にツリーの線を表示し
    //ノード行に展開/折りたたみ記号を表示
    c1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf;

    //(3)総計の作成
    //c1FlexGrid1.Subtotal(agree_enum, -1, -1, 3, "総計")
    c1FlexGrid1.Subtotal(agree_enum, level:-1, groupOn:-1, totalOn:3, caption:"総計");

    //(4)地方名で小計を作成
    c1FlexGrid1.Subtotal(agree_enum, level:0, groupOn:0, totalOn:3, caption:"{0}計");

    //都道府県名で小計を作成
    c1FlexGrid1.Subtotal(agree_enum, level:1, groupOn:1, totalOn:3, caption:"{0}計");

    //(5)最初のツリーレベルだけを展開
    c1FlexGrid1.Tree.Show(1);
}
  

小計実行の処理

 小計を実行するには、作成したプロシージャ(メソッド)「run_subtotal」の引数に、計算の種類を指定するAggregateEnum列挙体のメンバを設定し、メソッドを実行します。どの計算を実行するのかは、選択されたRadioButtonコントロールによって切り替えます。

 「合計」「平均」「対総計比」それぞれ、計算結果の桁数が違いますからセルの書式を設定します。特に実数となる「平均」「対総計比」は、小数点の桁数を指定しておかないとデータが分かりづらくなります。

 セルの書式は、Colsプロパティに列番号を指定し、Formatプロパティに書式を指定します。書式指定は、.NET Frameworkの書式指定に従います。

 そして、その桁数に合わせて列幅を自動調節するように、AutoSizeColsメソッドを実行します。

 これで、「小計を実行」ボタンをクリックすると、ラジオボタンで選択された小計が実行され、グリッドに小計が挿入されます。

Visual Basic
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    '一度小計をクリア
    C1FlexGrid1.Subtotal(AggregateEnum.Clear)

    '合計の小計を実行
    If RadioButton1.Checked = True Then
        run_subtotal(AggregateEnum.Sum)
        C1FlexGrid1.Cols(3).Format = "0"
    End If

    '平均値の小計を実行
    If RadioButton2.Checked = True Then
        run_subtotal(AggregateEnum.Average)
        C1FlexGrid1.Cols(3).Format = "##.##"
    End If

    '対総計比の小計を実行
    If RadioButton3.Checked = True Then
        run_subtotal(AggregateEnum.Percent)
        C1FlexGrid1.Cols(3).Format = "0.#"
    End If

    '列幅を内容に合わせる
    C1FlexGrid1.AutoSizeCols()
End Sub
C#
private void button2_Click(object sender, EventArgs e)
{
    //一度小計をクリア
    c1FlexGrid1.Subtotal(AggregateEnum.Clear);

    //合計の小計を実行
    if(radioButton1.Checked==true)
    {
        run_subtotal(AggregateEnum.Sum);
        c1FlexGrid1.Cols[3].Format = "0";
    }

    //平均値の小計を実行
    if(radioButton2.Checked == true)
    {
        run_subtotal(AggregateEnum.Average);
        c1FlexGrid1.Cols[3].Format = "##.##";
    }

    //対総計比の小計を実行
    if(radioButton3.Checked == true)
    {
        run_subtotal(AggregateEnum.Percent);
        c1FlexGrid1.Cols[3].Format = "0.#";
    }

    //列幅を内容に合わせる
    c1FlexGrid1.AutoSizeCols();
}

小計の削除とツリーの展開・縮小に合わせた列幅の自動調整

 最後に、小計を削除し元のグリッドに戻す処理を行います。これは、Subtotalメソッドに引数「AggregateEnum.Clear」を指定して実行するだけです。

 そして、ツリーの展開・縮小のたびに列幅の自動調整を行う処理を作成します。これは、C1FlexGridコントロールの「AfterCollapse」イベントで行います。

 「AfterCollapse」イベントは、ツリーの展開・縮小が行われた後に発生するイベントです。このイベントハンドラでAutoSizeColsメソッドを実行すれば、展開・縮小後にそれぞれの列幅が自動調整されます。

Visual Basic
Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
    '小計をクリアし元のテーブルに戻す
    C1FlexGrid1.Subtotal(AggregateEnum.Clear)
End Sub

Private Sub C1FlexGrid1_AfterCollapse(sender As System.Object, e As C1.Win.C1FlexGrid.RowColEventArgs) Handles C1FlexGrid1.AfterCollapse
    'ツリーの展開・縮小のたびに列幅の自動調整を行う
    C1FlexGrid1.AutoSizeCols()
End Sub
C#
private void button3_Click(object sender, EventArgs e)
{
    //小計をクリアし元のテーブルに戻す
    c1FlexGrid1.Subtotal(AggregateEnum.Clear);
}

private void c1FlexGrid1_AfterCollapse(object sender, RowColEventArgs e)
{
    //ツリーの展開・縮小のたびに列幅の自動調整を行う
    c1FlexGrid1.AutoSizeCols();
}

まとめ

 C1FlexGridコントロールの自動小計機能とアウトラインツリー表示は、データをすっきりとまとめ、ユーザーに見やすいグリッドを提供します。

 小計のレベルも階層状に深くすることができるので、データを全体からより詳細な集計までカバーすることができ、データ分析にも役に立ちます。

 今回もAccessのデータベースを対象にアプリケーションを作成しましたが、ADO.NETが対応するデータベースであればどんなデータベースでもグリッドに読み込み小計を追加することができます。

参考資料(サンプルデータ)

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 瀬戸 遥(セト ハルカ)

    8ビットコンピュータの時代からBASICを使い、C言語を独習で学びWindows 3.1のフリーソフトを作成、NiftyServeのフォーラムなどで配布。Excel VBAとVisual Basic関連の解説書を中心に現在まで40冊以上の書籍を出版。近著に、「ExcelユーザーのためのAccess再...

All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5