SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

5分でわかるActiveReports帳票

5分でわかるActiveReports帳票(2013年度版)-Matrixデータ領域を使用したクロス集計表の作成

ActiveReports for .NET 7.0Jで作るサンプル帳票(6)

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

 ページレポートに用意されているMatrixデータ領域(以下、Matrix)は、データを縦(行)と横(列)の両方向に展開できるコントロールです。行と列それぞれにグループを設定し、行と列が交差するセルに集計値を表示できます。つまり、「クロス集計表」を作成することができるコントロールです。

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

 Matrixは、他のデータ領域と異なり、横方向にもデータを展開できるため、使い方も他のデータ領域とは少し異なります。今回はこのMatrixの使い方を紹介します。

備考

 本稿は、連載『5分でわかるActiveReports帳票(2007年度版)』(渡辺俊史・宮本奈紗 著)の増補改訂版です。

Matrixレポートの作成

 まず、Matrixを使ったレポートを作成してみましょう。

 プロジェクトにページレポートを追加し、データソース、データセットを設定します。これらの手順については第2回をご参照ください。

 今回も、ActiveReportsに付属するAccessデータベースファイル「Nwind.mdb」を使用します。過去の注文データ(Order Details)テーブルから、注文ごとの価格の合計(Subtotal)、注文日(OrderDate)、発送する地域名(ShipCountry)、発送する区市町村(ShipCity)のデータセットを取得するため、以下のようなクエリーを設定します。

SELECT DISTINCTROW [Order Details].OrderID,
    Sum(CCur([UnitPrice]*[Quantity]*(1-[Discount])/100)*100) AS Subtotal,
    Orders.OrderDate,
    Orders.ShipCountry,
    Orders.ShipCity
FROM     [Order Details]
INNER JOIN Orders ON Orders.OrderID = [Order Details].OrderID
GROUP BY [Order Details].OrderID, 
    Orders.OrderDate,
    Orders.ShipCountry,
    Orders.ShipCity
ORDER BY Orders.OrderDate;

Matrixの配置

 次にページレポート上にMatrixを配置します。

 配置したら、プロパティウィンドウからMatrixのFixedSizeプロパティを設定し、クロス集計表が表示される領域を設定します。

 なお、Matrixは、初期状態では2×2の表になっており、各セルはTableデータ領域と同様にTextBoxコントロールで構成されています。

Matrixデータ領域
Matrixデータ領域

 出力内容を分かりやすくするために、それぞれのセル(TextBoxコントロール)に罫線を設定します。セルを選択した状態で、プロパティウィンドウのBorderStyleプロパティを”Solid”に設定します。

 なお、今回紹介しているレポートでは、すべて罫線を設定していますが、以降の説明ではこの罫線を設定する手順は省略しています。

Matrixにフィールドを追加する

 前述のとおり、初期状態のMatrixは4つのセルから構成されており、それぞれのセルを「コーナー」「行ヘッダ」「列ヘッダ」「集計詳細」と言います(下図参照)。

Matrixの構成要素
Matrixの構成要素

 左上の「コーナー」には特別な機能はありません。空白のままにしておくか、タイトルなどを表示するのに使います。

 「行ヘッダ」と「列ヘッダ」には集計対象としてグループ化したいフィールドを、「集計詳細」には集計したいフィールドと集計式を設定します。ここでは、以下のように設定します。

  • 「行ヘッダ」にはフィールド「ShipCountry」を設定します。TextBoxコントロールのValueプロパティは「=Fields!ShipCountry.Value」です。
  • 「列ヘッダ」にはフィールド「OrderDate」を設定します。TextBoxコントロールのValueプロパティは「=Fields!OrderDate.Value」です。
  • 「集計詳細」にはフィールド「Subtotal」を設定します。TextBoxコントロールのValueプロパティは「=Sum(Fields!Subtotal.Value)」です。
備考

 フィールドを設定するには、レポートエクスプローラのデータセットからデザイナ上に設定したいフィールドをドラッグ&ドロップするか、TextBoxコントロール上にマウスを移動した時に表示される「フィールド選択修飾」アイコン(フィールドセレクター)をクリックして表示されるリストから選択してください。

  ここまでの手順で作成したレポートでもプレビュー表示することは可能ですが、集計表として見やすくするために書式を設定します。

  • 「列ヘッダ」に設定されているフィールド「OrderDate」は日付時刻型です。何も書式を設定しないと時刻まで表示されてしまいますので、TextBoxコントロールのFormatプロパティから”Short Date”を選択し、「2000/01/01」のような形式で表示させます。
  • 「集計詳細」に設定しているフィールド「Subtotal」は金額に関する項目です。Formatプロパティから”Currency”を選択し、記号付きの通貨として表示させます。

Matrixを使ったレポートの動作

 以上の手順で作成したレポートをプレビュー表示させると、以下のようになります。

