意外と使いやすい、Datatableクラス

前回投稿したブログの続きを書こうとして、纏められないまま賞味期限が過ぎてしまいました。私はなんて愚かなんだ・・・。

すべては仕事が悪いよ仕事がー!などと言い訳しながら、仕事でちょっとした衝撃を受けたプログラミングについて1つ書こうかなと。

そのプログラミングは、VB.netで使用した「Datatable」クラス。

簡単に言うとこのクラスは、メモリー上にDBを持たせて変数としてセットする型。

この型に持たせると格納したデータの行や列の内容をフレキシブルに参照&編集ができ、特定のデータを抽出して別の変数に保持できたりと大変優秀です。現在行っている仕事ではこのDatatable型を使った制御が至る所であったので、忘備録兼今後VBをやる人用に書き留めておこうかと。

使い方としてはDB上でSQLを書き込んで実行、その結果をDatatable型の変数に格納するのがベター。

変数宣言は以下のように書き込む。


Dim dt As New DataTable(“テーブル名”);


Datatableに1行データを追加したい場合は事前にDataRow型の変数を定義し、列毎にデータ内容をセットして、Datatable.Rows.Addで格納する。

一例としてはこんな感じ。


‘変数宣言

DataTable tbl= new DataTable(“table1”);

DataRow row;

‘テーブルの列定義

tbl.Columns.Add(“id”,typeof(int));

tbl.Columns.Add(“name”, typeof(String));

tbl.Columns.Add(“kana”, typeof(String));

‘1行分のデータをセット

row = employee.NewRow();

row[“id”] = 1;

row[“name”] = “手素斗”;

row[“romaji”] = “テスト”;

‘Datatableに1行格納

Datatable.Rows.Add(row);


SELECTのSQL文を実行させて、その内容をDatatableにセットしたい場合は、row部分にSQLの結果を1つずつ入れていく。この手順だとExecuteNonQueryを使用することが多いとか。(ExecuteNonQueryについては省略)

さてここからが本題。今週の仕事で依頼された作業が、

1.SQLの実行結果を1行ごとにCSVで出力したい。

2.出力する順番は列Aの昇順。

3.1つのCSVに出力できるデータ数は100行まで。超える場合は新しいCSVに出力する。

4.列Aの内容が同じデータが複数行あり、すべて出力すると1つのCSVに出力できる100行の上限を超える場合は、それらのデータは新しいCSVに出力する。(既に99件出力しており、次に出力するデータがA列の内容が同じデータが2件ある場合は、新しいCSVに2行とも出力する)

(やべぇ…4の仕訳け方どう組めばいいんだ…)

当初は列Aが同じデータ毎の件数を出すSQLを組んで呼び出し、その内容を逐一保持して現在のCSVへ出力済みのデータ行数と加算した結果が100を超えるなら次のCSVへ仕訳けようと考えたりしていましたが、ここから新しいSQLを組むの管理難しくないか?となりまして断念。

せめて新しくSQLを組まずにDatatable型に入っている列Aが同じ内容のデータ件数が割り出せればー!と使えそうなDatatableクラスのメソッドがないか調べてましたが・・・


‘データテーブルのレコード数を取得

Console.WriteLine(Datatable.length);


ほほー。データテーブルに格納されているデータ行は.lengthで取得できるのか。

あとは列Aが同じ内容のデータだけ絞り出せるものがあればいいのだが・・・(検索ポチポチ)

こ れ だ !

Datatable.SelectメソッドでDatatable内のデータ行に対して特定の条件と同じデータを返すことができる。

書き方は、Datatable.Select(“列名 = XX”);

つまりこれとlengthを組み合わせれば、列Aが同じデータの件数が取得できるということで、

現在読み込んでいるデータ行の列Aの内容は、DataRow(“列A”);で取得して、Datatable.selectメソッドと繋げれば・・・


‘現在行の列Aの内容が同じデータ数を取得

Dim retuACount As Integer;

retuACount = Datatable.select(“列A = ‘” & DataRow(“列A”) & “‘”).length;


結果はビンゴ!見事列Aの内容が同じデータ行数が取得できました。

あとは現在CSVに出力されている行数と上記行数の合計が100を超えているかどうかで比較してあげれば、すんなりいけました。

普通にSQLの結果を配列で格納するのもいいですが、やはりメソッドが充実したクラスを使うのが一番良き。

実際DatatableクラスとSQLは鉄板の組み合わせのようで、調べてみるといろんなサイトでこの2つを使用したケース例が多いです。

その時、ふと閃いた!

このアイディアは、次の仕事の経験に活かせるかもしれない!

VB.netプログラミングの成長につながった!