VB.NETでDataGridViewへAccessのデータベースファイルを読み込む
新しく VB.NET のタグを作りました。仕事でやったことを「あー、あのときどうしたんだっけー!」と忘れた時用に書いていきたいと思います。どれだけの方に需要があるかは分かりませんが…。。どこかでどなたかの検索にひっかかってくだされば嬉しいなーと思います。
関連記事
- DataGridViewへAccessのデータベースファイルを読み込む ←NOW!
- AccessDBテーブルの主キー情報を取得する
- DataGridViewに読み込んだDB情報を再取得する
- DataGridViewをセル編集したときの行数を格納する
- Accessのデータベースファイルへ書き込むための接続・切断
- Accessデータベースのレコードを削除する
- Accessデータベースを更新する
ガッツリ続き物になってしまいました…。過去の分と合わせて順番に読んでいただけると分かりやすいかと思います。
なるべく簡素に書いているので、例外処理は甘いと思われます。ご参考にする際は、ご自分の環境に合わせてご修正ください。
解説のためツギハギしちゃったので、最後の記事(7回め)に全コードまとめてあります。書いたときの環境
- Visual Studio 2010
- .NET Framework 4.0
です。
背景
MS AccessのDBを使っているシステムがいくつかあるんですが、社内全てのPCにAccessが入ってるわけじゃないんですよね。
昔書いたこの記事のように、DBだけ用意しておいて、読み書きはExcelからやっちゃうなんてことも。でも、Officeすら入ってないPCからちょこっと中身を見たり、変更したいという必要に迫られまして。
というわけで、VBから既存のAccessのDBを操作するようなものをちょっとずつ作ってるメモです。
今回の目的
既存のDBファイルのテーブルをDataGridViewへ読み込みます。テーブルごとにSQLをベタ書きするんじゃなくて、テーブル名だけ指定すれば同じコードで全部のテーブルに対応できる、というのがいいなーと思って書きました。
AccessのDBを用意
とりあえずふたつ、簡単なテーブルを作っておきます。型とかはこんな感じにしておきました。主キーが複数というパターンもあったのでそういうのも作っておきます。(今回は読み込むだけなので使いませんが、今後主キー情報を取得したりするつもりです。)
まずは読み込みをしたいので、適当にデータを入れておきます。
Visual Studio 2010にて
Windowsフォームアプリケーションを作ります。
Form1.vb [デザイン]
スタートアップフォームであるForm1
に、テーブルの名前をText
に設定したボタンを、テーブルの数だけつけておきます。ボタンは、ツールボックスの [コモン コントロール] の中です。
Form1.vb [コード]
Form1のコード画面へ、以下を書きます。
'### Form1.vb ### Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Form2.Text = Button1.Text 'タイトルをテーブル名に Form2.Show() 'Fomr2を表示 End Sub Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click Form2.Text = Button2.Text 'タイトルをテーブル名に Form2.Show() 'Fomr2を表示 End Sub End Class
ボタンのテキストがテーブル名になっているので、それをForm2のタイトルに入れてしまおうという魂胆。ここでは、Form2を開くだけ。
Button1_Clickの記述が間違ってたのをご指摘いただいて修正しました! ありがとうございました!
Form2.vb [デザイン]
[プロジェクト] → [Windows フォームの追加] → [Windows フォーム] → [作成] で、Form2
が出来ます。
ここへ、テーブルを読み込むDataGridView1
を作ります。DataGridViewは、ツールボックスの [データ] の中です。
[データ ソースの選択] が [なし] になってるので、DataGridView上で編集しても直でDBに変更がかからない仕様です。追加と編集だけ有効にしておいて、後でボタンをつけて、クリックしたらDB編集するSQLを走らせる、みたいなのにしようかなーと。
DBtable.vb
Form2 のコードでインスタンスを作るので、その元となるクラスを先に作ります。[プロジェクト] → [クラスの追加] で、DBtable.vb
という名前にします。
'### DBtable.vb ### Imports System.Data.OleDb Class DBtable 'フィールド Private tableName As Object Private fileName As String Private dgv As DataGridView = Form2.DataGridView1 'コンストラクタ Sub New(tableName_ As Object, fileName_ As String) tableName = tableName_ fileName = fileName_ End Sub '---------------------------------------------------- ' テーブルに関すること '---------------------------------------------------- Private dbCnc As OleDbConnection Private dbAdp As OleDbDataAdapter Private tableData As DataTable Public Sub setDataSource() 'テーブルデータ読込 tableData = getTableData("SELECT * FROM " & tableName & ";") 'データグリッドビューへバインド Dim bindingSource1 As New BindingSource() bindingSource1.DataSource = tableData dgv.DataSource = bindingSource1 End Sub Private Function getTableData(ByVal strSQL As String) As DataTable 'テーブルを接続 dbCnc = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; " & "Data Source=" & fileName) dbAdp = New OleDbDataAdapter(strSQL, dbCnc) Dim table As New DataTable dbAdp.Fill(table) Return table End Function Public Sub Dispose() 'コネクション切断(なくてもいい気もする) dbAdp.Dispose() 'アダプター破棄 dbCnc.Dispose() 'コネクションを破棄 End Sub End Class
テーブル名と、対象のAccessファイル名を引数として持ってきて、接続したりバインドしたりほにゃほにゃ。
42~46行のDisposeプロシージャは、接続するなら切断したほうがいいんじゃないの…、と思って書いてはみたものの、破棄せずにインスタンス再生成したときとかもちゃんとキレイになってたのでなくてもいいかもしれない…。一応書いておいた名残です。
こちらを参考にさせていただきました。
Form2.vb [コード]
Form2をロードするとき(22行)に DBtable クラスのインスタンスを作って、DataGridView にセットします。
'### Form2.vb ### Public Class Form2 Private Const FILE_NAME As String = "C:\test.accdb" Private db As DBtable Private dgv As DataGridView '---------------------------------------------------- ' メソッド '---------------------------------------------------- Private Sub setTable() 'DataGridViewにテーブル内容をセット db = New DBtable(Me.Text, FILE_NAME) 'インスタンス生成 db.setDataSource() 'データセット End Sub '---------------------------------------------------- ' Formイベント '---------------------------------------------------- Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load 'フォームロード時 dgv = Me.DataGridView1 Call setTable() End Sub Private Sub Form2_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed 'フォームが閉じたとき db.Dispose() End Sub End Class
27行目のDisposeは、せっかく接続破棄のプロシージャを作ったので、フォームが閉じるときに呼び出しておきます(なくてもいい気がする)。
動作テスト
F5キーでデバッグ開始するとForm1
が起動するので、各テーブル名のボタンを押してやると、
このように、テーブルごとに中身を表示できます。
今後、ここから更新や削除を行えるようにしていく予定です。テーブルによって主キーの数やそれぞれフィールドの型が違うので、そこを取得しながら汎用的に使えるコードにできたらなーと思っています。
2件のコメント
このような内容を探していました。
今後の参考にさせていただきます。
細かい点ですが、Form1.vb [コード]のボタン名が違っているようです。
誤:Private Sub table1_Click(
正:Private Sub Button1_Click(
y.yさんコメントありがとうございます! 何年も間違いに気づいてませんでした…Σ(゚д゚lll) ご指摘ありがとうございます!
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)
YouTubeでQ&Aコンテンツを企画しています
運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。