CodeZine(コードジン)

特集ページ一覧

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

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

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

本連載では帳票作成コンポーネント「ActiveReports for .NET 3.0J」をさらに使いこなすためのテクニックを紹介していきます。今回はVisual Studio 2008に対応したActiveReportsの新機能について紹介します。

編集部注

 本稿はActiveReportsの旧バージョンを用いた内容となっています。最新版に基づいた記事は連載の目次「5分でわかるActiveReports帳票」をご参照ください。

はじめに

 ActiveReports for .NET(以下ActiveReports)はVisual Studioと統合された使いやすいレポートデザイナや高機能なレポートビューワ、多彩な出力形態をサポートする帳票作成コンポーネントです。ActiveReportsは2008年3月下旬にリリースされたService Pack1でVisual Studio 2008に対応しました。今回はVisual Studio 2008に対応したActiveReportsの新機能について紹介します。

前回の記事

過去の連載記事

対象読者

  • Visual Basic 2008またはVisual C# 2008を使ってプログラムを作ったことのある方。
  • 帳票作成ツールに興味のある方。
  • 今回のサンプルではLINQ(Language INtegrated Query:言語統合クエリ)や匿名クラスなどの新機能を使用しています。各機能の詳細については他のCodeZine記事を参照ください。

必要な環境

開発ツール
  • Visual Studio 2008(Express EditionではActiveReportsをインストールできません)
開発言語

 本記事のサンプルコードはC# 3.0/Visual Basic 9.0で記述しています。

Visual Studio 2008に対応したActiveReports 3.0

 ActiveReports 3.0は、2008年3月下旬にリリースされたService Pack1でVisual Studio 2008(以下VS2008)に対応しました。このService PackにはVS2008のIDE対応および追加の新機能、改訂されたヘルプが含まれています。また、製品付属のサンプルコードにも、VS2008対応版が追加されました。この他、以前のバージョンで作成したレポートファイルを変換するためのインポートウィザードも、VS2008に対応したものに更新されています。

 今回は、ActiveReportsの新機能として「ActiveReports用プロジェクトテンプレート」と「データソースとしてLINQを使ったクエリ結果を扱う方法」の2つを紹介します。

ActiveReports用のプロジェクトテンプレート

 VS2008では、.NET Frameworkの機能追加に合わせて「新しいプロジェクト」ダイアログで選択可能なプロジェクトテンプレートが大幅に追加され、帳票アプリケーションのための「Reporting」というグループと、帳票アプリケーション用のプロジェクトテンプレートが追加されました。VS2008にActiveReportsをインストールすると、「新しいプロジェクト」ダイアログのReportingグループに「ActiveReportsアプリケーション」というプロジェクトテンプレートが追加されます。

 これまではActiveReportsを利用した帳票アプリケーションを開発するのに、いったん「Windows Formsアプリケーション」のプロジェクトテンプレートを作ってからActiveReportsのレポートファイルを追加する、という手順を取っていましたが、このプロジェクトテンプレートを使うことで、すぐに帳票アプリケーションの開発をスタートすることができます。

Reportingグループに追加されたプロジェクトテンプレート
Reportingグループに追加されたプロジェクトテンプレート

 「新しいプロジェクト」ダイアログから「ActiveReportsアプリケーション」テンプレートを選択してプロジェクトを作成すると、Viewerコントロールが追加されたWindowsフォームと、空のActiveReportsファイルを1つ含むプロジェクトが作成されます。

ActiveReportsアプリケーションの初期設定
ActiveReportsアプリケーションの初期設定

 このFormコントロールには以下のように、デフォルトのLoadイベントが実装されています。

 Form1.cs(VBの場合はForm1.vb)を右クリックしてメニューから「コードの表示」を選択すると、Loadイベントに最初から実装されているコードを見ることができます。

デフォルトで生成されるForm1_Loadメソッド(C#)
private void Form1_Load(object sender, EventArgs e)
{
    NewActiveReport1 rpt = new NewActiveReport1();
    rpt.Run();
    this.viewer1.Document = rpt.Document;
}
デフォルトで生成されるForm1_Loadメソッド(Visual Basic)
Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
  Dim rpt As New NewActiveReport1
  rpt.Run()
  Me.Viewer1.Document = rpt.Document
End Sub

 デフォルトのLoadイベントが実行されると、ActiveReportsのレポートインスタンスが生成され、Formに関連付けられたViewerコントロールにプレビューが表示されます。

 このプロジェクトテンプレートを使えば、F5キーを押してデバッグ起動することですぐに帳票のプレビューを確認できます。今回は、このプロジェクトテンプレートを使用して以後のサンプルコードを説明していきます。

アプリケーションの初期表示
アプリケーションの初期表示

LINQを使ったクエリの結果を帳票に表示する

 .NET Framework 3.5に対応したVisual Studio 2008の目玉機能と言えば、なんといってもLINQ(Language INtegrated Query:言語統合クエリ)ではないでしょうか。

 これまではRDBMSのテーブルに格納されたデータやオブジェクトのコレクション、XMLドキュメントなど、データソースの種類ごとに異なったデータアクセスコードを記述する必要がありました。.NET Framework 3.5では新しいLINQの構文を活用することで、データソースの種類を気にせず、統一的な問い合わせコードでデータを操作できるようになります。

 ActiveReportsも、VS2008への対応と合わせてLINQを使ったデータの取り扱いに対応しました。今後は帳票として出力するデータの操作にLINQを活用するシーンも増えてくるのではないかと思います。

LINQを使うための準備

 これから紹介するサンプルコードでは、冒頭で紹介した「ActiveReportsアプリケーション」のプロジェクトテンプレートを使用しますが、ここで1つ、気をつけたいポイントがあります。

 このテンプレートで作成したプロジェクトのForm.csやProgram.csには、LINQを使用するための名前空間が設定されていません。プロジェクトをLINQのコードを記述するソースファイルを開いて、先頭にusingディレクティブ(VBの場合はImportsステートメント)を追加して、LINQを使えるようにしましょう。

LINQを使用するためのusingディレクティブ(C#)
using System.Linq;
LINQを使用するためのImportsステートメント(Visual Basic)
Imports System.Linq

 参照を追加したところで、さっそくLINQを利用した帳票作成を始めたいと思います。

ActiveReportsでLINQを使うときの原則

 ActiveReportsでは、帳票の出力元となるデータソースを、DataDynamics.ActiveReports.ActiveReport3オブジェクトのDataSourceプロパティに設定します。DataSourceプロパティの型はobject型になっているので、一見どんな型のオブジェクトを指定してもよさそうに見えますが、LINQによるクエリの結果をそのままデータソースとして使うことはできません。

 LINQのクエリ結果はSystem.Collections.Generics.IEnumerable<T>インターフェースを実装した型で返されます。ActiveReportsでLINQの問い合わせ結果をデータソースとして使うためには、問い合わせ結果をToListメソッドでリストの型(System.Collections.Generics.List<T>)に変換して渡します。

 LINQにはオブジェクトコレクションを操作するための「LINQ to Object」、データベースに格納されたデータにアクセスするための「LINQ to SQL」、XMLドキュメント用の「LINQ to XML」の3種類がありますが、どのタイプのLINQでもこのルールは同じです。

Enumerable.Rangeで作った列挙を表示させる

 それでは、まず最初は簡単な例でLINQを試してみましょう。

 System.Linq.Enumerableクラスには、IEnumerable<T>インターフェースを実装した各種データソースを操作するためのさまざまなメソッドが提供されています。Enumerable.Rangeメソッドは、指定された範囲の整数のシーケンスを返します。

 例えばEnumerable.Range(1, 10)と書くと、1から10までの数値の列挙がIEnumerableインターフェースで返されます。今回は、このデータの集まりに対して「4より大きな値」という検索条件を指定し、結果として「Countプロパティに数値を含む匿名クラス」を生成してその集合を返すクエリを書いてみましょう。

 VS2008で、冒頭に紹介した「ActiveReportsアプリケーション」のプロジェクトを新規作成し、デフォルトで作成されるフォームのLoadイベントに、以下のようにLINQのコードを追加してみましょう。

Form_Loadメソッドに、列挙から4以上の値を取得するクエリを追加する(C#)
private void Form1_Load(object sender, EventArgs e)
{
    NewActiveReport1 rpt = new NewActiveReport1();

    //クエリ元のデータを指定
    var query = from x in Enumerable.Range(1, 10) 
                where x > 4                       //検索条件を指定
                select new {Count = x};           //匿名クラスを生成

    rpt.DataSource = query.ToList();
    rpt.Run();
    this.viewer1.Document = rpt.Document;
}
Form_Loadメソッドに、列挙から4以上の値を取得するクエリを追加する(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 query = From x In Enumerable.Range(1, 10) _ 
              Where x > 4 _                       ' 検索条件を指定
              Select New With {.Count = x}        ' 匿名クラスを生成

  rpt.DataSource = query.ToList()
  rpt.Run()
  Me.Viewer1.Document = rpt.Document
End Sub

 なお、このコードの問い合わせ部分はLINQで記述する以外にも、IEnumerableインターフェースに定義されたメソッドを連結する形(メソッドチェイン)で書くことができます。また、条件式の部分にはC#/Visual Basicの新機能「ラムダ式」を使用することもできます。

 以下は、今紹介したLINQのクエリ部分を、メソッドチェインとラムダ式で書きかえたものです。見た目は少し違いますが、どちらも同じ意味になります。

問い合わせ部分をラムダ式で記述したもの(C#)
private void Form1_Load(object sender, EventArgs e)
{
    NewActiveReport1 rpt = new NewActiveReport1();

    //クエリ元のデータを指定
    var query = Enumerable.Range(1, 10)
            .Where(x => x > 4)
            .Select(x => new {Count = x});
    rpt.DataSource = query.ToList();
    rpt.Run();
    this.viewer1.Document = rpt.Document;
}
問い合わせ部分をラムダ式で記述したもの(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 query = Enumerable.Range(1, 10) _
            .Where (Function(x) x > 4) _
            .Select(Function(x) New With {.Count = x})
  rpt.DataSource = query.ToList()
  rpt.Run()
  Me.Viewer1.Document = rpt.Document
End Sub

帳票レイアウト側の設定と実行

 レポートファイル側では、LINQによって返される予定のオブジェクトを表示するために、Labelコントロールを1つ配置します(以下の帳票レイアウトの水色の部分)。LabelコントロールのDataFieldプロパティには、クエリの中で作成した匿名クラスで定義した「Count」プロパティを設定してください。

クエリ結果を表示するための帳票レイアウト
クエリ結果を表示するための帳票レイアウト

 コードの記述と帳票レイアウトの設定が終わったら準備完了です。

 F5キーを押してプロジェクトを実行すると、フォームのViewerコントロールには次のような結果が表示されます。

帳票の出力結果
帳票の出力結果

 1~10の整数のうち、where句で記述した検索条件(4より大きい)にマッチする6件のデータだけが表示されているのがわかります。

帳票出力にLINQを活用する(CSVファイルに含まれたデータの並べ替え・抽出)

 ここまではウォーミングアップということで、LINQを使った簡単なサンプルを紹介しました。ここからは、次はもう少し実用的なサンプルを紹介したいと思います。

 LINQを使うと、これまでSQLでやっていたようなデータの並べ替えや抽出、複数データソースの結合といった操作を、データソースの種類を問わず簡潔に記述できます。

CSVファイルに含まれたデータの並べ替え・抽出

 まずは、帳票のデータソースとして使用することも多いCSVファイルを、LINQで操作するサンプルを紹介します。

 以前の記事では、CSVファイルをデータソースにして帳票を出力する方法について紹介しましたが、そのときはStreamReaderを利用してファイルを一気に読み取るだけの形だったため、ファイル内のデータ順序は決まっているものとして説明していました。

 これまではファイルに格納されたデータを並べ替えたり、条件に一致したデータだけを抽出するためにファイルの各行を何らかのオブジェクトに変換し、それをいったんListに格納してから並べ替えたりといったコードを記述する必要がありましたが、LINQを使うとファイルに格納されたデータの並べ替えや抽出を簡単に書くことができます。

 以下のデータは今回使用するCSVファイルの内容です。このファイルには商品情報が含まれていて、1件分のデータは「商品コード」「商品名称」「単価」の3要素で構成されています。ここでは、CSVファイルが「C:\ActiveReports3」というフォルダに保存されているものとします。

データファイル(Products.csv)
A12358847,USBフラッシュメモリ(2GB) ,4980
A12318181,USBフラッシュメモリ(8GB) ,9980
A22175175,ブロードバンドルータ,24800
A71351582,ストレートLANケーブル(10m),1650
A47005782,20インチワイド液晶ディスプレイ,39800
A99157000,外付型DVDドライブ,13800
A72002487,A3対応インクジェットプリンタ,49800
A35365587,光学式5ボタンマウス,6500
A23548783,IEEE802.11g/b対応 無線LANアクセスポイント,7800
A55487527,A4対応モノクロレーザープリンター,29800

 このCSVファイルに対し「ファイルを読み込んで、単価の高いものから5件ぶんを降順で表示する」というコードを作成してみましょう。

商品情報を表示するための帳票レイアウト
商品情報を表示するための帳票レイアウト

 Detailセクションの、商品コードと商品名称を表示する位置にLabelコントロールを2つ配置し、DataFieldプロパティにはそれぞれ「ProductCode」「ProductName」を設定します。単価の部分は金額の書式表示としたいのでTextBoxコントロールを使用し、DataFieldプロパティには「UnitPrice」を、OutputFormatプロパティには「##,##0」を設定します。

 以下のコードはAcviteReportsプロジェクトのForm_Loadメソッドに、CSVファイルへアクセスするLINQのクエリを追加したものです。

 ファイルをStreamReaderで読み出して文字列のリストに変換する部分はサブルーチンとして別メソッドに切り出しています。取り込んだ各行はカンマで区切られた複数のデータを表す文字列なので、これを配列の形に変換します。LINQクエリの中でletキーワードを使い文字列をSplitメソッドで分解した結果を配列の形で保持しておくと、続きの部分を簡潔に書くことができます。

CSVファイルから目的のデータを抽出する(C#)
private void Form1_Load(object sender, EventArgs e)
{
  NewActiveReport1 rpt = new NewActiveReport1();

  string fileName = @"C:\ActiveReports3\Products.csv";
  using (StreamReader reader = File.OpenText(fileName))
  {
    var query = from line in GetLines(reader)
                 // 各行をカンマで区切る
                 let items = line.Split(',')                 
 
                 // 単価の高い順に並べ替え
                 orderby Convert.ToInt32(items[2]) descending 
                 select new {
                   ProductCode = items[0],
                   ProductName = items[1],
                   UnitPrice   = items[2]
                 };
    query = query.Take(5); // 結果から先頭5件分だけ取得
    rpt.DataSource = result.ToList();
    reader.Close();
  }
  rpt.Run();
  this.viewer1.Document = rpt.Document;
}

//StreamReaderで取得したデータをリストに変換するサブルーチン
private IEnumerable<string> GetLines(StreamReader r)
{
  while (!r.EndOfStream)
  {
    string line = r.ReadLine();
    yield return line;
  }
}
CSVファイルから目的のデータを抽出する(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 fileName = "C:\ActiveReports3\Products.csv"
  Using reader As New StreamReader(fileName)
    Dim query = From lines In GetLines(reader) _
                Let items = lines.Split(",") _  ' 各行をカンマで区切る
                Order By Convert.ToInt32(items(2)) Descending _ 
                                             ' 単価の高い順に並べ替え
                Select New With{ _
                    .ProductCode = items[0], _
                    .ProductName = items[1], _
                    .UnitPrice   = items[2] _
                }
    query = query.Take(5) ' 結果から先頭5件分だけ取得
    rpt.DataSource = query.ToList()
    reader.Close()
  End Using
  rpt.Run()
  Me.Viewer1.Document = rpt.Document
End Sub

'StreamReaderで取得したデータをリストに変換するサブルーチン
Private Function GetLines(ByRef Reader As StreamReader) _
  As IEnumerable(Of String)
  Dim result As New List(Of String)
  While Reader.EndOfStream <> True
    Dim line = Reader.ReadLine()
    Debug.WriteLine(line)
    result.Add(line)
  End While
  Return result
End Function

 コードの記述が終わったら、さっそくアプリケーションを実行してみましょう。以下のように、単価の高い商品5件だけが表示されるはずです。

CSVファイルに対するLINQクエリの実行結果
CSVファイルに対するLINQクエリの実行結果

帳票出力に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の活用法を中心に紹介しました。

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

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

著者プロフィール

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

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

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

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

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