システム開発で欠かせないのが、データベースですよね。
そして、VB.NET では、DataTable クラスを使用して操作する方法が多いと思います。
また、DataTable クラスはデータベース以外でも使えるので、覚えておくと便利ですよ!
ちなみに、データベースの接続/操作方法については、中年 SE の下記ブログを読んでみてくださいね。
DataTable オブジェクトに列を追加/データを追加
まずは、下記ソースを参考に DataTable オブジェクトに列とデータを追加してみましょう!
尚、フォームには DataGridView コントロール(GrdNormal と GrdDistintc)を 2 つ追加してあります。
用途は、DataTable オブジェクトにセットした値を表示するためです。
'変数の宣言
Dim dt As New DataTable()
Dim row As DataRow = Nothing
'DataTable に列を作成
dt.Columns.Add("EMP_CD", Type.GetType("System.String"))
dt.Columns.Add("EMP_NAME", Type.GetType("System.String"))
dt.Columns.Add("FLOOR", Type.GetType("System.Int32"))
dt.Columns.Add("MEMO", Type.GetType("System.String"))
'DataTable の列と同じレコードを生成、及び、値の設定
'1 レコード目
row = dt.NewRow()
row("EMP_CD") = "001"
row("EMP_NAME") = "経理部"
row("FLOOR") = 1
row("MEMO") = String.Empty
dt.Rows.Add(row)
'2 レコード目
row = dt.NewRow()
row("EMP_CD") = "002"
row("EMP_NAME") = "営業部"
row("FLOOR") = 1
row("MEMO") = String.Empty
dt.Rows.Add(row)
'3 レコード目
row = dt.NewRow()
row("EMP_CD") = "003"
row("EMP_NAME") = "開発部"
row("FLOOR") = 1
row("MEMO") = String.Empty
dt.Rows.Add(row)
'DataGridView に DataTable の値を表示
GrdNormal.DataSource = Nothing
GrdNormal.DataSource = dt
上記プログラムを実行すると、GrdNormal グリッドビューには下記の通り表示されます。
一番下の行(*が表示されている行)は、新規追加行となるので、今回追加したレコードではありませんので注意してくださいね。
上記ソースの続きで、下記ソースを追加してください。
内容は、「FLOOR」列と「MEMO」列の値を Distinct し、重複行を除去したレコードを DataGridView に表示します。
'変数の宣言
Dim dv As DataView = Nothing
Dim dtDis As DataTable = Nothing
'作成した DatatTable に対する DataView を生成
dv = New DataView(dt)
'「FLOOR、MEMO」で Distinct したレコードを取得
dtDis = dv.ToTable(True, "FLOOR", "MEMO")
'DataGridView に「FLOOR、MEMO」で Distinct した値を表示
GrdDistintc.DataSource = Nothing
GrdDistintc.DataSource = dtDis
上記プログラムを実行すると、GrdDistintc グリッドビューには下記の通り表示されます。
3 レコードとも、
- 「FLOOR」列には『1』
- 「MEMO」列には『空文字』
がセットされているので、Distinct した結果は 1 レコードに纏まります。
DataView の Distinct 動作の注意点【超重要】
中年 SE は昔、この DataView で Distinct した時に、どーしても想定した値が取得できなくてハマったことがあったので、注意点として記載しておきますね!
注意してほしい点は、Distinct する列に『NULL』値が含まれる列があるかどうかです。
ソースコード 1(a)を、下記のように修正して実行してみましょう。
ちなみに変更した内容は「2 レコード目の MEMO 列に、NULL 値(DBNull.Value)をセット」です。
'変数の宣言
Dim dt As New DataTable()
Dim row As DataRow = Nothing
'DataTable に列を作成
dt.Columns.Add("EMP_CD", Type.GetType("System.String"))
dt.Columns.Add("EMP_NAME", Type.GetType("System.String"))
dt.Columns.Add("FLOOR", Type.GetType("System.Int32"))
dt.Columns.Add("MEMO", Type.GetType("System.String"))
'DataTable の列と同じレコードを生成、及び、値の設定
'1 レコード目
row = dt.NewRow()
row("EMP_CD") = "001"
row("EMP_NAME") = "経理部"
row("FLOOR") = 1
row("MEMO") = String.Empty
dt.Rows.Add(row)
'2 レコード目
row = dt.NewRow()
row("EMP_CD") = "002"
row("EMP_NAME") = "営業部"
row("FLOOR") = 1
row("MEMO") = DBNull.Value
dt.Rows.Add(row)
'3 レコード目
row = dt.NewRow()
row("EMP_CD") = "003"
row("EMP_NAME") = "開発部"
row("FLOOR") = 1
row("MEMO") = String.Empty
dt.Rows.Add(row)
'DataGridView に DataTable の値を表示
GrdNormal.DataSource = Nothing
GrdNormal.DataSource = dt
上記プログラムを実行すると、GrdNormal グリッドビューには下記の通り表示されます。
ソースコード 1(a)で実行した時と同じ表示結果ですよね。
でも、実際の値としては「NULL がセットされているので空文字とは違う」ということに注意してください。
ソースコード 2 は変更せずに実行してください。
すると、GrdDistintc グリッドビューには下記の通り表示されます。
1,3 レコード目には、
- 「FLOOR」列には『1』
- 「MEMO」列には『空文字』
をセットしました。
2 レコード目には、
- 「FLOOR」列には『1』
- 「MEMO」列には『DBNull.Value』
をセットしました。
空文字と NULL は DataGridView に表示した際、セルには何も表示されないので、一見すると全く同じに見えます。
しかし、実際の値としては空文字と NULL は別物なので、Distinct した結果は 2 レコードに纏まります。
この動作に注意しないで、DataGridView だけを見て判断していると、調査しているときにハマる場合があるので気を付けてくださいね!
今回に限らず、データベースのデータを取り扱う際には、「NULLと空文字の違い」をしっかりと理解していきましょう!
中年 SE との約束だよ!!