アクションマクロをVBA変換する方法とそのメリットについて知りたいですか?
この記事では、アクションマクロをVBA(Visual Basic for Applications)に変換する方法について以下の観点で具体的に紹介します。
- アクションマクロの概要とその利用上のメリット、デメリット
- VBA変換の目的と作業の概要
- VBA変換作業の具体的手順
そしてこの具体的手順の中で、autoexec アクションマクロの名称変更や関数名・モジュール名の変更、モジュールの統合などについて取り上げ
さらに .accdbファイルの起動方法変更やアクションマクロの終了処理、VBAコードの抽出方法、Subversionリポジトリへのコミット手順についても説明します。
このアクションマクロのVBA変換手順を学ぶことで、簡単にプロトタイプが開発できるアクションマクロのメリットを生かしつつ、Subversion 等の構成管理ツールと組み合わせたコードの保守性の向上も手に入れることができます。
さあ、一緒にVBA変換の世界へ足を踏み入れ、あなたのツール開発の生産性を爆上げしませんか?
アクションマクロ概要
アクションマクロは、Microsoft Accessに組み込まれた開発ツールで、プログラミングの知識が限られたユーザーがちょっとした自動化ツールを作る場合に便利なしくみです。
ユーザーはAccessに組み込まれたビジュアルエディタから事前定義されたアクションや条件分岐等の制御構造を含むアクションを選ぶことで、例えばデータのインポートやエクスポート、更新、クエリの実行、フォームの開閉、レポートの印刷などの操作を含む様々なツールを開発することが出来ます。
具体的には、Access のリボンメニューから
作成 > マクロ
を順にクリックすることで起動される
ビジュアルエディタ を使用してアクション操作を作成、実行します。
このアクションマクロでは、ビジュアルエディタ内の✙アイコン右の▽アイコンから呼び出す「アクション」と
アクションの中で指定する「引数」を使い一つの処理を記述します。
このビジュアルエディタ内では、以下のような様々なアクションが選択でき、データベース内のテーブルやクエリ、フォーム、レポートなどのオブジェクトに対するさまざまな操作を行うことができます。
つまりAccessユーザーは
このビジュアルエディタを使ってアクションマクロの中にこうしたアクションを積み上げていくだけで手軽にツール開発ができてしまうわけです。
これらのアクションがどのような操作に対応するのかについて、本記事の趣旨と離れますが以下のリファレンスを提供していますので必要に応じて参照してください。
ただ、より高度な制御や本格的な機能が必要な場合は、やはりVBA(Visual Basic for Applications)を使用したカスタムコーディングが必要になります。
アクションマクロ利用のメリット
これはしらかば堂の私見になりますが
Access でのアクションマクロ利用には次のようなメリットがあります。
項番 | 特徴 | 説明 |
---|---|---|
1 | 初心者に適したツール | アクションマクロは、ビジュアルな操作によって処理を作成できるため、他のノーコード製品同様、プログラミングの経験が少ないユーザーでも直感的にツールが開発できます。 |
2 | 迅速にプロトタイプが作成可能 | アクションマクロを使用することで、アイデアのプロトタイプを素早く作成することができます。 |
3 | 自動化処理との親和性が高い | Access で作った .accdb ファイルの中にautoexec マクロというアクションマクロを定義すると、この .accdb ファイルをバッチファイル、タスクマネージャと組み合わせることでちょっとした自動化ツールを簡単に実装できます。 |
但し、実際のツール開発にあたっては、ツール内で利用するテーブル、クエリ、マクロ、フォーム、レポート等に対するきちんとした名称付与基準等のローカルルールを設け、これを関係者内で共有する必要があります。
アクションマクロ利用のデメリット
また同時に次のようなデメリットもあるように思います。
項番 | 特徴 | 説明 |
---|---|---|
1 | 技術情報の少なさ |
現在日本国内で利用可能なMicrosft 365 Access のアクションマクロには全部で87個ものアクションが選択可能ですが、国内のWebサイト、書籍等にこのアクションマクロを網羅的に扱っているものが少なく、使い慣れたアクション以外はよくわからないといった状況が起こりがちです。 |
2 | 複雑なロジックの表現の難しさ |
アクションマクロで分岐条件を記述することは可能ですが、複雑な条件やループの記述が難しく、処理の流れがわかりにくくなることがあります。 |
3 | エディタとしての使い勝手が悪い |
VScode等の汎用エディタに慣れたユーザーには他のノーコード製品同様、コピペ、一括修正ができないというその編集操作にストレスを感じるケースがあります。 |
4 | トレーサビリティ、メンテナンス性の問題 |
アクションマクロとVBAを併用してツールを作成する場合、ユーザーはアクションマクロのビジュアルエディタとVBE(Visual Basic Editor)の両方にまたがってツールのロジックを追うことになるため、特に別のユーザーの作成したツールのロジックを追う際にストレスを感じることがあります。 |
5 | 制約が多く再利用性に難がある |
アクションマクロは特定の操作に制限されているため、複雑な処理や特定の要件には対応しづらい、あるいは自由度や柔軟性が限られるケースがあります。 例えば、「保存済みのインポート/エキスート操作の実行」というアクションは事前にAccessの中で実行したインポート/エキスート操作を名前をつけて保存しておき、これをアクションマクロから再呼び出しする仕組みですが このインポート/エキスート先のファイルの指定が事前にAccessの中で実行したインポート/エキスート操作を行ったユーザーの操作に紐づくため、こうして作ったツールを別のユーザーへ展開すると(ユーザーのアカウント名等の実行環境が異なるため)動かないといったことが発生します。 その結果せっかく作ったツールがメンバ間で共有できない、あるいは展開の際に再度インポート/エキスート操作を実行して保存し直さないといけないといった再利用性に関する問題が発生します(注1)。 |
6 | デバッグの難しさ | アクションマクロにはVBEのようなリッチなデバッグ機能がないため、バグの特定やデバッグに困難を感じるケースがあります。 |
7 |
Subversion管理下で |
実は後ほどご紹介する方法で その結果、Subversionでの管理を出来ているにも関わらず(注2)アクションマクロ部分がブラックボックス化されてしまい差分管理ができないということがおきます。 |
(注1)インポート/エキスート操作を伴うツールのグループ内展開の難しさを解決する手段として、必要に応じて以下の記事も参照してください。
アクションマクロをVBA変換しよう
VBA変換の目的
実はアクションマクロをVBA変換することで、先に述べたアクションマクロのメリットを享受しつつ、デメリットを軽減することができました。
ここでは VBA変換することのメリットを実感するをために、以下の記事
中に登場する
- 作成T0000東京都コロナ発症状況_マスタ.accdb
という .accdbファイルの中の4つのマクロ
- autoexec
- M0010_Call_ImportCsvFile
- M0000_作成東京都コロナ発症状況マスタ
- M0020_Call_CleanUpImportErrorTable
をVBA化してみましょう。これらのマクロは以下のようなものです。
つまりこの .accdb ファイルの中のアクションマクロでは
- autoexec
が以下のアクションマクロを順次呼び出し、さらにそれらのアクションマクロ中で定義された処理が順次実行されています。
アクションマクロ名 | 処理内容 |
---|---|
M0010_ Call_ImportCsvFile |
以下のVBA関数を引数付きで呼び出します。 ImportCsvFile(“Downloads\130001_tokyo_covid19_patients.csv”, “130001_tokyo_covid19_patients”, True, True) |
M0000_作成東京都コロナ発症状況マスタ |
以下のクエリを順番に呼び出します。 Q0000_作成_T0000_東京都コロナ発症状況_マスタ |
M0020_ Call_CleanUpImportErrorTable |
以下のVBA関数を呼び出します。 CleanUpImportErrorTable() |
さて、これらのアクションマクロをVBAに変換する目的をもう一度明確にすると、大きく次の3点に集約されます。
項番 | 目的 |
---|---|
1 | この .accdbファイルの中のアクションマクロをVBA化することでツールの実装をVBAに集中させ、コードの可読性、保守性を向上させる。 |
2 | アクションマクロをVBA化後、さらにツールでVBAコードを抽出することで(注1)、VBAコードに対するSubversion での差分管理を可能とする(注2)。 |
3 |
保守性の向上をめざし、この .accdbファイルの autoexec アクションマクロを無効化してメンテナンスの際にShiftキー無しで普通に開けるようにする。 逆にバッチファイルからの自動起動の際は Access の /x スイッチ(注3)を使ってターゲットアクションマクロ(ここでは Call_Main とします)を直接起動する方式に変更する。 |
(注2)以下の記事で紹介している Subversion、そのクライアント TortoiseSVN を使うと .accdb ファイルから抽出したVBAコードの差分管理ができるようになります。
(注3) Access にはコマンドライン、バッチファイルからの起動時に使用可能な起動スイッチの指定ができ、例えば /x スイッチでアクションマクロを指定して起動したり、VBAコード抽出前に /decompile を指定することができます。
VBA変換作業の概要
以上の目的を達成するための変換作業は概ね以下のような流れの作業になります。
なお、ここで題材としている
- 作成T0000東京都コロナ発症状況_マスタ.accdb
は既にSubversionによリ差分管理されています。
項番 | 作業 | 目的 |
---|---|---|
1 | autoexec アクションマクロの名称変更 | autoexec アクションマクロの名前を autoexec_ に変更します。 |
2 |
アクションマクロのVBA変換 |
以下の4つのアクションマクロをVBA変換します。
|
3 | 関数名とモジュール名の変更 |
VBA変換された モジュール内で autoexec_() の関数名を Main() に変更し、モジュール名も Module2に変更します。 またこの関数を後で追加するアクションマクロ main から呼び出せるよう、戻り値の型を Integer とし、戻り値を設定するコードを追加します。 |
4 |
VBA変換されたアクションマクロのModule2モジュールへの統合 |
Main()関数の中でそれぞれのアクションマクロを呼びだしているステートメント部分をそれぞれのマクロをVBA化して生成したVBAコードで置き換えます。 |
5 | 不要モジュールの削除 |
不要となったVBA変換後の以下のモジュールを削除します。
|
6 | アクションマクロ main の定義 | 関数 Main() を呼び出すアクションマクロ mainを定義します。 |
7 |
バッチファイル内での.accdbファイル起動方法変更 |
この Access ツールを起動するバッチファイル の中で、このツールの呼び出し部分を /x main を使った書き方に置き換えます(注5)。 |
8 |
アクションマクロ exit の定義 |
Access の起動スイッチ /decompile 使用時(注4)に起動するアクションマクロ exit を定義します。 |
9 |
.accdbファイル からのVBAコード抽出 |
.accdb ファイルから VBAコードを抽出する(注5) |
10 |
.accdbファイル、.bas ファイルのSubversionリポジトリへのコミット |
管理対象となる .accdb ファイル、およびVBA抽出操作で出来た .bas ファイルをSubversionのクライアント TortoiseSVN を使って Subversion リポジトリにコミットします(注2)。 |
(注4)ここでアクションマクロのVBA変換用の題材として使用している
作成T0000東京都コロナ発症状況_マスタ.accdb
を起動するバッチファイル
作成東京都コロナウイルス発症者推移グラフ.bat
については以下の記事で詳しく紹介していますので必要に応じて参照ください。
(注5) .accdb ファイルから VBAコードを抽出する方法については必要に応じて以下の記事を参考にしてください。
VBA変換作業の具体的手順
autoexec アクションマクロの名称変更
まず この
- 作成T0000東京都コロナ発症状況_マスタ.accdb
をShiftを押しながらオープンし、ナビゲーションウインドウで autoexec アクションマクロの名前を autoexec_ に変更します。
アクションマクロのVBA変換
次に以下の4つのアクションマクロをVBA変換します。
- autoexec_
- M0000_作成東京都コロナ発症状況マスタ
- M0010_Call_ImportCsvFile
- M0020_Call_CleanUpImportErrorTable
ここでは最初の autoexec_ マクロを例にして、その具体的な手順を紹介します。
まずナビゲーションウインドウでマクロ名をクリックしながら右マウスボタンを押して
コンテキストメニューを表示し、このアクションマクロをデザインビューで開きます。
このアクションマクロのデザインビューを開いた状態で、左上のリボンメニューにある
マクロを Visual Basic に変換 ボタン
をクリックします。
すると以下のようなダイアログが現れるので
□ エラー処理コードを追加する(E)
□ コマントを含める(I)
の両方のチェックを外して 変換(C) ボタンをクリックすると以下のダイアログが現れるのでここで OK ボタンをクリックすると
次のようなVBE画面が現れ、これでVBA変換処理は終了です。
これらの4つのアクションマクロのVBA変換後の、変換前のアクションマクロ名に対応した各モジュール内のVBAコードは以下のようになっています。
Option Compare Database
Option Explicit
'------------------------------------------------------------
' autoexec_
'
'------------------------------------------------------------
Function autoexec_()
DoCmd.RunMacro "M0010_Call_ImportCsvFile", , ""
DoCmd.RunMacro "M0000_作成_東京都コロナ発症状況_マスタ", , ""
DoCmd.RunMacro "M0020_Call_CleanUpImportErrorTable", , ""
DoCmd.Quit acSave
End Function
Option Compare Database
Option Explicit
'------------------------------------------------------------
' M0010_Call_ImportCsvFile
'
'------------------------------------------------------------
Function M0010_Call_ImportCsvFile()
If (ImportCsvFile("Downloads\130001_tokyo_covid19_patients.csv", "130001_tokyo_covid19_patients", True, True) > 0) Then
End If
End Function
Option Compare Database
Option Explicit
'------------------------------------------------------------
' M0000_作成_東京都コロナ発症状況_マスタ
'
'------------------------------------------------------------
Function M0000_作成_東京都コロナ発症状況_マスタ()
DoCmd.SetWarnings False
DoCmd.OpenQuery "Q0000_作成_T0000_東京都コロナ発症状況_マスタ", acViewNormal, acEdit
DoCmd.OpenQuery "Q0010_削除_130001_tokyo_covid19_patients", acViewNormal, acEdit
DoCmd.OpenQuery "Q1010_作成_T1010_最終日付", acViewNormal, acEdit
DoCmd.OpenQuery "Q1020_更新_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
DoCmd.OpenQuery "Q1030_削除_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
End Function
Option Compare Database
Option Explicit
'------------------------------------------------------------
' M0020_Call_CleanUpImportErrorTable
'
'------------------------------------------------------------
Function M0020_Call_CleanUpImportErrorTable()
If (CleanUpImportErrorTable() > 0) Then
End If
End Function
関数名とモジュール名の変更
先ほどVBA変換された 変換するマクロ: autoexec_ モジュール 内のVBAコード
Option Compare Database
Option Explicit
'------------------------------------------------------------
' autoexec_
'
'------------------------------------------------------------
Function autoexec_()
DoCmd.RunMacro "M0010_Call_ImportCsvFile", , ""
DoCmd.RunMacro "M0000_作成_東京都コロナ発症状況_マスタ", , ""
DoCmd.RunMacro "M0020_Call_CleanUpImportErrorTable", , ""
DoCmd.Quit acSave
End Function
に対し、VBEの中で手動で
- 関数名を autoexec_ から main に変更
- main 関数の戻り値の型をIntegerに設定
- 戻り値の設定用のコードを追加
- モジュール名を Module2に変更
します。
変更後の Module2モジュールは次のようになります。
Option Compare Database
Option Explicit
'------------------------------------------------------------
' Main
'
'------------------------------------------------------------
Function Main() As Integer
Const C_SUCCESS As Integer = 0
Const C_FAILURE As Integer = 1
DoCmd.RunMacro "M0010_Call_ImportCsvFile", , ""
DoCmd.RunMacro "M0000_作成_東京都コロナ発症状況_マスタ", , ""
DoCmd.RunMacro "M0020_Call_CleanUpImportErrorTable", , ""
DoCmd.Quit acSave
Main = C_SUCCESS
End Function
ここで
- 5行目、8行目:関数名の変更、戻り値型の設定を手動で追加した部分
- 10~11行目、18行目:関数の戻り値設定用に手動で追加した部分
という対応関係なっています。
VBA変換されたアクションマクロのModule2モジュールへの統合
次に Main() 関数の中でそれぞれのアクションマクロを呼びだす
DoCmd.RunMacro "M0010_Call_ImportCsvFile", , ""
DoCmd.RunMacro "M0000_作成_東京都コロナ発症状況_マスタ", , ""
DoCmd.RunMacro "M0020_Call_CleanUpImportErrorTable", , ""
というステートメント部分をそれぞれのマクロをVBA化して生成したVBAコードで置き換えます。
Option Compare Database
Option Explicit
Function main() As Integer
Const C_SUCCESS As Integer = 0
Const C_FAILURE As Integer = 1
Call ImportCsvFile("Downloads\130001_tokyo_covid19_patients.csv", "130001_tokyo_covid19_patients", True, True)
DoCmd.SetWarnings False
DoCmd.OpenQuery "Q0000_作成_T0000_東京都コロナ発症状況_マスタ", acViewNormal, acEdit
DoCmd.OpenQuery "Q0010_削除_130001_tokyo_covid19_patients", acViewNormal, acEdit
DoCmd.OpenQuery "Q1010_作成_T1010_最終日付", acViewNormal, acEdit
DoCmd.OpenQuery "Q1020_更新_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
DoCmd.OpenQuery "Q1030_削除_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
Call CleanUpImportErrorTable()
DoCmd.Quit acSave
main = C_SUCCESS
End Function
ここで
- 9行目:DoCmd.RunMacro “M0010_Call_ImportCsvFile”, , “” の置き換え部分
- 11~16行目:DoCmd.RunMacro “M0000_作成_東京都コロナ発症状況_マスタ”, , “” の置き換え部分
- 18行目:DoCmd.RunMacro “M0020_Call_CleanUpImportErrorTable”, , “”
という対応関係になっています。
どうでしょう。だいぶすっきりしましたね。
ちなみにこの Module2 モジュールで参照している ImportCsvFile 関数、CleanUpImportErrorTable 関数は以下の記事で紹介されているもので、 Module1 モジュール中に記述されています。
不要モジュールの削除
次に元のVBAコードをMain関数に転記し、不要となったVBA変換後の以下のモジュール
- 変換するマクロ: M0000_作成東京都コロナ発症状況マスタ
- 変換するマクロ: M0010_Call_ImportCsvFile
- 変換するマクロ: M0020_Call_CleanUpImportErrorTable
を削除します。
アクションマクロ mainの定義
次にリボンメニューから
作成 > マクロ
を順にクリックし、以下のような関数 Main() を呼び出すアクションマクロ mainを定義します。
バッチファイル内での.accdbファイル起動方法変更
次にこの Access ツールを起動するバッチファイル
- 作成_東京都コロナウイルス_発症者推移グラフ.bat
の中で、このツールの呼び出し部分を
作成_T0000_東京都コロナ発症状況_マスタ.accdb
から
作成_T0000_東京都コロナ発症状況_マスタ.accdb /x main
に変更します。
この修正を Subversion クライアント TortiseSVN の差分抽出ツールから参照すると以下のように見えます。
アクションマクロ exit の定義
さらにリボンメニューから
作成 > マクロ
を順にクリックし、Accessの終了 を呼び出すアクションマクロ exitを定義します。
この時点でもともと定義されていた以下の4つのアクションマクロは従来処理のバックアップとして残してありますが、ここで実施しているVBA変換後の正常動作確認後のタイミングで必要に応じて削除しましょう。
- autoexec_
- M0000_作成東京都コロナ発症状況マスタ
- M0010_Call_ImportCsvFile
- M0020_Call_CleanUpImportErrorTable
.accdbファイル からのVBAコード抽出
ここで対象となっている
- 作成T0000東京都コロナ発症状況_マスタ.accdb
の格納されているフォルダに
で紹介されている
- ExportVBAcodeFromAccdb.bat
をコピーし
このバッチファイルをダブルクリックすると以下のように
- Module1.bas
- Module2.bas
という2つの .bas ファイルが作成されます。
ここで 抽出された Module2.bas は以下のようになっています。
Module Main
Option Compare Database
Option Explicit
Function Main() As Integer
Const C_SUCCESS As Integer = 0
Const C_FAILURE As Integer = 1
Call ImportCsvFile("Downloads\130001_tokyo_covid19_patients.csv", "130001_tokyo_covid19_patients", True, True)
DoCmd.SetWarnings False
DoCmd.OpenQuery "Q0000_作成_T0000_東京都コロナ発症状況_マスタ", acViewNormal, acEdit
DoCmd.OpenQuery "Q0010_削除_130001_tokyo_covid19_patients", acViewNormal, acEdit
DoCmd.OpenQuery "Q1010_作成_T1010_最終日付", acViewNormal, acEdit
DoCmd.OpenQuery "Q1020_更新_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
DoCmd.OpenQuery "Q1030_削除_T0000_東京都コロナ発症状況_マスタ_400日以前", acViewNormal, acEdit
Call CleanUpImportErrorTable
DoCmd.Quit acSave
Main = C_SUCCESS
End Function
End Module
目的どうりアクションマクロが VBAコードで抽出できる形になりましたね。
.accdbファイル、.bas ファイルのSubversionリポジトリへのコミット
それでは今回生成された3つのファイルを選択しTortoiseSVN のコンテキストメニューから
ToitoiseSVN > +追加(A)
を順にクリックし
OKボタンをクリックしてから
同様にフォルダ配下のファイル全体を選択して
SVN コミット(C)…
をクリックすると
次の様なダイアログが現れるので
20230625 アクションマクロをVBAに変換 refs #385
というメッセージを記入して OK ボタンをクリックすると
以下の様なダイアログが現れるので OK ボタンをクリックすると
元のフォルダ上の全てのファイルに緑色の✅アイコンが追加され、無事アクションマクロのVBA修正後の .bas ファイルが無事リポジトリに登録されました。
まとめ
この記事では、アクションマクロをVBA(Visual Basic for Applications)に変換する方法について以下の観点で具体的に紹介しました。
- アクションマクロの概要とその利用上のメリット、デメリット
- VBA変換の目的と作業の概要
- VBA変換作業の具体的手順
そしてこの具体的手順の中で、autoexec アクションマクロの名称変更や関数名・モジュール名の変更、モジュールの統合などについて取り上げ
さらに .accdbファイルの起動方法変更やアクションマクロの終了処理、VBAコードの抽出方法、Subversionリポジトリへのコミット手順についても説明しました。
このアクションマクロのVBA変換手順を学ぶことで、簡単にプロトタイプが開発できるアクションマクロのメリットを生かしつつ、Subversion 等の構成管理ツールと組み合わせたコードの保守性の向上も手に入れることができます。
さあ、一緒にVBA変換の世界へ足を踏み入れ、あなたのツール開発の生産性を爆上げしませんか?
この記事が少しでも読者の方のお役に立てれば幸いです。
こうしたノーコードの開発手法はMicrosoftの PAD(Power Automate Desktop)やAowerApps、ExcelのPower Query 等の先駆けといえるものですね。