Matrixデータ領域を使ったレポート
Matrixデータ領域を使ったレポート

 集計表の列が日付(注文日)ごとになるため、数十ページのレポートになります。また、使用しているサンプルデータベースには、同じ注文日で発送先が異なるデータが少ないため、空白マスが大量に存在します。

 このように、このレイアウトでは集計表としてはあまり実用的ではありませんが、この表を元にMatrixの動作を見てみましょう。

縦・横方向への伸長

 最初に述べた通り、Matrixは縦と横の両方向に伸長できるデータ領域です。

 行数(縦方向)は、Matrixの「行ヘッダ」に設定したフィールドに対してグループ化した時に得られるデータ数です。今回の場合、「行ヘッダ」に設定したフィールド「ShipCountry」に対してグループ化した時に得られるデータ数が”24”であり、これが集計結果全体の行数です。

 一方、列数(横方向)は、Matrixの「列ヘッダ」に設定したフィールドに対してグループ化した時に得られるデータ数です。今回の場合、「列ヘッダ」に設定したフィールド「OrderDate」に対してグループ化した時に得られるデータ数は”228”となり、これが集計結果全体の列数です。

 ただし、1ページに表示できる行数・列数は、MatrixコントロールのFixedSizeプロパティで決定されます。今回作成したレポートの場合、1ページに表示できる行数は最大27行、列数は最大5列になります(ヘッダ部分は除く)。

 従って、縦方向(24行)は1ページに収まりますが、横方向(228列)は1ページに収まらず46ページに分かれることになります。

 なお、今回作成したレポートでは、行ヘッダに設定したフィールドのデータ数(24)が、1ページで表示できる行数(27行)以下でしたが、このデータ数が多くなれば、縦方向も複数ページに分かれて表示されます。

 例えば、行ヘッダにフィールド「ShipCity」を指定した場合、そのフィールドをグループ化した時のデータ数は”49”になり、これは縦方向に2ページ必要なデータ数です。

 従って、フィールド「ShipCountry」を行ヘッダに設定した時に比べて、ページ数が倍になります。

 このように、Matrixによって生成された集計結果の行数・列数が1ページに収まりきらない場合、各ページに分割されてレポートが生成されます。集計結果がどのように分割されるかは、以下の図をご覧ください。

縦・横に表が広がる
縦・横に表が広がる

集計値が表示される

 行ヘッダや列ヘッダにフィールドを設定したときは、TextBoxコントロールのValueプロパティにはフィールドの値をそのまま出力するような式(例:=Fields!ShipCountry.Value)が設定されました。

 一方、集計詳細セルにフィールドを設定したときは、集計関数Sum()を含む式が自動的に設定されました。このように、集計詳細セルには集計した値を表示することになっています。これは行と列が同じ組み合わせのレコードが複数存在しうるからです。例えば、今回のレポートで使用している売上データで言えば「ShipCountry=東京、OrderDate=4月1日というレコードが複数存在する」ということです。

 集計詳細セルに設定したフィールドの型が数値型の場合、デフォルトで設定される集計関数は合計値を取得するSum()ですが、他にも任意の集計関数が設定できます。例えば、件数を取得するCount()、平均を取得するAvg()なども設定できます。

 設定したフィールドの型が数値型でない場合、デフォルトで設定される集計関数は、最初のレコードの値を表示するFirst()です。従って、行と列の組み合わせに対して対象データが1レコードしか存在しない、または行と列の組み合わせが一致するすべてのレコードについてフィールドの値が常に同じであると保証されている場合以外には、意図した結果になりません。

Matrixの機能を使ったデータのグループ化

 最初に作成したレポートは、日付項目(OrderDate)を列ヘッダに設定したため、列が日付ごとに生成され、大量の空白マスが発生してしまいました。

 そこで、月単位の集計に変更したいと思います。

 データセットのSQLを変更して、「OrderDate」をあらかじめ月単位のデータに変換することで月単位の集計にすることは可能です。しかしながら、Matrixのグループ化の機能を使用すると、SQL文を変更しなくても集計単位を変更できます。

列グループを設定する

 まず、「行ヘッダ」と「集計詳細」には、最初のレポートと同じように”ShipCountry”と”Subtotal”を設定します。

 次にデザイナ上でMatrixを選択した状態で「プロパティ設定ダイアログ」を開き、「列グループ」タブを開きます(「プロパティ設定ダイアログ」はプロパティウィンドウの[コマンド]ペインから開くことが可能です)。

列グループの設定画面
列グループの設定画面

 「グループ化の条件」の「式」に、「年」と「月」を組み合わせたデータを取得するため、以下のように式を記述します(式の記述方法については第4回をご参照ください)。

=Year(Fields!OrderDate.Value) & "/" & Month(Fields!OrderDate.Value)

 なお、画面上には「=Year([OrderDate]) & "/" & Month([OrderDate])」のように短縮形で表示されます。

 また、列ヘッダのTextBoxのValueプロパティも、同じ式を設定しておきます。

 以上のように編集することで「列」が月単位になり、月ごとの集計値が表示されるようになります。

