SHOEISHA iD

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

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

5分でわかるActiveReports帳票

5分で"もっと"わかるActiveReports帳票(2008年度版)-Visual Studio 2008に対応したActiveReportsの新機能

第2回 Visual Studio 2008に対応したActiveReportsの新機能紹介

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

帳票出力にLINQを活用する(複数のXMLファイルを組み合わせて出力する)

複数のXMLファイルを組み合わせて出力する

 次は、複数のXMLファイルに含まれるデータを組み合わせて1つの帳票に出力する例を紹介します。

 「データの集合同士を結合する」という操作は、SQLに専用の構文が用意されているデータベースの世界では特に難しい操作ではありません。しかし、オブジェクトのコレクションやXMLドキュメントを結合する処理を結合したい場合、これまでの.NET言語ではコレクションをループで1つ1つ処理していくというやり方が主流でした。コレクションを処理するコードはループを多用するため、ネスト(入れ子構造)が深く、わかりにくいコードになってしまうことも少なくありません。

 このようなデータソースの結合操作も、LINQを使うとすっきりしたコードにまとめることができます。

 以下のデータはアドレス帳のデータと、アドレス帳に含まれるデータをグループ分けしたデータです。アドレス帳の各要素には番号、氏名、メールアドレスとグループ番号が、アドレスグループにはグループ番号とグループ名がそれぞれ定義されています。ここでも先ほどと同じように、「C:\ActiveReports3」フォルダにこれらの2ファイルが配置されているものとします。

アドレス帳のデータ(AddressBook.xml)
<?xml version="1.0" encoding="UTF-8"?>
<AddressBook>
<Address>
  <AddressNo>1</AddressNo>
  <Name>山口</Name>
  <Email>yamaguchi@example.com</Email>
  <GroupNo>01</GroupNo>
</Address>
<Address>
  <AddressNo>2</AddressNo>
  <Name>新井</Name>
  <Email>arai@example.com</Email>
  <GroupNo>02</GroupNo>
</Address>
<Address>
  <AddressNo>3</AddressNo>
  <Name>中村</Name>
  <Email>nakamura@example.com</Email>
  <GroupNo>01</GroupNo>
</Address>
<Address>
  <AddressNo>4</AddressNo>
  <Name>松田</Name>
  <Email>matsuda@example.com</Email>
  <GroupNo>03</GroupNo>
</Address>
<Address>
  <AddressNo>5</AddressNo>
  <Name>高島</Name>
  <Email>takashima@example.com</Email>
  <GroupNo>02</GroupNo>
</Address>
</AddressBook>
アドレス帳グループのデータ(AddressGroup.xml)
<?xml version="1.0" encoding="UTF-8"?>
<AddressGroups>
  <AddressGroup>
    <GroupNo>01</GroupNo>
    <GroupName>友人</GroupName>
  </AddressGroup>
  <AddressGroup>
    <GroupNo>02</GroupNo>
    <GroupName>職場</GroupName>
  </AddressGroup>
  <AddressGroup>
    <GroupNo>03</GroupNo>
    <GroupName>趣味</GroupName>
  </AddressGroup>
</AddressGroups>

 今回はこの2つを組み合わせて、次のような帳票を出力します。

XMLのデータソースを組み合わせたアドレス帳出力
XMLのデータソースを組み合わせたアドレス帳出力

 この帳票を出力するために、次のような帳票レイアウトを作成します。

アドレス帳の帳票レイアウト
アドレス帳の帳票レイアウト

 Detailセクションには番号、グループ、氏名、メールアドレスの各列にLabelコントロールを配置します。各LabelのDataFieldプロパティにはそれぞれ「AddressNo」「GroupName」「Name」「Email」を設定します。

 このサンプルは、LINQのデータソースとしてXMLファイルを使用しますが、XMLを操作するためのLINQ(LINQ to XML)を使用するには、System.LinqのほかにSystem.Xml.Linq名前空間の参照を追加する必要があります。usingディレクティブ(Visual Basicの場合はImportsステートメント)を使って、ソースファイルの先頭に以下のコードを追加してください。

