ssCAROのブログ

色んなとこで見つけたプログラムのメモ置き場っぽい

SQLiteをExcel(VBA)でODBCなしで使う

CSVで保存されたデータを集計して帳票として表示したい。
CSVファイルが大量にあったのでVBAで書くよりDBの方が便利かな~と思ったので無料のSQLite3を使用した。

SQLiteVBAで使うためにODBCのインストールが必要みたいだけどインストールしたくなかったので調べたら次の情報を見つけた。

SQLite for Excel
http://sqliteforexcel.codeplex.com/
https://github.com/govert/SQLiteForExcel
・SQLiteForExcel-1.0.zip

SQLiteのDLL版をVBAで使用するための、DLL(ラッパー)を使う。
zipを展開して次のDLLを使用する。
\SQLiteForExcel-1.0\Distribution\SQLite3_StdCall.dll

SQLiteの本体(DLL版)をダウンロードする。
http://www.sqlite.org/
sqlite-dll-win32-x86-3220000.zip

SQLite3_StdCall.dll と同じ場所に sqlite3.dll を置く。

Excelファイル(xls)もdllと同じ場所に置く、なのでフォルダは次のようになる。

  • Sample.xls
  • SQLite3_StdCall.dll
  • sqlite3.dll

ExcelVBAを作る
\SQLiteForExcel-1.0\Source\SQLite3VBAModules\Sqlite3.bas をインポートする。

エラー処理は一切なしです。

Dim ret As Long
Dim i As Long
Dim rowCount As Long
Dim colCount As Long
Dim colType As Long
Dim sql As String
Dim dbPath As String
Dim dbHandle As Long
Dim stmtHandle As Long
Dim getDatas() As Variant

'DB、テーブルは既に作成済みとします。
dbPath = ThisWorkbook.Path & "\sample.sqlite3"

'<SELECT>
sql = "SELECT * FROM SAMPLE"

ret = SQLite3Open(dbPath, dbHandle)

ret = SQLite3PrepareV2(dbHandle, sql, stmtHandle)

ret = SQLite3Step(stmtHandle)
rowCount = 0
'RecordsetオブジェクトのGetRowsメソッドの取得と同じ
'getDatas = ***.GetRows()
Do While ret <> SQLITE_DONE
    If rowCount = 0 Then
        colCount = SQLite3ColumnCount(stmtHandle)
        ReDim getDatas(colCount - 1, rowCount)
    Else
        ReDim Preserve getDatas(colCount - 1, rowCount)
    End If
    For i = 0 To colCount - 1
        colType = SQLite3ColumnType(stmtHandle, i)
        getDatas(i, rowCount) = ColumnValue(stmtHandle, i, colType)
    Next
    ret = SQLite3Step(stmtHandle)
    rowCount = rowCount + 1
Loop

ret = SQLite3Finalize(stmtHandle)

ret = SQLite3Close(dbHandle)

'<INSERT/UPDATE>
sql = "INSERT INTO SAMPLE VALUES('1', 'ABCD', '9999')"

ret = SQLite3Open(dbPath, dbHandle)

ret = SQLite3PrepareV2(dbHandle, sql, stmtHandle)
If ret <> SQLITE_DONE Then
    Debug.Print "SQL error: " & SQLite3ErrMsg(dbHandle)
End If

ret = SQLite3Step(stmtHandle)

ret = SQLite3Finalize(stmtHandle)

ret = SQLite3Close(dbHandle)

'--------------------
'Sqlite3Demo.basより
Private Function ColumnValue(ByVal stmtHandle As Long, ByVal ZeroBasedColIndex As Long, ByVal SQLiteType As Long) As Variant
    Select Case SQLiteType
        Case SQLITE_INTEGER:
            ColumnValue = SQLite3ColumnInt32(stmtHandle, ZeroBasedColIndex)
        Case SQLITE_FLOAT:
            ColumnValue = SQLite3ColumnDouble(stmtHandle, ZeroBasedColIndex)
        Case SQLITE_TEXT:
            ColumnValue = SQLite3ColumnText(stmtHandle, ZeroBasedColIndex)
        Case SQLITE_BLOB:
            ColumnValue = SQLite3ColumnText(stmtHandle, ZeroBasedColIndex)
        Case SQLITE_NULL:
            ColumnValue = Null
    End Select
End Function