Quantcast
Channel: t-hom’s diary
Viewing all articles
Browse latest Browse all 493

Access VBAでフォームのコントロールイベント共通化

$
0
0

前回紹介したExcelVBAのユーザーフォームに動的メニューを追加する方法を紹介した。
thom.hateblo.jp

ただ、実は作りたかったのはAccessで、連票フォームのフッター領域にそれを配置したかったのだ。
f:id:t-hom:20171216122925p:plain

慣れないAccessと格闘する前にまずExcelフォームでプロトタイプを作ろうと思い立ったのが前回の記事。

Accessフォームで発生した問題

さて、Accessに移植するにあたり、ひとつハマったことがある。
すごく単純なことだけど、コントロールイベントをクラスで検知しようとした際に、うまく動かなかったのだ。
原因はボタンのクリック時イベントに、[イベントプロシージャ]を選択していなかったこと。

今回はこれについて順を追って説明する。

まず以下のようなフォームを作成した。
f:id:t-hom:20171216123618p:plain

それからVBEでクラスモジュールを挿入し、オブジェクト名をButtonWrapperとした。
コードは以下のとおり。

PublicWithEvents btn As CommandButton

PrivateSub btn_Click()MsgBox btn.Caption &"がクリックされました。"EndSub


フォーム本体のコードは次の通り。

Private Buttons As Collection
PrivateSub Form_Load()Set Buttons =New Collection
    For i =0To4Dim b As ButtonWrapper
        Set b =New ButtonWrapper
        Set b.btn =Me.Controls("コマンド"& i)
        Buttons.Add b
    NextEndSub

こうすると、コマンド0からコマンド4までの5つのボタンがButtonWrapperオブジェクトに包まれてCollection(Buttons)に格納される。
ButtonWrapper内ではボタン用の変数btnがWithEventsで宣言されているので、ボタンごとにイベントを書かなくてもこれでイベントを検知できる。

これだけで動くと思っていた。
実際、ExcelVBAならこれだけで動く。

ところがフォームを起動してボタンを押してもうんともすんとも言わない。

解決策

調べた結果、ボタンのプロパティでクリック時イベントが空だと、いくらイベント検知のコードがあっても動かないらしい。
f:id:t-hom:20171216124457p:plain

ということで全ボタンを選択し、クリック時プロパティのプルダウンからイベントプロシージャを選択。
f:id:t-hom:20171216124749p:plain

これで、無事にイベントを検知できるようになった。

仕様の推察

Excelの場合はボタンをクリックした際のイベントはVBAで書くと決まっているのでイベントを検知したら即、対応するコードが実行される。
Accessでは事情が異なり、クリックイベント=VBAとは限らない。

試しにボタンを配置した後、デザインモードでクリックしてイベントのビルドを選択してみる。
f:id:t-hom:20171216130354p:plain

すると、ビルダーの選択画面が出てきて、コード(VBA)以外にも、式・マクロといったAccess機能でイベントを作成できることがわかる。
f:id:t-hom:20171216130738p:plain

クリック時プロパティに明示的に[イベントプロシージャ]を設定しておくと、Accessにコードを実行するということが伝わり、対応するコードが実行される。

普通にイベントをビルドした場合は問題ないが、今回のようにコントロールイベントを共通化する際は明示的にイベントのビルドを行わないので、この設定が必要である。


Viewing all articles
Browse latest Browse all 493

Trending Articles