2015年10月25日日曜日

VBAにおけるSQLの基礎

VBAとデータベース レコードセットについてVBA:データベースにアクセスする(解説)でも説明しましたが、こういうデータベースの検索や編集を行うにはSQL文を使用します。

こんなふうにSQL文を書きましたね。
strSQL = "SELECT テーブルの名前.* FROM テーブルの名前 ORDER BY ID;"
これはデータを検索し、選択するSELECT文というものです。選択されたデータはのちに

    i = 1
    Do Until adoRS.EOF
        With Worksheets("Sheet1")
            .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
'(実行するときにテーブル上に存在していない項目(フィールド名)を指定しているとエラーになるので注意)


こんな感じでエクセルシート上に書き込まれます(これはコードの一部分です。そのままでは動きません。コード全体が見たい人はVBAとデータベース レコードセットについてなどを参照してください)。

ORDER BY IDというのはIDの順番に書き込めという意味です。仮にテーブル上に「Date(日付)」という項目(フィールド名)があり、日付順に並べたいのであれば、ORDER BY Date と書きます。

なお、昇順に並べたいのであれば
ORDER BY ID ASC
と書きます。
降順に並べたいのであれば
ORDER BY ID DESC
と書きます。

特定のデータを検索したい場合はWHEREを使います。

strSQL = "SELECT テーブルの名前.* FROM テーブルの名前 WHERE ID = 2;"

こうするとIDが2の人物だけが選択されます。あとはさっきと同じ方法でシートにそのIDを持つデータの情報を書き込むことができます。

With Worksheets("Sheet1")
            .Cells(1, 1).Value = adoRS!ID
            .Cells(1, 2).Value = adoRS!Name
            .Cells(1, 3).Value = adoRS!age
End With
(さっきと同じ方法)

データをデリートするDELETEを用いたSQL文は以下のように記述します。
strSQL = "DELETE FROM テーブル名 WHERE ID = 1;"
これはIDが1のデータをデータベースから削除します。
なお、これはおそらく即時更新モードで実行されるから?なのかよくわからないですが、レコードセットを閉じようとするとエラーになります。よって、次のようにレコードセットを閉じずに記述します。

Sub Test()
    Dim adoCON      As New ADODB.Connection
    Dim adoRS       As New ADODB.Recordset
    Dim strSQL      As String
    Dim odbdDB      As Variant

 
    odbdDB = ActiveWorkbook.Path & "\データベース名.accdb"
    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                        & "Data Source=" & odbdDB & ""
    adoCON.Open
 
    strSQL = "DELETE FROM テーブル名 WHERE ID = 1;"
    adoRS.CursorLocation = adUseClient
    adoRS.Open strSQL, adoCON, adOpenDynamic
 
    adoCON.Close
    Set adoCON = Nothing
End Sub

つぎに新規レコードを挿入するSQL文です。次のように書きます。
strSQL = "INSERT INTO テーブル名 (フィールド名) VALUES (""Food"")"
これは指定のテーブルのフィールドに「Food」という新規レコードを挿入するSQL文です。ちなみに「フィールド」というのは「ID」とか「日付」とかデータの一番上にある題名みたいなやつです。

なお、これはおそらく即時更新モードで実行されるから?なのかよくわからないですが、レコードセットを閉じようとするとエラーになります。よって、次のようにレコードセットを閉じずに記述します。

Sub Test()
    Dim adoCON      As New ADODB.Connection
    Dim adoRS       As New ADODB.Recordset
    Dim strSQL      As String
    Dim odbdDB      As Variant

 
    odbdDB = ActiveWorkbook.Path & "\データベース名.accdb"
    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                        & "Data Source=" & odbdDB & ""
    adoCON.Open
 
    strSQL = "INSERT INTO テーブル名 (フィールド名) VALUES (""Food"");"
    adoRS.CursorLocation = adUseClient
    adoRS.Open strSQL, adoCON, adOpenDynamic

    adoCON.Close
    Set adoCON = Nothing
End Sub

次にUPDATEです。これはすでにデータベースにある値を変更するものです。
strSQL = "UPDATE テーブル名 SET フィールド名 = ""aaa"" WHERE ID = 1;"
これは「テーブル名」というテーブルの「フィールド名」というフィールドにあるIDが1のデータのフィールド名を「aaa」に変更するものです。なお、WHEREを指定せずに実行すると

strSQL = "UPDATE テーブル名 SET フィールド名 = ""aaa"";"

指定されたフィールドがすべて「aaa」へと変更されます。この変更はもとに戻せないので、実際に実行する前にMsgBoxで確認を取ったほうがよいでしょう。これはデータロストにもつながりますので、取り扱いは慎重に

なお、これはおそらく即時更新モードで実行されるから?なのかよくわからないですが、レコードセットを閉じようとするとエラーになります。よって、次のようにレコードセットを閉じずに記述します。

Sub Test()
    Dim adoCON      As New ADODB.Connection
    Dim adoRS       As New ADODB.Recordset
    Dim strSQL      As String
    Dim odbdDB      As Variant

 
    odbdDB = ActiveWorkbook.Path & "\データベース名.accdb"
    adoCON.ConnectionString = "provider=Microsoft.ACE.OLEDB.12.0;" _
                        & "Data Source=" & odbdDB & ""
    adoCON.Open
 
    strSQL = "UPDATE テーブル名 SET フィールド名 = ""aaa"" WHERE ID = 1;"
    adoRS.CursorLocation = adUseClient

    mbResult = MsgBox("本当に実行する?", vbYesNo)
    Select Case mbResult
    Case vbYes
    Case vbNo
        Exit Sub
    End Select
    adoRS.Open strSQL, adoCON, adOpenDynamic

    adoCON.Close
    Set adoCON = Nothing
End Sub

変数を使いたい場合

SQL文の中に変数を使いたい場合は次のように書いてください。

変数が数値の場合
strSQL = "SELECT テーブル名.* FROM テーブル名 WHERE フィールド名 = " & TextBox1.Value & ";"

変数がString型の場合
strSQL = "SELECT テーブル名.* FROM テーブル名 WHERE フィールド名 LIKE '" & TextBox1.Value & "';"