VBAクラスを使ったイベント作成(Event,RaiseEvent,WithEvents)
VBAクラスを使う事で、ユーザー定義イベントを作成したり、動的にイベントを割り当てる事が出来ます。
ユーザー独自のイベントを作成したり、フォームに動的に追加したコントロールにイベントを設定することができます。
変数宣言にWithEventsキーワードを指定することで、クラスで発生するイベントに応答することができます。
このVBAサンプルは、これで何かができるというものではなく、
クラスのイベントを理解する為に極めて単純化したVBAコードになります。
Eventステートメント
[Public] Event プロシージャー名[(引数リスト)]
イベントに名前付き引数、省略可能な引数、またはParamArray引数を指定することはできません。
値を返すようにイベントを宣言することはできません。
イベントが宣言されたら、 RaiseEventステートメントを使用してイベントを発生させます。
イベントは、それが宣言されているモジュール内でしか生成できません。
RaiseEventステートメント
RaiseEvent イベント名[(引数リスト)]
イベントが発生したモジュール内で、そのイベントが宣言されていない場合は、エラーが発生します。
WithEventsキーワード
Dim ステートメント
Private ステートメント
Public ステートメント
モジュール レベルで使用します。
オブジェクトのモジュールのみで使えます、つまり、標準モジュールでは使用できません。
WithEventsは任意の数の変数に宣言できます。
ただし、WithEventsでは配列は作成できません。
また、キーワードNewとWithEventsは一緒には使用できません。
↓
Private WithEvents xlApp As Excel.Application
・・・
Set xlApp = New Excel.Application
このように、WithEventsとNewは分けて使わなければなりません。
標準モジュールと動作概要
たったこれだけですが、
ボタン1とボタン2では全く違った実装となります。
クリックすると、3秒後にセッメージボックスが表示されます。
クリックすると、直ぐにセッメージボックスが表示されます。
起動するプロシージャーは以下になります。
Sub EventTest()
UserForm1.Show
End Sub
記述場所およびプロシージャー名等、特に何も制限はありません。
UserForm1を表示さえすれば、どのような方法でも構いません。
ユーザーフォーム(UserForm1)
Option Explicit
'ボタン1:イベントに応答するために定義する変数
Private WithEvents mTimer As clsEvent
'ボタン2:動的ボタン対応クラスのインスタンス変数
Private clsEvent As clsEvent
'ボタン1:最初から存在するbtn1のClickイベント
Private Sub btn1_Click()
Set mTimer = New clsEvent
Call mTimer.TimerMsg(3)
End Sub
'ボタン1:WithEventsを指定したmTimerのTimerEventイベント
Private Sub mTimer_TimerEvent(ByVal aTime As Long)
MsgBox aTime & "秒経過しました。"
End Sub
'ボタン2:イベントクラスにボタンを追加
Private Sub UserForm_Initialize()
Set clsEvent = New clsEvent
Set clsEvent.Button = addButton(Me.btn1.Top + 50, _
Me.btn1.Left, _
Me.btn1.Height, _
Me.btn1.Width, _
"ボタン2")
End Sub
'ボタン2:ユーザーフォームにボタンを追加
Private Function addButton(ByVal aTop As Single, _
ByVal aLeft As Single, _
ByVal aHeight As Single, _
ByVal aWidth As Single, _
ByVal aName As String) As MSForms.CommandButton
Set addButton = Me.Controls.Add("Forms.CommandButton.1", aName)
With addButton
.Top = aTop
.Left = aLeft
.Height = aHeight
.Width = aWidth
.Caption = aName
End With
End Function
クラス(clsEvent)
Option Explicit
'ボタン1:イベントの宣言、RaiseEventでイベント発生
Public Event TimerEvent(ByVal aTime As Long)
'ボタン2:イベントに応答するために定義する変数
Private WithEvents myButton As MSForms.CommandButton
'ボタン1:指定時間後にTimerEventイベントを発生させる
Public Sub TimerMsg(ByVal aTime As Long)
Application.Wait Now() + TimeSerial(0, 0, aTime)
RaiseEvent TimerEvent(aTime)
End Sub
'ボタン2:クラスで扱うボタンの設定/取得
Public Property Get Button() As Control
Set Button = myButton
End Property
Public Property Set Button(ByVal addBtn As Control)
Set myButton = addBtn
End Property
'ボタン2:クラスで扱うボタンのClickイベント
Private Sub myButton_Click()
MsgBox myButton.Caption & "がクリックされました。"
End Sub
クラスを使ったイベントの解説
(ボタン2を配置する時だけボタン1を使っています。)
本来は、
・EventステートメントとRaiseEventステートメントでの、ユーザー定義イベント
・WithEventsキーワードでの、クラス発生イベントの応答
これらを別々に解説するところなのでしょうが、ここではこの2つを一緒にしたものになります。
クラスを使ったイベントとして、混乱しやすく覚えづらい部分なので、その違いを比較しやすいようにと言う目的があります。
ボタン1:
ボタン2:
その変数またはプロシージャーが使われているボタンを指しています。
変数およびプロシージャーは、それぞれのボタンで全く別々のものが使用されています。
ユーザーフォームが表示された後にボタン1クリック。
・TimerMsgプロシージャー
ここでEventステートメントで定義されているTimerEventを発生させる
あくので、EventとRaiseEventの使い方のサンプルVBAとしての意味合いだけのものです。
ボタン2の動作順
ボタン2は、ユーザーフォームには最初は配置されていないボタンです。
ユーザーフォームが初めて表示(使用)されたとき、
Set clsEvent.Button = addButton(… 'クラスにボタンを登録
ユーザーフォームが表示された後にボタン2クリック。
フォーム標準のボタンを割り当てています。
Clickはボタンに標準で存在するイベントです。
プロシージャー名は、
変数名_イベント名
VBAクラスを使ったイベントの最後に
・EventステートメントとRaiseEventステートメントでの、ユーザー定義イベント
・WithEventsキーワードでの、クラス発生イベントの応答
いずれも頻繁に使うものではないと思います。
動作の仕組みを理解しておき、実際に使う時に調べながら記述できるようにしておくだけで良いでしょう。
同じテーマ「VBAクラス入門」の記事
VBAクラスの作り方:列名のプロパティを自動作成する
VBAクラスの作り方:独自Rangeっぽいものを作ってみた
クラスとイベントとマルチプロセス並列処理
クラスとCallByNameとポリモーフィズム(多態性)
オートフィルターを退避回復するVBAクラス
オートフィルター退避回復クラスを複数シート対応させるVBAクラス
コレクション(Collection)の並べ替え(Sort)に対応するクラス
VBAクラスのAttributeについて(既定メンバーとFor Each)
VBAクラスを使ったイベント作成(Event,RaiseEvent,WithEvents)
VBAで音楽再生するクラスを作成
図形を方程式で動かすVBAクラス
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。