System.Xml.Linq名前空間を参照するusingディレクティブ(C#)
using System.Xml.Linq;
System.Xml.Linq名前空間を参照するImportsステートメント(Visual Basic)
Imports System.Xml.Linq

問い合わせコードの記述

 以下のコードは、2つのXMLファイルをデータソースとして使用し、結合結果をデータソースとして指定するコードです。LINQでXMLドキュメントを操作するには、主にSystem.Xml.Linq.XElementクラスのメソッドを使用することになります。

 具体的には、XElementクラスのLoad()メソッドでXMLファイルを読み出し、Elements()メソッドでコレクションを指定します。そして、Element()メソッドとValueプロパティを組み合わせて、XMLドキュメントから値を取得します。

 LINQで2つのデータを結合(内部結合)する場合は、fromクエリ句に続けて「join コレクション on 結合条件」の形で記述します。結合条件は「値1 equals 値2」の形で記述します。クエリが完成したら、これまでの例と同じようにToList()メソッドでListの形に変換します。

複数のXMLファイルをLINQで結合して表示する(C#)
private void Form1_Load(object sender, EventArgs e)
{
  NewActiveReport1 rpt = new NewActiveReport1();

  string xmlFile1 = @"C:\ActiveReports3\AddressBook.xml";
  string xmlFile2 = @"C:\ActiveReports3\AddressGroup.xml";

  IEnumerable<XElement> xml1 
    = XElement.Load(xmlFile1).Elements("Address");
  IEnumerable<XElement> xml2 
    = XElement.Load(xmlFile2).Elements("AddressGroup");

  var query = from doc1 in xml1
              join doc2 in xml2
              on doc1.Element("GroupNo").Value equals 
doc2.Element("GroupNo").Value select new { AddressNo = doc1.Element("AddressNo").Value, Name = doc1.Element("Name").Value, Email = doc1.Element("Email").Value, GroupName = doc2.Element("GroupName").Value }; rpt.DataSource = query.ToList(); rpt.Run(); this.viewer1.Document = rpt.Document; }
複数のXMLファイルをLINQで結合して表示する(Visual Basic)
Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

  Dim rpt As New NewActiveReport1

  Dim xmlFile1 = @"C:\ActiveReports3\AddressBook.xml";
  Dim xmlFile2 = @"C:\ActiveReports3\AddressGroup.xml";

  Dim xml1 = XElement.Load(xmlFile1).Elements("Address");
  Dim xml1 = XElement.Load(xmlFile2).Elements("AddressGroup");

  Dim query = From doc1 In xml1
              Join doc2 In xml2
                On doc1.Element("GroupNo").Value 
Equals doc2.Element("GroupNo").Value _ Select New With { _ .AddressNo = doc1.Element("AddressNo").Value, _ .Name = doc1.Element("Name").Value, _ .Email = doc1.Element("Email").Value, _ .GroupName = doc2.Element("GroupName").Value _ } rpt.DataSource = query.ToList() rpt.Run() Me.Viewer1.Document = rpt.Document End Sub

 コードを書き終えたらアプリケーションを起動して、帳票のプレビューを表示してみましょう。2つのXMLファイルに格納されたデータがLINQによって結合され、1つの帳票として出力できました。

XMLのデータソースを組み合わせたアドレス帳出力(再)
XMLのデータソースを組み合わせたアドレス帳出力(再)

まとめ

 今回は、Visual Studio 2008に対応したActiveReports 3.0の新機能として、ActiveReports用の新しいプロジェクトテンプレートとLINQの活用法を中心に紹介しました。

 次回は「帳票アプリケーション開発におけるテスト」というテーマでお送りする予定です。お楽しみに。

 

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
5分でわかるActiveReports帳票連載記事一覧

もっと読む

この記事の著者

宮本奈紗(ミヤモトナサ)

株式会社システムインテグレータ ERPソリューション部所属。ERPシステムの設計・開発に従事。業務でActiveReportsを使用。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

渡辺俊史(ワタナベトシフミ)

株式会社システムインテグレータ パッケージ開発部所属。ECサイト構築パッケージの設計・開発に従事。VSUG(Visual Studio User Group) データベース・データアクセスフォーラムリーダー。blog...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2496 2015/06/04 12:59

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング