【VBA/EXCEL】EXCELでSQLエディタの実装(SELECT命令編)
はじめに
SQLエディタの実装(SELECT命令編)
- VB系環境では、SQLはADO(ActiveX Data Objects)を使用します。
- 「ツール」→「参照設定」からMicrosoft ActiveX Data Objects X.X Libraryを追加する必要があります。 X.Xは2.7などバージョンになるので、環境に合わせて選択します。
- これにより、使用できるデータベースは
今回は、SELECT命令のみ実装していきます。
実装
※本記事では、SQLインジェクション等のセキュリティ対策は考慮していません。
まず、プロバイダを設定します。
本記事の範囲ではモジュールを分ける必要は特にないですが、今後の拡張を考慮して、
今回はモジュール名:Comを作成し、ここに記述します。
'--DB接続 Public Const Provider As String = "MSDASQL" Public ConnectionString As String
次に、モジュール名:Initを作成し、DB接続設定を進めます。
今回はEXCELの同Book内のシートをデータベースとして運用していきます。
'--初期処理 Sub initDB() Com.File_Name = ThisWorkbook.FullName Com.ConnectionString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" & "DBQ=" & Com.File_Name & "; ReadOnly=True;" End Sub
テスト用SQLを実行する処理は以下のとおりです。
SQLの記述にはシート名:SQL、実行結果の出力先にはシート名:resultとしています。
主処理部はモジュール名:SqlBrowserに作成し、以下のサブプロを記述します。
Sub SqlBrowser() Dim thisSheet As String thisSheet = "SQL" Dim outSheet As String outSheet = "result" Dim row As Long Dim col As Long row = 1 col = 1 '--一覧クリア(とりあえず空欄が10000行分見つかるまでクリアしていく) Dim i As Long i = 0 Do While i <= 10000 If Worksheets(outSheet).Cells(row + i, col).Value = "" Then i = i + 1 End If Worksheets(outSheet).Rows(row + i).ClearContents '行クリア Loop '--DBオブジェクト作成 Call init.initDB Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Set cn = New ADODB.Connection Set rs = New ADODB.Recordset Dim sql As String '--SQL文を格納 sql = Worksheets(thisSheet).Cells(1, 2).Value '--SQL実行 Call Sql_select.Sql_select(cn, rs, sql) '--SQLの結果を出力 Dim fld As ADODB.Field Dim j As Long j = 0 '--列名表示 For Each fld In rs.Fields If IsNull(fld.Name) Then Worksheets(outSheet).Cells(row, col + j).Value = "null" Else Worksheets(outSheet).Cells(row, col + j).Value = fld.Name End If j = j + 1 Next fld i = 1 j = 0 '--レコード出力 Do Until rs.EOF Dim f As Long For f = 0 To (rs.Fields.Count - 1) If IsNull(rs.Fields(f)) Then Worksheets(outSheet).Cells(row + i, col + f).Value = "" Else Worksheets(outSheet).Cells(row + i, col + f).Value = rs.Fields(f) End If Next f i = i + 1 rs.MoveNext Loop rs.Close cn.Close Set rs = Nothing Set cn = Nothing End Sub
主処理部からSQL実行部を呼び出します。
モジュール名:Sql_selectを作成し、以下のサブプロを記述します。
Sub Sql_select(cn As ADODB.Connection, _ rs As ADODB.Recordset, _ sql As String) cn.Provider = Com.Provider cn.ConnectionString = Com.ConnectionString cn.Open rs.Open sql, cn, adOpenStatic End Sub
実行結果
テスト用のテーブルは以下のシート名:tblTestを作成し、内容は以下の通り。
また、SQLエディタはシート名:SQLを作成し、以下の通り。
今回テスト用に実行するSQLは以下の通り。
select * from [tblTest$] where id >= 200
実行ボタンを押すと、シート名:resultに列名付きで出力します。
この例では、idが200以上のレコードを抽出し出力されているはずです。
日付データとかの扱いや表示が課題かなあ...
おわり
- 今回はSELECT命令のみ実装しました。
- INSERTやUPDATE、DELETEなども使えるようにしていく予定です。
- あとSQLインジェクション等のセキュリティ対策は考慮していません。