月単位で集計したレポート
月単位で集計したレポート
注意点:表示とグループ化の式は必ずしも同じではない

 ここで、最初に作成したレポートに戻り、「プロパティ設定ダイアログ」の「列グループ」を開いてみてください。列ヘッダにフィールドを設定しただけですが、今回設定した「グループ化の条件」の「式」として「=[OrderDate]」が設定されていることが確認できると思います。

 「列グループ」「行グループ」を設定していない場合、列ヘッダ、行ヘッダに設定したフィールドが自動的にグループ化の式になります。同時に、同じ式が、列ヘッダ、行ヘッダ自体のTextBoxコントロールのValueプロパティに設定されます。これがフィールドを設定しただけで(行/列グループを設定しなくても)、集計表が生成される仕組みです。

 ただし、このように動作するのは空のMatrixに対して行った最初の設定の時のみです。いったん、設定したMatrixに対して同じ操作で編集を加えた場合、意図した結果にならないことに注意が必要です。

 例えば、列ヘッダに一回フィールドを設定したあと、列ヘッダの式(Valueプロパティ)だけを変更した場合、ヘッダの表示は変更されますが、グループ化の式は変更されません。

 集計するグループも変更したい場合、列グループのグループ化の条件の式と、列ヘッダのValueプロパティをそれぞれ別個に変更する必要があります。これは、行グループを変更する場合も同じです。

ソートとフィルタ

 行グループや列グループについて、式の設定によって項目順のソート(並べ替え)や、フィルタ処理をすることができます。こちらの設定について今回は割愛いたしますが、基本的に第4回のTableのソートやフィルタ処理と同じなので、そちらをご覧ください。

グループを階層化する

 行グループや列グループは、階層構造とすることも可能です。

 例えば、行ヘッダに「ShipCountry(発送先の地域名)」のみを設定している表に「ShipCity(発送先の区市町村)」を行グループとして追加する方法を説明します。

 レポートエクスプローラを開き、データセットの中の「ShipCity」を行ヘッダ上にドラッグ&ドロップしてください。このときはすでに「ShipCountry」のセルの右側にバーが表示されている状態でドロップしてください(下図、参照)。このように設定することで行ヘッダが階層化され、大分類に地域名が、小分類に区市町村名が表示されるようになります。

行グループの追加(レポートエクスプローラを使用する場合)
行グループの追加(レポートエクスプローラを使用する場合)
行グループを階層化したレポート
行グループを階層化したレポート

 地域名と区市町村名が実際と異なる行がありますが、これはNwind.mdbのデータがこのように設定されているためです。

 なお、行グループの追加はプロパティ設定ダイアログからも行うことが可能です。

 デザイナ上でMatrixを選択した状態で「プロパティ設定ダイアログ」を開き、「行グループ」タブを開いてください。一番上の行グループ一覧の上にある「+」ボタンをクリックし、行グループを追加したら、「式」のコンボボックスから追加したいフィールド(今回の場合、”=Fields!ShipCity.Value”)を選択してください。

複数の行グループが存在するプロパティ設定ダイアログ
複数の行グループが存在するプロパティ設定ダイアログ

集計する

 Matrixでは、「集計詳細」セルに出力された値をさらに集計して表示することができます。集計したい行ヘッダまたは列ヘッダを右クリックし、「集計」を選択して有効にしてください。行または列に対する集計結果を表示するセルが追加されます。

集計の追加
集計の追加

 前述の「月単位で集計したレポート」について、行ヘッダと列ヘッダの両方の集計を有効にした場合、以下のようになります。これは最終ページのプレビュー結果ですが、一番右の列に各行の合計が、一番下に各列の合計が表示されます(行や列が複数ページにまたがって出力されている場合、ページをまたがって集計が行われます)。

集計付きのレポート
集計付きのレポート

行を追加する

 これまでは「集計詳細」に各発送先・注文日ごとの「小計」のみを表示してきましたが、Matrixでは、複数の集計項目を「集計詳細」に追加できます。

 ここでは「小計」の下に「件数」を表示する方法を説明したいと思います。

 集計詳細セルを右クリックし、「行の追加」もしくは「列の追加」を選択します。「行の追加」を選択すると、1つの行ヘッダに対して2つの行が作成され、またそれぞれの行のための見出し用ヘッダが現れます。

行の追加
行の追加
集計行が複数になり、各行に対して見出しヘッダが追加される
集計行が複数になり、各行に対して見出しヘッダが追加される

 「集計詳細」に新たに追加されたTextBoxコントロールのValueプロパティに、件数をカウントするための以下のような式を記述します。

=Count(Fields!OrderID.Value)

 対応する見出し部分にはそれぞれ「小計」「件数」と記述します。

複数項目を表示するレポート
複数項目を表示するレポート

まとめ

 Matrixは縦と横に伸長するデータ領域であり、クロス集計表のように、他のコントロールやデータ領域では実現することが難しい表を作成できます。

 次回は、セクションレポートとページレポートそれぞれのグラフの作成方法を解説します。

この記事は参考になりましたか?

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

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7542 2015/07/23 16:16

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング