DevExpressのKnowledge Baseを見ていたら、以下の内容がありました。
- Can the grid display data from several data tables in a single grid view?
内容は、複数のDataTableの内容を一つのグリッドに表示することが出来るか?というものです。
普通は、データを取得するSQLで結合してしまってグリッドなどに表示することが多いと思いますが
それとは別に、解答の中で以下のクラスについて記述されていました。
- HOW TO: Implement a Custom DataView Class in Visual Basic .NET
上記記事内で、「JoinView」というクラスが紹介されています。
このクラスを利用すると、複数のDataTableのデータを一つのグリッドで表示する
ことが簡単にできます。
随分昔からあったみたいですが、知りませんでした (^_^;
仕事で似たようなものを自作した覚えはありますが。
で、とりあえず試してみました。
サンプルで利用しているデータベースは、Northwindです。
以下、サンプルです。
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Windows.Forms; namespace AdoNet_JoinView_NTables { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { DataSet ds = new DataSet(); using (DbConnection conn = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection()) { // // 接続. // conn.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True;"; conn.Open(); // // 表示に必要なデータを取得. // DataTable customers = new DataTable("Customers"); DataTable employees = new DataTable("Employees"); DataTable orders = new DataTable("Orders"); Read(customers, conn, @"SELECT * FROM Customers"); Read(employees, conn, @"SELECT * FROM Employees"); Read(orders, conn, @"SELECT * FROM Orders"); // // 一旦データセットにまとめ、リレーション設定. // ds.Tables.AddRange(new[] { customers, employees, orders }); ds.Relations.Add("CustOrd", customers.Columns["CustomerID"], orders.Columns["CustomerID"]); ds.Relations.Add("EmpOrd", employees.Columns["EmployeeID"], orders.Columns["EmployeeID"]); } // // 結合ビューを作成し、DataGridViewにデータソースとして設定. // // コンストラクタに指定する内容は // ・起点となるデータテーブル // ・表示項目(複数の場合カンマで結合、別テーブルの項目はリレーション名を付与して設定する) // ・絞り込み条件 (オプション) // ・ソートオーダー(オプション) // JoinView dataSource = new JoinView( ds.Tables["Orders"], "OrderID,CustomerID,EmployeeID,OrderDate,CustOrd.CompanyName Company,CustOrd.ContactName Contact,CustOrd.ContactTitle Position,EmpOrd.FirstName,EmpOrd.LastName", "EmployeeID < 10", "OrderDate" ); dgvMain.DataSource = dataSource; } private void Read(DataTable table, DbConnection conn, string query) { using (DbCommand command = conn.CreateCommand()) { command.CommandText = query; using (DbDataReader reader = command.ExecuteReader()) { table.Load(reader); } } } } }
実行すると以下のようにちゃんと表示されます。
(FirstNameとかLastNameなどの部分)
取り込んで、利用する場合は無理にC#などに変換すると
手直しが大変なので、VBプロジェクトを作成して
DLLで利用した方が楽です。その際、Option StrictをOffに
しないと、大量にエラーが発生するので注意。
私は、面倒なのでOffにしました。w
サンプルは以下の場所にアップしてあります。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