2015年10月24日土曜日

VBA:データベースにアクセスする 解説

すでに書いたデータベースとエクセルVBAをつなぐ方法を見てみましょう。これを解説してみたいと思います。

Sub Test()
    Dim adoCON      As New ADODB.Connection
    Dim adoRS       As New ADODB.Recordset
    Dim strSQL      As String
    Dim odbdDB      As Variant
    Dim wSheetName  As Variant
    Dim i           As Integer
    Dim Num1        As Integer
 
    odbdDB = ActiveWorkbook.Path & "\DB_name.accdb"

    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                        & "Data Source=" & odbdDB & ""
    adoCON.Open

前半部分です。この辺はまあ特に難しい部分はなく、見たままという感じですね。ここでは変数宣言をする場所でADODB.ConnectionにadoCONという名前をつけています。同じ変数宣言の場所でADODB.RecordsetにadoRSという名前をつけています。このadoRSがレコードセットですね。

前半部分は「あらかじめ使う変数を宣言する」ことと、「adoCON(ADODB.Connection)を開く」という2つのことをしています。まだレコードセットは宣言しただけで使われていません。

    adoCON.BeginTrans

    adoRS.CursorLocation = adUseClient

次にこの部分ですが、前にも説明したとおり、adoCON.BeginTransはトランザクションを始めるものです。adoCON.CommitTransはトランザクションを終了します。トランザクションはデータの扱いの正確性を保障するためのものなので無くてもプログラム自体は動きます。トランザクションについては他サイト様を参照ください。

 その下のこれ「adoRS.CursorLocation = adUseClient」ですが、これはカーソルの位置を変更しています。これはデータの管理をサーバー側・クライアント側どちらで行うのかを設定するものであり、「adUseClient」という値を設定し、カーソルの位置をクライアント側にすることで「クライアント側でデータを管理するよ」と宣言しています。この設定はレコードセットを開く前に設定しなければいけません。詳しくは他サイト様を参照してください。

次の部分

        strSQL = "SELECT * FROM table_name ORDER BY table_name.ID;"

これはSQL文です。VBAでSQLを用いることによって、データベースでデータの検索をしたり、データの削除、書き換えが可能になります。

VBAでSQLを使う場合、上記のようにダブルクオーテーションマークで囲む必要があります(赤く塗ってありますがわかりますか?)。今回はSQLでIDという項目の順番にすべてのデータを取得しています。

SQLでTextBox1.Valueに等しい値の検索をする場合はつぎのようになります。

strSQL = "SELECT * FROM table_name WHERE subject_of_the_table = " & TextBox1.Value & ";"

変数の値としてTextBox1.Valueを用いていますが、この場合は変数の値が数値であることを想定しています。仮にTextBox1.Valueの値が文字列だった場合、次のように記述します。

strSQL = "SELECT * FROM table_name WHERE subject_of_the_table  LIKE '" & TextBox1.Value & "';"

数値の場合と違うのは変数名がさらにシングルクオーテーションで囲まれていること、項目名の指定にイコール(=)ではなくLIKEが使われていることです。

 adoRS.Open strSQL, adoCON, adOpenDynamic

ここではOpenメソッドをつかってレコードセットを開いています。レコードセットとは、データベースのデータ全体やクエリの実行で取得したデータのことをいいます。

レコードセットは

Recordset.Open([Source], [ActiveConnection], [CursorType], [LockType], [Options])

というふうにOpenされます。私のコードでは[Source]としてstrSQL(SQL文)、[ActiveConnection]としてadoCON、[CursorType]としてadOpenDynamicを選択しています。strSQLっていうのはSQL文を代入したString型の変数です。adOpenDynamicは動的カーソルで、レコードセット内でのすべての種類の移動を許可します。

つぎにこの部分ですが、ここは簡単ですね。

 wSheetName = ActiveSheet.Name
    i = 1
    Do Until adoRS.EOF
        With Worksheets(wSheetName)
            .Cells(i, 1).Value = adoRS!ID
            .Cells(i, 2).Value = adoRS!Name
            .Cells(i, 3).Value = adoRS!age
        End With
        i = i + 1
        adoRS.MoveNext
    Loop

ここではID、Name、ageの項目をデータベースで検索、その値をA1セルから順番に書き込んでいます。adoRS.MoveNextはデータベース内の次の項目へと移るためのものです。これを書いておかないと延々とレコードセットの最初の行のみ検索し続けます。

次の部分

 adoCON.CommitTrans

これはトランザクションを終了するためのものです。

次の部分

adoRS.Close
Set adoRS = Nothing
adoCON.Close
Set adoCON = Nothing

これはレコードセットとコネクション(Connectionオブジェクト)を閉じています。なお、SQLのDELETE文などの即時更新モードでレコード編集しているときは、レコードセットを閉じることができません。Close メソッドを実行すると、エラーが発生します。

参考文献

Access VBA Tips+α 「Openメソッド」2015年10月25日閲覧。
Access VBA Tips+α 「Closeメソッド」2015年10月25日閲覧。
Microsoft Access Club 「SQLの実行方法 - ADOのExcuteメソッド : SQL入門講座」2015年10月25日閲覧。
Infifth「ADOを使ってExcelからAccessデータを利用してみよう」2015年10月25日閲覧。