2015
3
16

VB.NETからAccessデータベースを更新する

VB.NET で MSAccess のデータベースをどうにかするシリーズ、一応今回で完結です! INSERT と UPDATE を実装していきますー。


関連記事

  1. DataGridViewへAccessのデータベースファイルを読み込む
  2. AccessDBテーブルの主キーと各フィールド型を取得する
  3. DataGridViewに読み込んだDB情報を再取得する
  4. DataGridViewをセル編集したときの行数を格納する
  5. Accessのデータベースファイルへ書き込むための接続・切断
  6. Accessデータベースのレコードを削除する
  7. Accessデータベースを更新する ←NOW!

ガッツリ続き物になってしまいました…。過去の分と合わせて順番に読んでいただけると分かりやすいかと思います。

なるべく簡素に書いているので、例外処理は甘いと思われます。ご参考にする際は、ご自分の環境に合わせてご修正ください。

環境

  • Visual Studio 2010
  • .NET Framework 4.0

です。

コード

150316-1

今までの実装で、追加や変更したセルに色がついて該当行(ゼロから始まる)が格納されているはずです。ここで「保存」ボタンを押して走るコードを実装します。

Form2.vb

3~5行目で、どこも編集されていなければ終了しちゃいます。

8行目で SQL の処理の書いてあるプロシージャに飛ばします。

Module1.vb

こちらがそのプロシージャ。ちょっと長いので分離させました。これだけ見ると DELETE 文を書いたときとほぼ同じテンプレです。

UPDATEの処理

上記 DBsave プロシージャの7行目に入る部分。

ListBox3 には UPDATE する行数が格納されているので、そのアイテム数ぶん繰り返します。

3行目で UPDATE 文の冒頭を格納し、4~13行で DataGridView のカラム数(= フィールドの数)ぶん繰り返して、SQL 文を追記していきます。

5~8行目では、主キーのフィールドかどうかを判定しています。UPDATE では主キーは変更しない仕様にしたいので、主キー情報(ListBox1)と照らしあわせて該当のフィールドが主キーだったらフラグを立てておきます。

9行目でオートインクリメントではないこと(変更できないので)& 主キーでないことという条件に当てはまったら、10, 11行目が UPDATE 文のメイン部分を作っているところになります。

150316-3

図のように、10行目は各フィールドの中身(緑のところ)のみを作っています。ここが、数値だったり文字列だったり日付だったり、型が違えば括る文字が違います。NULL 判定(空かどうか)もしなきゃいけないので、ここはMAKE_field_txtという関数を別に作って(INSERT でも使うので後述します)そちらで生成して返り値を使うことにします。

11行目でフィールド名(= カラム名)、先の返り値、区切りのカンマを結合しています。全部ループし終わると最後のカンマが不要になるので、14行目で末尾を1文字削ります。

後は前回書いた WHERE 句を生成する関数を呼び出して(17行目)、こちらも結合して(19行目)、UPDATE 文が出来上がります。

INSERTの処理

上記 DBsave プロシージャの9行目に入る部分。

INSERT は ListBox4 に行数が格納されているので、そのアイテム数ぶん繰り返します。

3行目で冒頭部分を格納し、6~10行で先に(オートインクリメントを覗いた)フィールド名だけどんどん追記していきます。終わったらカンマをひとつ削り(11行目)、構文を追加(12行目)。

15~20行目でフィールドの中身をまた追記していきますが、先ほどの UPDATE のときに使った関数を再利用(17行目)します。関数の中身はこのあと書きますー。

で、最後のカンマを削って(21行目)、構文のカッコをつけて(22行目)、INSERT 文も出来上がりです。

フィールドの中身を生成する関数

こちらが各フィールドの中身をその都度生成する関数。DataGridView の該当行数(row_n)、該当列数(i)、型名(pattern)を引数として受け取って処理します。

8行目でまず空かどうかを判別して、中身がある場合は9~16行目で、型情報を見て、テキストなら「’」、日付型なら「#」(日付を#で括るのは Access 独特ですね)、それ以外は「無し」など、括る文字を設定してやります。足りないようならここで追加設定してください。その後17行目で結合しています。

中身が無かった場合は19~23行で、大体は「NULL」と入れてしまえば良いのですが、DataGridView の新行かつ型が Boolean で何もセルを触らなかった場合、「false」でなく「NULL」と判定されてしまう現象が確認できたので、ここで処理しています。他にも何かあったらここで設定したほうが良いかもしれません。

そんな感じで、最終的に出来たものを26行目で返り値として返してやり、これを UPDATE や INSERT 文に組み込んでいきます。

動作確認

動かしてみます。

150316-1

中身を変えて「保存」ボタンを押すと、

150316-2

出来た! …けど、あれ? INSERT した行が一番上になってる…。

調べてみると、こちらのページの最後の方にこうありました。

並び順を指定しなかった場合取得したレコードは予測不可能な順番で並んでいるということを覚えておいてください。
なお、並び順を指定する場合はSQL文でORDER BYを使用します。

(中略)

SQL Serverの場合は並び順を指定しなかった場合はクラスタードインデックス(つまり主キー)の順に自動的に整列します。つまり、このあたりの仕様はデータベースによって異なります。そういったことをこまごまと気にするのは大変なので順番が重要な場合はORDER BYを指定する癖をつけておきましょう。

なるほど。ちなみにこの VB で新しく追加したレコードを Access を起動して見てみたら、そちらでは一番下に追加されていましたので、DataGridView の仕様かもしれません。気になる方は ORDER BY で並び順もきちんと指定してあげるのが良さそうです。

こんな感じですが、一応、当初やりたかった機能は全て実装することが出来たので、これでこのシリーズは終了になります。需要は少ない気がしますが、どなたかのお役に立てたら光栄です。

  • このエントリーをはてなブックマークに追加
  • follow us in feedly 618
  • RSSを登録

公開日:2015/03/16


コメントを残す




*印は必須項目です。コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にですがスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)


back to top