目次
バッチファイルとGetObjFmAccdb で Access のクエリをSQL抽出し、VBAスニペットを生成しよう
この記事では、特定のフォルダ内にある「*.accdb」形式のAccessプロジェクトファイルに含まれるクエリを抽出する方法を紹介します。
具体的には、
- GetObjFmAccdb.bat
- GetObjFmAccdb.exe
というバッチファイルとユーティリティプログラムを使用して、クエリをSQLファイルとして抽出し、さらにここからVBAのスニペット(注1)を生成します。
これらのツールを用いて*.accdb ファイル中に含まれるクエリをテキスト形式のSQLファイルやVBAのスニペットとして保存しておくと、Accessファイル内のクエリをSubversion のクライアント TortoiseSVN による差分管理ができるようになります。
また将来的にあなたの Access ツールをアップサイジングし、SQL Server をバックエンドとしたユーザー向けのフロントエンドとしてリファクタリングする際 、このVBAのスニペットの再利用があなたの生産性を爆上げすることは確実です。
(注1) スニペット(英語: snippet)は、「断片」という意味で、再利用可能なソースコード、またはテキストの小さな領域を表すプログラミング用語です。
ツール開発の背景
それではまずこのツールの利用方法のイメージを理解しやすいよう、以下の記事
に登場する
- 作成T2040日付女性入院者数男性入院者数_xlsx.accdb
というプロジェクトファイルに対し次の記事
で紹介した方法でマクロをVBAに変換した次のプロジェクトファイルをサンプルとして使用してみましょう。
このプロジェクトファイルの中では、もともとautoexec マクロに定義されていたマクロがVBAに変換され、 main マクロから呼び出されているModule1 モジュール内のMain()関数として既に展開されています。
これでリファクタリングの際、アクションマクロとVBAの中をいったり来たりしなくて済むのでツール全体の動作は直観的に理解できるようになったわけですが、ここまでくると続いて次のような願望も湧き上がってきますね。
ところで DoCmd.OpenQuery で実行しているクエリが実際に何をしてるかって、結局それぞれのクエリをマクロのデザインビューで見てみないとわかんないじゃないですか。
これってなんかいい方法ないんですか?
そうですね。
そうやってクエリを初心者にも簡単なグラフィカルなデザインピューで視覚的に作れるのがAccessの長所でもあるわけなんですが
みなみさんのスキルレベルが爆上がりして Subversion 、ToutoiseSVNを使いこなせるようになると当然そうした要望も出てきますよね。
今回ご紹介するツールはその願望を解決するために開発したんですよ~。
利用方法
それではこのツールの利用方法を具体的に紹介していきましょう。
まず先ほどご紹介したバッチファイル、ユーティリティプログラムを
- %USERPROFILE%\Tools\bat\GetObjFmAccdb.bat
- %USERPROFILE%\Tools\exe\GetObjFmAccdb.exe
配下に配置し
またこの GetObjFmAccdb.bat のコピーを以下のようにターゲットファイル
- 作成T2040日付女性入院者数男性入院者数_xlsx.accdb
と同じフォルダに格納します。
GetObjFmAccdb.bat のコピーをターゲットとなるVBAコードを含む*.accdbと同じフォルダ配下に配置するのは、このバッチファイルのダブルクリックでファイル名を指定せずに *.sql、*.bas ファイルを抽出できるようにするためです。
ちなみにこのExportVBAcodeFromAccdb.bat は下記の記事でご紹介したもので、今回ご紹介する GetObjFmAccdb.bat が ExportVBAcodeFromAccdb.bat のVBAコード抽出機能を包含しているためここでは利用しません。
この状態で GetObjFmAccdb.bat をダブルクリックして起動するとコマンドライン上に以下のような実行履歴が残り
C:\Home\0385\accdb4>GetObjFmAccdb.bat
C:\Home\0385\accdb4>rem @echo off
C:\Home\0385\accdb4>setlocal
C:\Home\0385\accdb4>C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /h
GetObjFmAccdb.exe[評価版] : ver 1.230 (2023/10/07 06:15:48)
使用方法:
>GetObjFmAccdb /h ... このヘルプを出力します
>GetObjFmAccdb /v sample.accdb ... sample.accdb ファイルからVBAコードを抽出し、モジュール名.basを出力します
>GetObjFmAccdb /s sample.accdb ... sample.accdb ファイル内のクエリをSQLとして抽出し、クエリ名.sqlを出力します
>GetObjFmAccdb /c sample.sql ... sample.sql ファイルをVBA変換し、sample.basを出力します
C:\Home\0385\accdb4>taskkill /f /im msaccess.exe 1>nul 2>&1
C:\Home\0385\accdb4>for %f in (*.accdb) do (
"%~ff" /decompile /x exit
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /v "%~ff"
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /s "%~ff"
)
C:\Home\0385\accdb4>(
"C:\Home\0385\accdb4\作成_T2040_日付_女性入院者数_男性入院者数_xlsx.accdb" /decompile /x exit
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /v "C:\Home\0385\accdb4\作成_T2040_日付_女性入院者数_男性入院者数_xlsx.accdb"
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /s "C:\Home\0385\accdb4\作成_T2040_日付_女性入院者数_男性入院者数_xlsx.accdb"
)
C:\Home\0385\accdb4>for %f in (*.sql) do (
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /c "%~ff"
rem del "%~ff"
)
C:\Home\0385\accdb4>(
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /c "C:\Home\0385\accdb4\Q2000_作成_T2000_日付.sql"
rem del "C:\Home\0385\accdb4\Q2000_作成_T2000_日付.sql"
)
C:\Home\0385\accdb4>(
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /c "C:\Home\0385\accdb4\Q2020_作成_T2020_日付_男性_入院者数.sql"
rem del "C:\Home\0385\accdb4\Q2020_作成_T2020_日付_男性_入院者数.sql"
)
C:\Home\0385\accdb4>(
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /c "C:\Home\0385\accdb4\Q2030_作成_T2030_日付_女性_入院者数.sql"
rem del "C:\Home\0385\accdb4\Q2030_作成_T2030_日付_女性_入院者数.sql"
)
C:\Home\0385\accdb4>(
C:\Users\shirakabado\Tools\exe\GetObjFmAccdb.exe /c "C:\Home\0385\accdb4\Q2040_作成_T2040_日付_女性入院者数_男性入院者数.sql"
rem del "C:\Home\0385\accdb4\Q2040_作成_T2040_日付_女性入院者数_男性入院者数.sql"
)
C:\Home\0385\accdb4>pause
続行するには何かキーを押してください . . .
そして結果的に以下のように赤枠で囲った *.bas、*.sql ファイルが自動作成されます。
Module 毎に抽出されたVBAコード
ここでModule 毎に抽出されたVBAコードは例えば以下のようなものになります。
Module Module1
Option Compare Database
Function Main()
Const C_SUCCESS As Integer = 0
Const C_FAILURE As Integer = 1
DoCmd.SetWarnings False
If (LinkExternalDbTable("Tools\accdb\作成_T0000_東京都コロナ発症状況_マスタ.accdb", "T0000_東京都コロナ発症状況_マスタ") = 0) Then
Else
Beep
MsgBox "Link に失敗しました", vbOKOnly, ""
Main = C_FAILURE
Exit Function
End If
DoCmd.SetWarnings False
DoCmd.OpenQuery "Q2000_作成_T2000_日付", acViewNormal, acEdit
DoCmd.OpenQuery "Q2020_作成_T2020_日付_男性_入院者数", acViewNormal, acEdit
DoCmd.OpenQuery "Q2030_作成_T2030_日付_女性_入院者数", acViewNormal, acEdit
DoCmd.OpenQuery "Q2040_作成_T2040_日付_女性入院者数_男性入院者数", acViewNormal, acEdit
Call ExportTableToBook("T2040_日付_女性入院者数_男性入院者数", "Tools_Data_Temp\xlsx\T2040_日付_女性入院者数_男性入院者数.xlsx")
DoCmd.Quit acSave
Main = C_SUCCESS
End Function
クエリから抽出されたSQL
次にクエリから抽出されたSQLは以下のようなものになります。このSQLはAccess内の同名のクエリをデザインモード(SQLビュー)で参照した際のテキストと同じものです。
SELECT T0000_東京都コロナ発症状況_マスタ.公表_年月日 AS 日付 INTO T2000_日付
FROM T0000_東京都コロナ発症状況_マスタ
GROUP BY T0000_東京都コロナ発症状況_マスタ.公表_年月日;
SQLから生成されたVBAスニペット
そしてこのSQLから生成されたVBAスニペットコードは以下のようなものになります。
Dim strSQL As String
strSQL = "SELECT T0000_東京都コロナ発症状況_マスタ.公表_年月日 AS 日付 INTO T2000_日付 " & _
"FROM T0000_東京都コロナ発症状況_マスタ " & _
"GROUP BY T0000_東京都コロナ発症状況_マスタ.公表_年月日;"
DoCmd.RunSQL strSQL
わぁ~これあると便利かも~
解決できること
これらのツールと Subversion クライアント TortoiseSVN を利用すると
- クエリを含む .accdb ファイルの クエリに修正をかける
- GetObjFmAccdb.bat を起動し、クエリのSQLテキスト、そのVBAスニペットを生成する
- TortoiseSVN で上記修正に対する差分を抽出する
- 上記の差分も含めた全てをTortoiseSVN を使ってリポジトリにコミットする
といった一連の作業によリ、VBAコードの差分管理に加えてクエリの差分管理もできるようになります。
そしてこのSubversion が Redmine と連携していれば、さらに問題(チケット)管理と修正したクエリの紐づけができるようになり、個人、チームでのクエリ開発の変更の可視化、維持管理に計り知れないメリットを提供します。
例えばここでサンプルとして紹介している
- 作成T2040日付女性入院者数男性入院者数_xlsx.accdb
内の Q200_作成_T2000_日付 クエリの選択項目に以下のように 患者_年代 というフィールドを追加後
この GetObjFmAccdb.bat を実行すると TortoiseSVNの機能により変更のあったファイルのアイコンが赤い!に変わります。
さらに、TortoiseSVN でQ2000_作成T2000日付.sql や Q2000_作成T2000日付.bas の差分比較すると以下のようにピンポイントで修正前後のSQL、VBAスニペットが見えるようになります。
凄くないですか?
読んでほしい方
- Access VBAを使った業務効率化に取り組まれている方
- Subversion を使った開発リソースの差分管理を実施中、もしくは検討されている方
- Access VBA、およびクエリの維持管理の継承性を考慮している方、または苦労されている方
GetObjFmAccdb.bat の紹介
保存場所
本記事ではこのバッチファイルを以下の記事も参考にしながら
- %USERPROFILE%\Tools\bat\GetObjFmAccdb.bat
に保存し、そのコピーをVBAコードを抽出したい .accdb ファイルが格納されているフォルダに保存します。%USERPROFILE% については必要に応じて以下の記事も参照ください。
詳細
このバッチファイル GetObjFmAccdb.bat は以下の記事で紹介している
ExportVBAcodeFromAccdb.bat の機能に加え、Accessプロジェクト(.accdbファイル)内の定義済のクエリ定義を SQL フォーマットのテキストとしてエクスポートし、さらにそのVBAスニペットを生成するためのものです。
rem @echo off
setlocal
%USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /h
taskkill /f /im msaccess.exe >nul 2>&1
for %%f in (*.accdb) do (
"%%~ff" /decompile /x exit
%USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /v "%%~ff"
%USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /s "%%~ff"
)
for %%f in (*.sql) do (
%USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /c "%%~ff"
rem del "%%~ff"
)
pause
endlocal
GetObjFmAccdb.batの簡単な説明
行番号 | 説明 |
---|---|
1 | このバッチファイルで echo コマンド を除いた以後の実行コマンドそのもの、あるいはその実行結果を以下のようにコマンドプロンプト上に表示しないように指定 |
2 | 一時的な環境変数を作成し、スクリプト内での変更を限定します。 |
4 | GetObjFmAccdb の評価版/有償版識別のためのヘルプ情報を出力します |
6 | 現在実行中の msaccess.exe という名前のプロセスを念のため強制終了します。エラーメッセージは表示せず、結果を無視します。 |
8 | 現在のフォルダ内のすべての .accdbファイルに対して12行までの処理を繰り返すためのループです。 |
9 | %%~ff で指定された現在処理中の.accdb データベースに対しVBAコードをデコンパイル(注1)します。”~”は指定されたパラメータから “” を取る修飾子です(注2)。 |
10 | %%~ff で指定された現在処理中の.accdb データベースをパラメータとして %USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /v つまりVBA抽出機能を呼び出します。 |
11 | %%~ffで指定された現在処理中の.accdb データベースをパラメータとして %USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /s つまりSQL抽出機能を呼び出します。 |
14 | 現在のフォルダ内のすべての .sql ファイルに対して17行までの処理を繰り返すためのループです。 |
15 | %%~ffで指定された現在処理中の.sql ファイルをパラメータとして %USERPROFILE%\Tools\exe\GetObjFmAccdb.exe /c つまりSQLのVBAスニペット生成機能を呼び出します。 |
16 | .bas ファイルの作成された .sql が冗長と考える利用者向けに必要に応じて .sql ファイルを削除する為のもので、削除したいときは rem を外し有効化します。 |
19 | GetObjFmAccdb の評価版/有償版識別のためのヘルプ情報を確実に参照できるようここで一旦ポーズします。必要に応じて削除してください。 |
20 | setlocalで作成した一時的な環境変数を破棄し、元の状態に戻します。 |
(注1) /decompile スイッチはAccess の起動スイッチの一つで、VBA抽出の前に既にコンパイル済のVBAコードを未コンパイル状態に戻します。
ここではこの /decompile スイッチを /x exit スイッチと一緒に利用し、以下の exit マクロを呼び出し Access を終了するところまでを一気に実行しています。
詳細については必要に応じて以下の記事も参照ください。
(注2) バッチファイルのパラメータの修飾子の使い方については必要に応じて以下の記事も参照ください。
GetObjFmAccdb.exe の紹介
保存場所
バッチファイルと同様に
- %USERPROFILE%\Tools\exe\GetObjFmAccdb.exe
に保存します。
入手方法
この GetObjFmAccdb.exeファイル はしらかば堂が開発したユーティリティプログラムで以下の2種類のインストーラを準備しており、インストーラを使って上記のフォルダに GetObjFmAccdb.exe として保存可能です。
まず無償の評価版でその動作、効果を体感して頂き、気に入って頂けた方は有償版の購入をご検討くださいね。
評価版 | 有償版 | ||
---|---|---|---|
説明 | インストーラ入手先 | ||
価格 | 無償 | 3,000円 | |
利用可能期間 | 1カ月 | 無制限 | |
機能 | ヘルプ(注2) | 〇 | 〇 |
.accdb からの .bas 抽出(注3) | 〇 | 〇 | |
.accdb からの .sql 抽出(注4) | 〇 | 〇 | |
.sql からの .bas 生成(注5) | 〇 | 〇 |
(注2) ヘルプ … この GetObjFmAccdb コマンドで利用可能なコマンドスイッチ、使い方を表示します。
(注3) .accdb からの .bas 抽出 … 例えば Sample.accdb の中に VBA コードを含むフォームモジュール、標準モジュール、クラスモジュールが定義されているとき、/v スイッチを使用してこれらのモジュールからVBAコードを モジュール名.bas として抽出します。
(注4) .accdb からの .sql 抽出 … 例えば Sample.accdb の中にクエリ定義が存在する場合、/q スイッチを使用してこれらのクエリをSQLテキスト クエリ名.sql として抽出します。
(注5) .sql からの .bas 生成 … /c スイッチを使って上記機能で抽出された クエリ名.sql を入力とした VBA スニペットコード クエリ名.bas を生成します。
起動スイッチ
Windows 10 のコマンドプロンプト配下でこの GetObjFmAccdb.exe のヘルプ機能を実行すると以下のようになります。
>GetObjFmAccdb /h
GetObjFmAccdb.exe : ver 1.230 (2023/10/07 06:15:48)
使用方法:
>GetObjFmAccdb /h ... このヘルプを出力します
>GetObjFmAccdb /v sample.accdb ... sample.accdb ファイルからVBAコードを抽出し、モジュール名.basを出力します
>GetObjFmAccdb /s sample.accdb ... sample.accdb ファイル内のクエリをSQLとして抽出し、クエリ名.sqlを出力します
>GetObjFmAccdb /c sample.sql ... sample.sql ファイルをVBA変換し、sample.basを出力します
>
まとめ
この記事では、特定のフォルダ内にある「*.accdb」形式のAccessプロジェクトファイルに含まれるクエリを抽出する方法を紹介しました。
具体的には、
- GetObjFmAccdb.bat
- GetObjFmAccdb.exe
というバッチファイルとユーティリティプログラムを使用して、クエリをSQLファイルとして取り出し、さらにそのSQLファイルからVBAのスニペット(注1)を生成する手順を説明しました。
これらのツールを用いて*.accdb ファイル中に含まれるクエリをテキスト形式のSQLファイルやVBAのスニペットとして保存しておくことで、Accessファイル内のクエリをSubversion のクライアント TortoiseSVN による差分管理ができるようになります。
また将来的にあなたの Access ツールをアップサイジングし、SQL Server をバックエンドとしたユーザー向けのフロントエンドとしてリファクタリングする際 、このVBAのスニペットの再利用があなたの生産性を爆上げすることは確実です。
この記事が少しでも皆さんのお役に立てれば幸いです。
こんにちわ。しらかば堂です。
この記事が少しでも皆さんのお役に立てれば幸いです。