派遣事務員の迷走

派遣事務員コロ子。会社の犬。顔出しNG。常に迷走している。

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」イベント不要?
(いやいや、場合によるから)