前回投稿したブログの続きを書こうとして、纏められないまま賞味期限が過ぎてしまいました。私はなんて愚かなんだ・・・。
すべては仕事が悪いよ仕事がー!などと言い訳しながら、仕事でちょっとした衝撃を受けたプログラミングについて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プログラミングの成長につながった!