Excel VBA Accessのデータを取得

ExcelのVBAからAccessへ接続しデータを取得するコードのサンプル。接続方法はADOを利用する。接続する側にはAccessを入れる必要はないので管理者の端末にだけAccessがインストールされていればよい。

ExcelのVBAの参照設定の追加でVBE(VBAの編集画面)で、ツール→参照

ここで、
Microsoft ActiveX Data Objects 2.X Library
または
Microsoft ActiveX Data Objects 6.1 Library
を選択しておく。

標準モジュールにコードをGetData関数、GetHaiban関数、ExecuteUpdInsDelSQL関数を作成しておけば、どこでも利用できるようになる。一か所でまとめておけば何かあった時にも対応しやすい。

コードの例)

Private Const DB_FILEPATH = "testdb.accdb"
'データ取得サンプル
Public Sub getdatasanm()
    Dim str As String
    Dim rs As ADODB.Recordset
    str = " SELECT * FROM T_サンプル"
    If GetData(str, rs) Then
        Do Until rs.EOF
            MsgBox (rs!名前)
            rs.MoveNext
        Loop
        
        MsgBox (GetHaiban)
    
        str = " UPDATE T_サンプル SET 住所 = '日本' "
        ExecuteUpdInsDelSQL (str)
    End If
    
End Sub
'----------------------------------------------------------------------------------------
'切断型データベースによるデータ取得
' 引数1:実行するSQL
' 引数2:検索結果を格納するRecordset(参照渡し)
'----------------------------------------------------------------------------------------
Public Function GetData(ByVal strSQL As String, ByRef rdSet As ADODB.Recordset) As Boolean
    Dim myCon As New ADODB.Connection
    Dim myRecordSet As New ADODB.Recordset
    Dim strConnectionString As String
    Dim rdReturn As ADODB.Recordset
On Error GoTo CatchError
    strConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DB_FILEPATH
    myCon.ConnectionString = strConnectionString
    myCon.Open
    myRecordSet.CursorLocation = adUseClient
    '参照のみなので、読み取り専用(adLockReadOnly)で開く
    '更新の場合は、レコード単位排他ロック(adLockPessimistic)を指定
    myRecordSet.Open strSQL, myCon, adOpenDynamic, adLockReadOnly
    
    'データの取得が終わったらすぐに接続を切る。この時点でmyRecordSetはAccessとは切り離されるので、自由に利用できる
    '.NETのDataTableのイメージでよい
    Set myRecordSet.ActiveConnection = Nothing
    myCon.Close
    Set myCon = Nothing
    If myRecordSet.EOF Then
        GetData = False
        Exit Function
    Else
        GetData = True
        '列数のカウント
        Dim i As Long
        Set rdReturn = New ADODB.Recordset
        '戻り値のRecordSetを定義
        '  切断型レコードセットを利用しているのでそのままSetすれば呼び出し元でも利用できると思われるが、
        '  念のために別のレコードセットを定義。データ量によっては速度が遅く感じるかもしれないのでその際には修正検討。
        For i = 0 To myRecordSet.Fields.Count - 1
            rdReturn.Fields.Append myRecordSet.Fields(i).Name, myRecordSet.Fields(i).Type, myRecordSet.Fields(i).DefinedSize, adFldIsNullable
        Next
        rdReturn.Open
        Do Until myRecordSet.EOF
            With rdReturn
                .AddNew
                For i = 0 To myRecordSet.Fields.Count - 1
                    .Fields(i) = myRecordSet.Fields(i)
                Next
                .Update
            End With
            myRecordSet.MoveNext
        Loop
    End If
    rdReturn.MoveFirst
    Set rdSet = rdReturn
    '参照渡しなので下記のようにCloseしてしまうと呼び出し元で利用できない
    'rdReturn.Close
    myRecordSet.Close
    Set myRecordSet = Nothing
    Exit Function
CatchError:
    MsgBox "エラーが発生" & vbCrLf & Err.Number & vbCrLf & Err.Description, vbExclamation
End Function
'----------------------------------------------------------------------------------------
'配番テーブルを利用
'----------------------------------------------------------------------------------------
Public Function GetHaiban() As Long
    Dim myCon As New ADODB.Connection
    Dim myRecordSet As New ADODB.Recordset
    Dim strConnectionString As String
    Dim strSQL As String
    On Error GoTo CatchError
    strSQL = " SELECT * FROM T_配番 WHERE ID = 1 "
    strConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DB_FILEPATH
    myCon.ConnectionString = strConnectionString
    myCon.Open
    myCon.BeginTrans
    myRecordSet.Open strSQL, myCon, adOpenDynamic
    GetHaiban = myRecordSet!配番No
    Dim strUpdSQL As String
    strUpdSQL = " UPDATE T_配番 SET 配番No = " & myRecordSet!配番No + 1 & " WHERE ID = 1 "
    myCon.Execute strUpdSQL
    myCon.CommitTrans
    myRecordSet.Close
    Set myRecordSet = Nothing
    myCon.Close
    Set myCon = Nothing
    Exit Function
CatchError:
    MsgBox "エラーが発生" & vbCrLf & Err.Number & vbCrLf & Err.Description, vbExclamation
End Function
'----------------------------------------------------------------------------------------
'データ更新SQLを実行
' 引数1:実行するSQL(複数のSQLを同一トランザクションで実行したい場合は「;」で区切る
' 引数2:(オプション)複数のSQLを同一トランザクションで実行する場合は、Trueを指定
'----------------------------------------------------------------------------------------
Public Sub ExecuteUpdInsDelSQL(ByVal strSQL As String, Optional ByVal blnIsSomeSQL As Boolean = False)
    Dim myCon As New ADODB.Connection
    Dim myRecordSet As New ADODB.Recordset
    Dim strConnectionString As String
    On Error GoTo CatchError
    strConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DB_FILEPATH
    myCon.ConnectionString = strConnectionString
    myCon.Open
    myCon.BeginTrans
    If blnIsSomeSQL Then
        Dim sql() As String
        sql = Split(strSQL, ";")
        For i = 0 To UBound(sql)
            If Trim(sql(i)) <> "" Then
                myRecordSet.Open sql(i), myCon, adOpenDynamic, adLockPessimistic
            End If
        Next
    Else
        myRecordSet.Open strSQL, myCon, adOpenDynamic, adLockPessimistic
    End If
    myCon.CommitTrans
    Set myRecordSet = Nothing
    myCon.Close
    Set myCon = Nothing
    Exit Sub
CatchError:
    MsgBox "エラーが発生" & vbCrLf & Err.Number & vbCrLf & Err.Description, vbExclamation
End Sub
Public Function NullSpace(ByVal obj) As Variant
    If IsNull(obj) Then
        NullSpace = ""
    Else
        NullSpace = obj
    End If
End Function
Public Function NullZero(ByVal obj) As Variant
    If IsNull(obj) Then
        NullZero = 0
    Else
        NullZero = obj
    End If
End Function


PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...