テキストボックスのAfterUpdateの使い方と、似ているChangeイベントとの違いについてご説明します。
AfterUpdateイベントやBeforeUpdateイベント、Changeイベントなどの更新時に実行されるイベントは実行のタイミングが意外と混同されがちです。
そのため、使いどころがいまいちわからないという結果になってしまいます。
ですが、ちゃんと実行タイミングを理解することで使いどころが見えてきます。
その他のテキストボックスの操作やイベントについては、下記記事をご覧ください。
- テキストボックスの追加と詳細設定する方法
- テキストボックスに入力されている値を取得する方法
- テキストボックスのイベント一覧と使い方
- テキストボックスのChangeイベント テキストボックスの値が変更されると実行
1.今回使用するサンプルツール
まずは今回使用するサンプルツールについて、ご説明します。
テキストボックスを3つ用意して、1つ目と2つ目のテキストボックスに数字を入力して、確定されると、3つ目のテキストボックスが計算されます。
また、Changeイベントとの違いも見るために、同様のテキストボックスを用意してChangeイベントの挙動も組み込んでいます。
上が「AfterUpdateイベント」の挙動で、下が「Changeイベント」の挙動になります。
「AfterUpdateイベント」は入力した後、次のコントロールに移動して初めて計算されます。
「Changeイベント」は数字が入力されるたびに計算されます。
2.AfterUpdateイベントとは
AfterUpdateイベントはテキストボックスにテキストが入力され、他のコントロールにフォーカスが移動する直前に実行されます。
テキストボックスが確定した後に実行されるということです。
テキストを確定したら計算される処理や、 文字が確定するまで処理を行わなくても良い場合はChangeイベントではなくAfterUpdateイベントの方が良いです。
Changeイベントとの違い
Changeイベントでは文字列が変更されるたびにイベントが発生してしまいます。
重たい処理が組み込まれている場合や、文字列が確定するまで処理を行わなくても良い場合はChangeイベントではなくAfterUpdateイベントの方が処理の発生回数が抑制できます。
今回のサンプル動画のツールは単純な計算処理のためどちらも処理が一瞬ですが、もし重たい処理の場合は使い分ける事で大きく変わってきます。
AfterUpdateイベントの作成方法
「AfterUpdateイベント」は、イベントを組み込みたいテキストボックスが設置されているユーザーフォームのフォームモジュールに作成します。
作成するにはユーザーフォーム上のテキストボックスをWクリック、もしくは右クリックで「コードの表示」を選択します。
ユーザーフォームをWクリック、もしくは右クリックで「コードの表示」でもフォームモジュールを表示して、作成可能ですが初めからテキストボックスから表示した方が楽です。
対象のテキストボックスからフォームモジュールを開くと、基本的に「Changeイベント」が自動的に生成されます。
今回はChangeイベントも使用しますが、AfterUpdateイベントを使用するためには右上の「Change」を「AfterUpdate」に変更します。
変更すると新しくプロシージャが生成されます。
イベントが生成されたら、あとはイベントプロシージャ内に実行したいコードを記述します。
3.サンプルツール
AfterUpdateイベントの作成方法の説明はここまでにして、動画紹介したサンプルツールの作り方です。
ユーザーフォームとコントロールの準備
まずはユーザーフォームとテキストボックスを作ります。
フォームモジュールを追加して、テキストボックスを3つ×2を設置します。
テキストボックスの追加は「テキストボックスの追加と詳細設定する方法」をご覧ください。
計算するツールということで、「×」と「=」をラベルで付け加えています。
また、「AfterUpdateイベント」と「Changeイベント」の両方の挙動を確認するためにラベルを追加しています。
難しいことはなく、単純に設置しているだけです。
標準モジュール
フォームを作成したあとはユーザーフォームを表示するコードと、計算部分のコードを標準モジュールに記述します。
フォームモジュールに直接記述しても構いませんが、計算する値を入力するテキストボックスすべてに使用したいので、標準モジュールに作成して呼び出すだけにしたいと思います。
ユーザーフォームを表示する
作成したUserForm1をモードレスで表示します。
Sub FormShow()
UserForm1.Show vbModeless
End Sub
計算部分のコード
今回は2つのテキストボックスを掛け算します。
数字以外を入力された場合などのエラー処理は組み込んでいませんが、空白時の計算は行わない処理だけ組み込んでいます。
Sample1プロシージャに「AfterUpdateイベント用」を記述して、Sample2プロシージャに「Changeイベント用」を記述します。
実は指定しているテキストボックスが違うだけで、処理は同じです。
Sub Sample1()
With UserForm1
If .TextBox1.Value <> "" And .TextBox2.Value <> "" Then
.TextBox3.Value = Format(.TextBox1.Value * .TextBox2.Value, "#,##0")
End If
End With
End Sub
Sub Sample2()
With UserForm1
If .TextBox4.Value <> "" And .TextBox5.Value <> "" Then
.TextBox6.Value = Format(.TextBox4.Value * .TextBox5.Value, "#,##0")
End If
End With
End Sub
「If .TextBox1.Value <> “” And .TextBox2.Value <> “” Then」はテキストボックス1と2が空白じゃない時のみ計算するように判定しています。
「.TextBox3.Value = Format(.TextBox1.Value * .TextBox2.Value, “#,##0”)」でテキストボックス1×テキストボックス2の計算を行っています。
計算結果の桁数がわかりやすいように「Format」関数でカンマを表示させています。
Sample1も2も処理内容は同じです。
記述次第では1つのプロシージャにまとめられます。
今回は使用しないけどプロシージャをまとめてみる
例えば次の様に「ActCtrl = .ActiveControl.Name」とアクティブなコントロールの名前を取得して、分岐する方法です。
下記コードの様に記述すると1つにまとめることが可能です。(※今回は使いません。)
Sub Sample3()
Dim ActCtrl As String
With UserForm1
ActCtrl = .ActiveControl.Name
If ActCtrl = "TextBox1" Or ActCtrl = "TextBox2" Then
If .TextBox1.Value <> "" And .TextBox2.Value <> "" Then
.TextBox3.Value = Format(.TextBox1.Value * .TextBox2.Value, "#,##0")
End If
ElseIf ActCtrl = "TextBox4" Or ActCtrl = "TextBox5" Then
If .TextBox4.Value <> "" And .TextBox5.Value <> "" Then
.TextBox6.Value = Format(.TextBox4.Value * .TextBox5.Value, "#,##0")
End If
End If
End With
End Sub
フォームモジュール
次はフォームモジュールに記述する「Changeイベント」を記述します。
上記で説明した通り、設置したテキストボックスをWクリックすると自動的に「Private Sub TextBox1_Change()」が生成されますので、テキストボックスにそれぞれWクリックして作成します。
1つ目と2つ目は「AfterUpdateイベント」にします。
Option Explicit
Private Sub TextBox1_AfterUpdate()
Call Sample1
End Sub
Private Sub TextBox2_AfterUpdate()
Call Sample1
End Sub
Private Sub TextBox4_Change()
Call Sample2
End Sub
Private Sub TextBox5_Change()
Call Sample2
End Sub
生成したら、先ほどの標準モジュールの計算部分を各テキストボックスで呼び出します。
実行する
標準モジュールとフォームモジュールのイベントが出来ましたので、実行します。
「Sub FormShow()」を実行すると、フォームが表示されるのであとはテキストボックス1と2、4と6に数字を入力します。
あとはイベントが実行されるので、テキストボックス3と6に計算結果が表示されます。