DataTable自体があまり使われないのかもしれないけど、データベースからとってきた値をとりあえず入れて使う分には使いやすいのでよく使う。
プログラマーによってクラスの作り方がバラバラだったり、共通関数に渡すときに統一できたりとか、Webサービスからデータを渡すときに簡単に渡せたりするんで結構重宝している。
CSVとデータベースの値を結合したり、CSVとCSVを結合したりするときにもSQLみたいに書きたい要望があったりするのでそのサンプル。
※まれにデータが数百万行あったりして、SQLよりもLINQで処理したほうが早いケースがあったりするときに書き直したりする。
VB.NET ====
''' <summary>
''' Left Join
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub btnLeftJoin_Click(sender As Object, e As EventArgs) Handles btnLeftJoin.Click
Dim dtUri As New DataTable
Dim drUriSample As DataRow
' ▼ 売上データ
dtUri.Columns.Add(New DataColumn("売上No", GetType(Integer)))
dtUri.Columns.Add(New DataColumn("売上日", GetType(String)))
dtUri.Columns.Add(New DataColumn("得意先CD", GetType(String)))
dtUri.Columns.Add(New DataColumn("商品名", GetType(String)))
dtUri.Columns.Add(New DataColumn("売上数量", GetType(Decimal)))
dtUri.Columns.Add(New DataColumn("売上金額", GetType(Decimal)))
' テストデータ
drUriSample = dtUri.NewRow
drUriSample("売上No") = 1
drUriSample("売上日") = "20171031"
drUriSample("得意先CD") = "00001"
drUriSample("商品名") = "パソコン"
drUriSample("売上数量") = 1
drUriSample("売上金額") = 150000
dtUri.Rows.Add(drUriSample)
drUriSample = dtUri.NewRow
drUriSample("売上No") = 2
drUriSample("売上日") = "20171031"
drUriSample("得意先CD") = "00002"
drUriSample("商品名") = "マウス"
drUriSample("売上数量") = 1
drUriSample("売上金額") = 3000
dtUri.Rows.Add(drUriSample)
drUriSample = dtUri.NewRow
drUriSample("売上No") = 1
drUriSample("売上日") = "20171031"
drUriSample("得意先CD") = "00001"
drUriSample("商品名") = "モニター"
drUriSample("売上数量") = 2
drUriSample("売上金額") = 30000
dtUri.Rows.Add(drUriSample)
' ▼ 得意先データ
Dim dtTok As New DataTable
Dim drTokSample As DataRow
dtTok.Columns.Add(New DataColumn("得意先CD", GetType(String)))
dtTok.Columns.Add(New DataColumn("得意先名", GetType(String)))
dtTok.Columns.Add(New DataColumn("備考", GetType(String)))
' テストデータ
drTokSample = dtTok.NewRow
drTokSample("得意先CD") = "00001"
drTokSample("得意先名") = "株式会社 システム作ろう"
drTokSample("備考") = ""
dtTok.Rows.Add(drTokSample)
drTokSample = dtTok.NewRow
drTokSample("得意先CD") = "00002"
drTokSample("得意先名") = "株式会社 いろいろ販売"
drTokSample("備考") = ""
dtTok.Rows.Add(drTokSample)
Dim dtUriIchiran As New DataTable
Dim drIchiran As DataRow
' ▼ 売上一覧
dtUriIchiran.Columns.Add(New DataColumn("売上No", GetType(Integer)))
dtUriIchiran.Columns.Add(New DataColumn("売上日", GetType(String)))
dtUriIchiran.Columns.Add(New DataColumn("得意先CD", GetType(String)))
dtUriIchiran.Columns.Add(New DataColumn("得意先名", GetType(String)))
dtUriIchiran.Columns.Add(New DataColumn("売上数量", GetType(Decimal)))
dtUriIchiran.Columns.Add(New DataColumn("売上金額", GetType(Decimal)))
Dim lnqIchiran = From drUri In dtUri.AsEnumerable
Group Join drTok In dtTok
On drUri("得意先CD") Equals drTok("得意先CD")
Into grp = Group
From drTokEmpty In grp.DefaultIfEmpty
Select New With {
.売上No = drUri("売上No"),
.売上日 = drUri("売上日"),
.得意先CD = drUri("得意先CD"),
.得意先名 = If(drTokEmpty("得意先名") Is Nothing, "", drTokEmpty("得意先名")),
.売上数量 = drUri("売上数量"),
.売上金額 = drUri("売上金額")
}
For Each lnqdr In lnqIchiran
drIchiran = dtUriIchiran.NewRow
drIchiran("売上No") = lnqdr.売上No
drIchiran("売上日") = lnqdr.売上日
drIchiran("得意先CD") = lnqdr.得意先CD
drIchiran("得意先名") = lnqdr.得意先名
drIchiran("売上数量") = lnqdr.売上数量
drIchiran("売上金額") = lnqdr.売上金額
dtUriIchiran.Rows.Add(drIchiran)
Next
End Sub
C# ====
private void btnLeftJoin_Click(object sender, EventArgs e)
{
DataTable dtUri = new System.Data.DataTable();
DataRow drUriSample = null;
// ▼ 売上データ
dtUri.Columns.Add(new DataColumn("売上No", typeof(int)));
dtUri.Columns.Add(new DataColumn("売上日", typeof(string)));
dtUri.Columns.Add(new DataColumn("得意先CD", typeof(string)));
dtUri.Columns.Add(new DataColumn("商品名", typeof(string)));
dtUri.Columns.Add(new DataColumn("売上数量", typeof(decimal)));
dtUri.Columns.Add(new DataColumn("売上金額", typeof(decimal)));
// テストデータ
drUriSample = dtUri.NewRow();
drUriSample["売上No"] = 1;
drUriSample["売上日"] = "20171031";
drUriSample["得意先CD"] = "00001";
drUriSample["商品名"] = "パソコン";
drUriSample["売上数量"] = 1;
drUriSample["売上金額"] = 150000;
dtUri.Rows.Add(drUriSample);
drUriSample = dtUri.NewRow();
drUriSample["売上No"] = 2;
drUriSample["売上日"] = "20171031";
drUriSample["得意先CD"] = "00002";
drUriSample["商品名"] = "マウス"; ;
drUriSample["売上数量"] = 1;
drUriSample["売上金額"] = 3000;
dtUri.Rows.Add(drUriSample);
drUriSample = dtUri.NewRow();
drUriSample["売上No"] = 1;
drUriSample["売上日"] = "20171031";
drUriSample["得意先CD"] = "00001";
drUriSample["商品名"] = "モニター";
drUriSample["売上数量"] = 2;
drUriSample["売上金額"] = 30000;
dtUri.Rows.Add(drUriSample);
// ▼ 得意先データ
DataTable dtTok = new DataTable();
DataRow drTokSample = null;
dtTok.Columns.Add(new DataColumn("得意先CD", typeof(string)));
dtTok.Columns.Add(new DataColumn("得意先名", typeof(string)));
dtTok.Columns.Add(new DataColumn("備考", typeof(string)));
// テストデータ
drTokSample = dtTok.NewRow();
drTokSample["得意先CD"] = "00001";
drTokSample["得意先名"] = "株式会社 システム作ろう";
drTokSample["備考"] = "";
dtTok.Rows.Add(drTokSample);
drTokSample = dtTok.NewRow();
drTokSample["得意先CD"] = "00004";
drTokSample["得意先名"] = "株式会社 いろいろ販売";
drTokSample["備考"] = "";
dtTok.Rows.Add(drTokSample);
DataTable dtUriIchiran = new DataTable();
DataRow drIchiran = null;
// ▼ 売上一覧
dtUriIchiran.Columns.Add(new DataColumn("売上No", typeof(int)));
dtUriIchiran.Columns.Add(new DataColumn("売上日", typeof(string)));
dtUriIchiran.Columns.Add(new DataColumn("得意先CD", typeof(string)));
dtUriIchiran.Columns.Add(new DataColumn("得意先名", typeof(string)));
dtUriIchiran.Columns.Add(new DataColumn("売上数量", typeof(decimal)));
dtUriIchiran.Columns.Add(new DataColumn("売上金額", typeof(decimal)));
var lnqIchiran = from drUri in dtUri.AsEnumerable()
join drTok in dtTok.AsEnumerable()
on drUri["得意先CD"] equals drTok["得意先CD"]
into tokGroup
from drTokEmpty in tokGroup.DefaultIfEmpty()
select new
{
売上No = drUri["売上No"],
売上日 = drUri["売上日"],
得意先CD = drUri["得意先CD"],
得意先名 = (drTokEmpty == null) ? "" : drTokEmpty["得意先名"],
売上数量 = drUri["売上数量"],
売上金額 = drUri["売上金額"]
};
foreach (var lnqdr in lnqIchiran)
{
drIchiran = dtUriIchiran.NewRow();
drIchiran["売上No"] = lnqdr.売上No;
drIchiran["売上日"] = lnqdr.売上日;
drIchiran["得意先CD"] = lnqdr.得意先CD;
drIchiran["得意先名"] = lnqdr.得意先名;
drIchiran["売上数量"] = lnqdr.売上数量;
drIchiran["売上金額"] = lnqdr.売上金額;
dtUriIchiran.Rows.Add(drIchiran);
}
}
===========
on句で結合するときに別の関数を間に挟んだりできるので結構便利
例)Private MaeZero(string Value,int Keta) As String ->前ゼロ梅する関数
Dim lnqIchiran = From drUri In dtUri.AsEnumerable
Group Join drTok In dtTok
On MaeZero(drUri("得意先CD"),5) Equals MaeZero(drTok("得意先CD"),5)
Into grp = Group
From drTokEmpty In grp.DefaultIfEmpty
Select New With {
.売上No = drUri("売上No"),
.売上日 = drUri("売上日"),
.得意先CD = drUri("得意先CD"),
.得意先名 = If(drTokEmpty("得意先名") Is Nothing, "", drTokEmpty("得意先名")),
.売上数量 = drUri("売上数量"),
.売上金額 = drUri("売上金額")
}
Group Join drTok In dtTok
On MaeZero(drUri("得意先CD"),5) Equals MaeZero(drTok("得意先CD"),5)
Into grp = Group
From drTokEmpty In grp.DefaultIfEmpty
Select New With {
.売上No = drUri("売上No"),
.売上日 = drUri("売上日"),
.得意先CD = drUri("得意先CD"),
.得意先名 = If(drTokEmpty("得意先名") Is Nothing, "", drTokEmpty("得意先名")),
.売上数量 = drUri("売上数量"),
.売上金額 = drUri("売上金額")
}
ただ、プロジェクト単位である程度書き方を統一しておかないとプログラマさんによっては書き方が全然違うので保守とか考えるときは注意したほうがいい。
みんなが知識ある人ばっかりだったらそんなに気にしなくてもいいかもしれないけど、開発の後半になって仕様変更とかで危なそうな個所を探すときにも書き方が一緒じゃないとGrepしても引っかからなかったりする。
パッと見でもわからないし・・・。