VBA ユーザーフォームは作った瞬間にオブジェクトが使えるようになる!?(コロ子勘違いしていた)
こんにちは。
派犬事務員のコロ子です。
お久しぶりです。長らくブログを書いてなかったけど、やめたわけじゃないよ~。
最近仕事で変な単調作業をしていて犬小屋に帰ってからぐったり疲れてパソコンを触る元気がなかったので。
VBAを書く仕事は全然疲れないのに単調作業は本当に疲れて困るわぁ~(>_<)
ユーザーフォームについて、またまた勘違いしてました・・・。
何を勘違いしていたかというと、ユーザーフォームって作った瞬間にインスタンスが生成されてオブジェクトが使えるようになるんですね。
どーゆーことかというと、
①「ボタン1」と押すとUserForm1が表示される。
②TextBox1に数字を入力する。
③UserForm1の「OK」ボタンを押すとTextBox2にTextBox1を10倍した数字が入る。
このようなフォームの場合、
この処理のコードは下記のようになる。
「ボタン1」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン1() 'ユーザーフォームを表示する UserForm1.Show End Sub
UserForm1のOKボタンを押したときのコード(UserForm1モジュールに記載) Private Sub CommandButtonOK_Click() 'TextBox2にTextBox1×10を入力 TextBox2.Value = TextBox1.Value * 10 End Sub
ねーねー。
「ボタン1」を押してフォームが表示されるのも必要だけど、シートの数字をダブルクリックしたら、最初からその数字がTextBox1に入ってフォームが表示されるようにできる?
さらにTextBox2にも×10の値を入れといてねー。
楽勝!
できますよ~。すぐやりますね~。
簡単だよー、秒でできるよー、と下記のコードを書いたら
シートモジュールのダブルクリックイベント Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) UserForm1.Show UserForm1.TextBox1.Value = Target.Value Call UserForm1.CommandButtonOK_Click End Sub
※【注意】他のモジュールからCallするので
Private Sub CommandButtonOK_Click()
↓
Public Sub CommandButtonOK_Click()
に変更する。
あれー・・・。
UserForm1.TextBox1.Value = Target.Valueに数字が入っていない。
どーゆーことかと、ステップ実行をしてみたら
ダブルクリックのイベントの中でユーザーフォームを開くので、次の処理はユーザーフォームを閉じてからじゃないと実行できないのね。なるほど~!
でも、何か変だなぁ。ユーザーフォームを閉じているのに何でUserForm1.TextBox1.Value = Target.Valueがエラーにならないんだろう・・・?
もう1回ダブルクリックでユーザーフォームを開いてみると、
なんと!!さっきダブルクリックした値が入っているではないですか!
【1回目】
3をダブルクリックしてユーザーフォームを開く
TextBox1に値は入っていない
【2回目】
5をダブルクリックしてユーザーフォームを開く
1回目でダブルクリックした値が入っている。
【3回目】
さらに別の数字をダブルクリックしてユーザーフォームを開いてみると
2回目でダブルクリックした値が入っている。
ど、どういうこと?
何で前回の値を覚えているの?
ユーザーフォームってフォームを表示したときにインスタンスが生成されて、閉じたときに破棄されるんじゃないの???
???と思いながら、下記コードを試したてみた。
Sub Test1() UserForm1.TextBox1 = 10 End Sub
UserForm1.TextBox1 に10を入れる
Sub Test2() UserForm1.Show Debug.Print UserForm1.TextBox1.Value End Sub
UserForm1が表示される。
TextBox1 に10が入っている。
Sub Test3() Debug.Print UserForm1.TextBox1.Value End Sub
UserForm1を閉じて実行するとTextBox1は空欄。
ユーザーフォームは表示していないときもメンバーにアクセスできる。
ということは
①ユーザーフォームはVBEエディタで作った瞬間にインスタンスが生成されてオブジェクトが参照できる。
②閉じた時に値が破棄される。
ということなのね!
では、正解は
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) 'TextBox1に値をセット UserForm1.TextBox1.Value = Target.Value 'クリックイベントを呼び出す Call UserForm1.CommandButtonOK_Click 'フォームを表示 UserForm1.Show End Sub
TextBox1に値をセットして
リックイベントを呼び出して
それからフォームを表示を表示する。
またまた、長いこと勘違いしてたわぁ~。全然楽勝じゃなかったわぁ~。
ユーザーフォームは表示された時にインスタンスが生成されると思ってた。
だって「UserForm_Initialize」ってイベントがあるから。。。
ということは、ユーザーフォームのメンバーの初期値は「Initialize」イベントの中で書かなくてもOKってこと?
例えば、下記のようなシートでユーザーフォームを表示するとき
「ボタン1」を押したら、コンボボックスにB列のデータを
「ボタン2」を押したら、コンボボックスにD列のデータを
表示させたいとき
いつも「Initialize」イベントで書いていたけど、これでいいんだよね。
「ボタン1」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン1() UserForm2.ComboBox1.RowSource = Range("B6:B20").Address UserForm2.Show End Sub
「ボタン2」に登録するコード(Sheetモジュールか標準モジュールに記載) Public Sub ボタン2() UserForm2.ComboBox1.RowSource = Range("D6:D20").Address UserForm2.Show End Sub
もしかして「Initialize」イベント不要?
(いやいや、場合によるから)