ExcelからODBCなしでSQLiteを操作する(実践編１）

前回の[記事](http://qiita.com/hisayuki/items/9b42624790ba74a2fb35)からの続きです。
なので、環境等は前回の記事を参照してください。

また、今回はサンプルExcelではないので__Sqlite3_64.bas__を読み込んでます。
登場するモジュールは__Sqlite3_64.bas__にあるものです。

今回はDBの作成、テーブルの作成までやっていきます。


## DLL読み込み
まずはSQLite.dllの読み込みです。
標準モジュールに新しいモジュールを作り、Executeと名前を付けました。

### SQLite3Initialize()
```VBScript:Execute
Public Sub Execute()
    Dim InitReturn As Long  'SQLiteDLL
    
    #If Win64 Then
        Debug.Print "Excel is 64bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize(ThisWorkbook.Path + "\x64")
        'データベースハンドラ定義
        Dim myDbHandle As LongPtr
    #Else
        Debug.Print "Excel is 32bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize
        'データベースハンドラ定義
        Dim myDbHandle As Long
    #End If
    'SQLiteDLL読み込み成否
    If InitReturn <> SQLITE_INIT_OK Then
        Debug.Print "Error Initializing SQLite. Error: " & Err.LastDllError
        Exit Sub
    End If
End Sub
```
SQLite3Initializeモジュールが読み込みを行います。

```VBScript:Sqlite3.SQLite3Initialize
Public Function SQLite3Initialize(Optional ByVal libDir As String) As Long
    ' A nice option here is to call SetDllDirectory, but that API is only available since Windows XP SP1.
    If libDir = "" Then libDir = ThisWorkbook.Path
    If Right(libDir, 1) <> "\" Then libDir = libDir & "\"
    
    If hSQLiteLibrary = 0 Then
        hSQLiteLibrary = LoadLibrary(libDir + "SQLite3.dll")
        If hSQLiteLibrary = 0 Then
            Debug.Print "SQLite3Initialize Error Loading " + libDir + "SQLite3.dll:", Err.LastDllError
            SQLite3Initialize = SQLITE_INIT_ERROR
            Exit Function
        End If
    End If
        
    #If Win64 Then
    #Else
    If hSQLiteStdCallLibrary = 0 Then
        hSQLiteStdCallLibrary = LoadLibrary(libDir + "SQLite3_StdCall.dll")
        If hSQLiteStdCallLibrary = 0 Then
            Debug.Print "SQLite3Initialize Error Loading " + libDir + "SQLite3_StdCall.dll:", Err.LastDllError
            SQLite3Initialize = SQLITE_INIT_ERROR
            Exit Function
        End If
    End If
    #End If
    SQLite3Initialize = SQLITE_INIT_OK
End Function
```
SQLite3Initializeは引数を渡さなければ、デフォルトで起動ブックと同階層のdllを読み込みます。
同時に同階層のSQLite3_StdCall.dllも読み込んでいるので、そのまま使う場合は
SQLite.dllとSQLite3_StdCall.dllは必ず同じ階層に配置する必要があります。

## DB作成
DBファイルについては、SQLite3Openモジュールで自動で作ることが出来ます。
ファイルを開いた状態になるので、SQLite3Closeで最後は閉じます。

#### SQLite3Open()
```VBScript:Sqlite3.SQLite3Open
#If Win64 Then
Public Function SQLite3Open(ByVal fileName As String, ByRef dbHandle As LongPtr) As Long
#Else
Public Function SQLite3Open(ByVal fileName As String, ByRef dbHandle As Long) As Long
#End If
    SQLite3Open = sqlite3_open16(StrPtr(fileName), dbHandle)
End Function
```
#### SQLite3Close()
```VBScript:Sqlite3.SQLite3Close
#If Win64 Then
Public Function SQLite3Close(ByVal dbHandle As LongPtr) As Long
#Else
Public Function SQLite3Close(ByVal dbHandle As Long) As Long
#End If
    SQLite3Close = sqlite3_close(dbHandle)
End Function
```
SQLite3Openモジュールに引数でファイル名を渡したタイミングでDBファイルは作成されます。


```VBScript:Execute
Option Explicit

Public Const DB_FILE_DIR As String = "E:\sqlite\db"
Public Const DB_FILE_NAME As String = "sampe.db"

Public Sub Execute()

    Dim InitReturn As Long  'SQLiteDLL
    Dim dbFile As String    'DBファイル
    Dim RetVal As Long      'DBData
    

    #If Win64 Then
        Debug.Print "Excel is 64bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize(ThisWorkbook.Path + "\x64")
        'データベースハンドラ定義
        Dim myDbHandle As LongPtr
    #Else
        Debug.Print "Excel is 32bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize
        'データベースハンドラ定義
        Dim myDbHandle As Long
    #End If
    
    'SQLiteDLL読み込み成否
    If InitReturn <> SQLITE_INIT_OK Then
        Debug.Print "Error Initializing SQLite. Error: " & Err.LastDllError
        Exit Sub
    End If
    
    'ファイル名取得
    dbFile = DB_FILE_DIR + "\" + DB_FILE_NAME
    
    'DBファイルOpen
    RetVal = SQLite3Open(dbFile, myDbHandle)
    Debug.Print "SQLite3Open returned " & RetVal
    Debug.Print myDbHandle
    
    
    'DBファイルClose
    RetVal = SQLite3Close(myDbHandle)
    Debug.Print "SQLite3Close returned " & RetVal

End Sub
```
実行すると以下のようにファイルが出来ます。
![image](https://qiita-image-store.s3.amazonaws.com/0/33165/3cd6e46b-6be6-0826-1a21-19e5f68cfe39.png)

## テーブル作成
テーブル作成も含め、SQLステートメントの発行にはSQLite3PrepareV2モジュールを使います。
今回は以下のSQLを発行します。
```sql:SQL
CREATE TABLE MyBigTable (
    TheId INTEGER, 
    TheDate REAL, 
    TheText TEXT, 
    TheValue REAL)
```
### SQLite3PrepareV2()
```VBScript:Sqlite3.SQLite3PrepareV2
#If Win64 Then
Public Function SQLite3PrepareV2(ByVal dbHandle As LongPtr, ByVal sql As String, ByRef stmtHandle As LongPtr) As Long
#Else
Public Function SQLite3PrepareV2(ByVal dbHandle As Long, ByVal sql As String, ByRef stmtHandle As Long) As Long
#End If
    ' Only the first statement (up to ';') is prepared. Currently we don't retrieve the 'tail' pointer.
    SQLite3PrepareV2 = sqlite3_prepare16_v2(dbHandle, StrPtr(sql), Len(sql) * 2, stmtHandle, 0)
End Function
```
その後、実行、ステートメントの削除と続きます。
### SQLite3Step()
```VBScript:Sqlite3.SQLite3Step
#If Win64 Then
Public Function SQLite3Step(ByVal stmtHandle As LongPtr) As Long
#Else
Public Function SQLite3Step(ByVal stmtHandle As Long) As Long
#End If
    SQLite3Step = sqlite3_step(stmtHandle)
End Function

```
### SQLite3Finalize()
```VBScript:Sqlite3.SQLite3Finalize
#If Win64 Then
Public Function SQLite3Finalize(ByVal stmtHandle As LongPtr) As Long
#Else
Public Function SQLite3Finalize(ByVal stmtHandle As Long) As Long
#End If
    SQLite3Finalize = sqlite3_finalize(stmtHandle)
End Function
```

Executeモジュールに一連の動作を組み込んでいきます。
データベースハンドラ定義のタイミングでステートメントハンドラ定義も行います。

```VBScript:Execute
Option Explicit

Public Const DB_FILE_DIR As String = "E:\sqlite\db"
Public Const DB_FILE_NAME As String = "sampe.db"

Public Sub Execute()

    Dim InitReturn As Long  'SQLiteDLL
    Dim dbFile As String    'DBファイル
    Dim RetVal As Long      'DBData
    

    #If Win64 Then
        Debug.Print "Excel is 64bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize(ThisWorkbook.Path + "\x64")
        'データベースハンドラ定義
        Dim myDbHandle As LongPtr
        'ステートメントハンドラ定義
        Dim myStmtHandle As LongPtr
    #Else
        Debug.Print "Excel is 32bit"
        'SQLiteDLL読み込み
        InitReturn = SQLite3Initialize
        'データベースハンドラ定義
        Dim myDbHandle As Long
        'ステートメントハンドラ定義
        Dim myStmtHandle As Long
    #End If
    
    'SQLiteDLL読み込み成否
    If InitReturn <> SQLITE_INIT_OK Then
        Debug.Print "Error Initializing SQLite. Error: " & Err.LastDllError
        Exit Sub
    End If
    
    'ファイル名取得
    dbFile = DB_FILE_DIR + "\" + DB_FILE_NAME
    
    'DBファイルOpen
    RetVal = SQLite3Open(dbFile, myDbHandle)
    Debug.Print "SQLite3Open returned " & RetVal
    Debug.Print myDbHandle
    
     'SQL statement作成
    RetVal = SQLite3PrepareV2(myDbHandle, "CREATE TABLE MyBigTable (TheId INTEGER, TheDate REAL, TheText TEXT, TheValue REAL)", myStmtHandle)
    Debug.Print "SQLite3PrepareV2 returned " & RetVal
    
    'SQL実行
    RetVal = SQLite3Step(myStmtHandle)
    Debug.Print "SQLite3Step returned " & RetVal
    
    'statement 削除
    RetVal = SQLite3Finalize(myStmtHandle)
    Debug.Print "SQLite3Finalize returned " & RetVal
    
    'DBファイルClose
    RetVal = SQLite3Close(myDbHandle)
    Debug.Print "SQLite3Close returned " & RetVal

End Sub
```  

実行後のDBをSQLiteBrowser等で見てみると以下のようになっています。
![image](https://qiita-image-store.s3.amazonaws.com/0/33165/e7bf9e52-9849-8579-dbfe-067cd7fa7407.png)

## まとめ
設定編に引き続き実践編１を書いてみました。
今回はテーブル作成まで書きましたので、次回データのINSERTや
SELECTを書いていきたいと思います！