先日、Excelvba2013の質問で、フォームへの変数の引き継ぎのコードを教えていただきましたが、まだ理解が乏しく、もう少し追加で質問させて下さい。
標準モジュールから最初のユーザーフォームtest1を呼び出し、CommandButton1をクリックしてさらに別のユーザーフォームtest2を呼び出し、test1で使用していた変数をそのまま使いたいのですが、標準モジュールにPublicで宣言すると使えるという方法があるそうですが、その方法を使いたくない場合の方法として、Public Property Let というのを教えていただきました。
試した所、変数mValue2 の元の中身であるUBound(mydicKey)は、フォーム2のどこからでも使用できるようになりました。しかし、残りの変数Call test2.FormInit(ws, myDic, mydicKey, mydicitem, row)でフォーム2へ渡したものは、フォーム2のPublic Sub FormInit内のみでしか使用できず値が消えていました。
他のもフォーム2内のどこでも使用するにはどうすればよいのでしょうか?他のもPublic Property Letを使ってセットしようとしましたが、うまくいきませんでした。今回も標準モジュールにPublicで宣言する方法は、なしでお願いします。
全てで使える方法以外でも、フォーム2のPublic Sub FormInitから任意のプロシージャのみに引き渡す方法もあるのでしょうか?(例えばフォーム2のPublic Sub FormInitからフォーム2のPrivate Sub TextBox1_Changeのみへ変数rowを引き継ぐような方法)
また、Public Property Letがこの中でどんなふうな役割をしているのかもご教授いただけるとありがたいです。
どうぞ、よろしくお願いいたします。
★★★標準モジュール記載
Public Sub ShowForm()
Load test1
test1.Show vbModeless
End Sub
★★★フォーム1つ目(test1)
Dim ws As Worksheet
Dim myDic As Object
Dim mydicKey As Variant
Dim mydicitem As Variant
Dim row As Long
Dim c As Range
Private Sub UserForm_Initialize()
Dim i As Long
Set ws = ThisWorkbook.ActiveSheet
Set myDic = Nothing
Set myDic = CreateObject("Scripting.dictionary")
Call 別モジュール.mydic_set(ws, myDic, mydicKey, mydicitem, row)
With ComboBox1
.ColumnCount = 2
.TextColumn = 2
For i = LBound(mydicKey) To UBound(mydicKey)
.AddItem ""
.List(i, 0) = mydicKey(i)
.List(i, 1) = ws.Range(mydicitem(i)).Offset(1, 0)
Next i
End With
End Sub
Private Sub CommandButton1_Click()
Me.Hide
Load test2
test2.Value2 = UBound(mydicKey)
Call test2.FormInit(ws, myDic, mydicKey, mydicitem, row)
test2.Show vbModeless
End Sub
★★★フォーム2つ目(test2)test1から呼び出し
Privete mValue2 As Long
Public Property Let Value2(ByVal Value1 As Long)
mValue2 = Value1
End Property
Public Sub FormInit(ByVal ws As Worksheet, myDic As Object, mydicKey As Variant, mydicitem As Variant, row As Long)
Label1.Caption = mValue2
End Sub
Private Sub TextBox1_Change()
Label1.Caption = mValue2
End Sub
★★★フォーム1のサブモジュール
Function mydic_set(ByVal ws As Worksheet, myDic As Object, mydicKey As Variant, mydicitem As Variant, row As Long)
Dim c As Range
row = ws.Range("B" & Rows.Count).End(xlUp).Row
For Each c In ws.Range(ws.Cells(1, 2), ws.Cells(row, 2))
If c.Value Like "*番" Then
myDic.Add c.Value, c.Address
End If
Next c
mydicKey = myDic.Keys
mydicitem = myDic.Items
End Function
No.3ベストアンサー
- 回答日時:
>Public Property Letのみ使用してGetの方は使用していないのですが、ユーザーフォーム1の値である、UBound(mydicKey) をユーザーフォーム2内で使用できます。
再度書きますが、コード「test2.Value2 = UBound(mydicKey)」を実行した時点で
test2側に記述されたプロシージャー「Public Property Let Value2(ByVal Value1 As Long)」が起動し、mValue2へ値が渡されます。このmValue2はPublic Property Let の外(test2内では共通)で定義されたものですので、test2が破棄(UesrFormではUnloadなど)されるまで保持されるのです。
(もし中で定義されていれば、そのプロシージャが終了した時にその変数は破棄されます。)
つまり、test2が破棄されるまでは、その中の別のプロシージャーでは共通の値として使用できます。
また、この値を他のモジュールから参照する場合に必要なのが、「Public Property Get Value2」で「○○=test2.Value2」というコードの時に起動することになります。
勿論、test2内の別のプロシージャーで「〇〇=Value2」というコードでも起動しますが、ここではmValue2を直接参照できますのであまり意味はありません。
実はもっと多彩な使い方があるのですが、クラスモジュールに関する事項を参考にすれば良いと思います。実はUserFormは標準で準備されたクラスモジュールなのです。
No.2
- 回答日時:
内容がややこしいので正確に把握できていない点をご了承願います。
基本的に、test2(UserForm?)内で変数定義した物は他から参照できません。
(他から、むやみに変更されたくない変数などに使用するものです)
それを容易にするためにPublic(公開する)変数が存在するのですが、それを使いたくないようです。
そこでPublic Property Let/Getの出番になります。
簡潔に言えば、「Property Let (引数)」で「変数に引数を代入する」、「Property Get()」で「変数の値を引き出す」といったところでしょうか。ですから、
>最初の回答の中の話は、LetがあってGetで取得という感じで使用するのでしょうか?
という認識で問題ないと思います。
このように、外部からの「変数を引数の値にして」や「変数の値をください」という命令を公に使える(他のモジュールで使える)ようにしているのです。
勿論、Private Property Let/Getも存在し、これらは外部から使用することはできません。
「test2のmValue2が消えていた」ということですが、先に
test2.Value2 = UBound(mydicKey)
が確実に処理されていますでしょうか?
※この処理によりtest2の「Public Property Let Value2(引数)」プロシージャが処理され、mValue2の値が入力されます。
その後、「〇〇=test2.Value2」というコマンドのよって、「Public Property Get Value2」プロシージャが起動して「test2.Value2(test2での変数名はmValue2)」がかえって来るのです。
No.1
- 回答日時:
>残りの変数Call test2.FormInit(ws, myDic, mydicKey, mydicitem, row)でフォーム2へ渡したものは、
>フォーム2のPublic Sub FormInit内のみでしか使用できず値が消えていました。
Sub FormInit の外に変数宣言をして、
Sub FormInit の中で必要なものすべて転記します。
Property は次のように Get/Let をペアで使うとあたかも
Value2 という Public 変数のように使えます。
Dim mValue2 As Long
Public Property Get Value2() As Long
Value2 = mValue2
End Property
Public Property Let Value2(ByVal Value1 As Long)
mValue2 = Value1
End Property
同様に、Property には Get/Set をペアで使うのもあります。
こちらは、オブジェクト変数に使います。
単純な変数なら、フォーム上にテキストボックスを作ってそれを直接使うというのもあります。
変数の値が常に見えてるのでデバッグ中はとても便利です。
本番移行の際は、これらの Visible プロパティを False にすれば、
ロジックは変更する必要がありません。
この Visible プロパティをもれなく変更するには、
条件付きコンパイル引数を使うのが確実です。
興味があったら検索してみてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 別ブックからの転記の高速化について VBA 別ブックからの転記の高速化についてご教授下さい。 19 2022/07/26 13:07
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- Excel(エクセル) 【マクロ】スクショ印刷がうまく動かない件 5 2022/12/06 17:37
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Visual Basic(VBA) コード名シートA列と集計シートA列のコードが一致したら、コード名シートA5からk12の範囲をコピーし 1 2022/08/29 23:46
このQ&Aを見た人はこんなQ&Aも見ています
-
風水の観点で選ぶ観葉植物とは?置き場所や上げたい運気ごとの注意点を紹介!
観葉植物で運気をアップするコツを、風水デザイン1級建築士の福島昌彦さんに伺った。
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
Form間の値の渡し方
Visual Basic(VBA)
-
EXCEL VBAのユーザーフォームに引数を渡す方法について
Excel(エクセル)
-
-
4
Excel VBAで、ユーザーフォームの値を、モジュールで使用したい。
Visual Basic(VBA)
-
5
ユーザーフォームに入力したデータを保持する方法
Visual Basic(VBA)
-
6
UserForm1.Showでエラーになります。
工学
-
7
VBAでユーザーフォームの表示を確認
Visual Basic(VBA)
-
8
VBAでユーザーフォームを再表示させたい。
Excel(エクセル)
-
9
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
10
エクセルVBA テキストボックスに3桁ごとにコンマ
Visual Basic(VBA)
-
11
エクセルVBA ユーザーフォームのTextBoxを日付にしたい
Excel(エクセル)
-
12
Form オブジェクトの戻り値の設定
Visual Basic(VBA)
-
13
VBA ユーザーフォームのChangeイベントを停止したい
Access(アクセス)
-
14
EXCEL VBAモジュール間のデータ受け渡し
その他(プログラミング・Web制作)
-
15
VBA エンターキーでイベントに入りたい。
PowerPoint(パワーポイント)
-
16
ExcelのVBA。public変数の値が消える
Visual Basic(VBA)
-
17
VBAで別モジュールへの変数の受け渡し方法
Visual Basic(VBA)
-
18
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
19
オブジェクト型の変数にフォームを入れたい
Visual Basic(VBA)
-
20
VBA モジュールで共通に使う変数の宣言方法
その他(Microsoft Office)
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
access2021 更新前に処理をしたい
-
ユーザーフォームを表示中にシ...
-
エクセルVBA フォーム上でOnkey...
-
【VBAユーザーフォームで閉じる...
-
クリックイベントなのに、2回ク...
-
検索のユーザーフォームの表示...
-
テキストボックスやラベルのクリア
-
Form_Load と Form_Activate の...
-
VBA ユーザーフォームを速く開...
-
VBAでユーザーフォームを再表示...
-
ユーザーフォームのラベルに時...
-
ACCESSのフォーム、開くんです...
-
ユーザーフォームのコピー?
-
テキストボックス入力データの...
-
モーダルフォームとモードレス...
-
Excelのユーザーフォームのテキ...
-
[VB6.0]フォーム上に配置したコ...
-
VB.NETでフォーム間でのコント...
-
'ユーザーフォーム右上隅の[×...
-
VB.NETでWebブラウザのお気に入...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ユーザーフォームを表示中にシ...
-
ExcelVBAのユーザーフォームの...
-
ユーザーフォームのテキストボ...
-
クリックイベントなのに、2回ク...
-
MSGBOXのフォント大きさ変更
-
VBAでユーザーフォームを再表示...
-
Hideについて(.NET)
-
Form_Load と Form_Activate の...
-
モーダルフォームとモードレス...
-
コントロールの存在確認
-
ユーザーフォーム上に現在日時...
-
【VBAユーザーフォームで閉じる...
-
エクセルVBAのフォームを最...
-
ACCESSのフォーム、開くんです...
-
Microsoft Formsの「個人情報や...
-
VBA(エクセル)のユーザー...
-
フォームウィンドウを最前面に...
-
ユーザーフォームのラベルに時...
-
'ユーザーフォーム右上隅の[×...
-
Excelにて、ユーザーフォームで...
おすすめ情報
うーん、ちょっと難しく使いこなせていません。
Private Sub CommandButton1_Click()
Me.Hide
Load test2
test2.Value2 = UBound(mydicKey)
Call test2.FormInit(ws, myDic, mydicKey, mydicitem, row)
test2.Show vbModeless
Label1.Caption = mValue2
End Sub
mValue2に値が入っているのは確認できるのですが、上記のようにフォーム2の処理が終わり、フォーム1に戻った直後の処理の中(Label1.Caption = mValue2)では、中身が入っていません。
別の処理を行うと値が確認できます。
どうしたら、戻った直後の処理で変数mValue2を使えますか?
すみません。先ほどの補足は勘違いしていました。test2.Show vbModelessのあと、別フォームの処理にとんで、戻って続きを処理すると思っていましたが、違いました。よって、Label1.Captionの所は、フォーム2の方で操作すればできました。お騒がせしました。忘れて下さい。
最初の回答の中の話は、LetがあってGetで取得という感じで使用するのでしょうか?
以前別の質問の時、教えていただいた回答ではLetのみを使用して別フォームに引き渡していました。その辺りが今一結びつきません。調べても、教えていただいたようなやり方の記事もあまり出てこないので・・・。
その辺りを、もう少しご教授いただけないでしょうか?
お手数をおかけいたしますが、よろしくお願いいたします。
test2のmValue2が消えていた、とかその辺りの処理はできました。
もう少し教えていただきたいのは、今回提示したコードは、Public Property Letのみ使用してGetの方は使用していないのですが、ユーザーフォーム1の値である、UBound(mydicKey) をユーザーフォーム2内で使用できます。Public Property Letの処理で mValue2の中の値を入れているのだと思いますが、今回の説明の最後にある、「〇〇=test2.Value2」というコマンドのよって、「Public Property Get Value2」プロシージャが起動して、という所ですが、このコードに「Public Property Get Value2」というプロシージャは存在していないのですが、mValue2 という入れ物に入っています。そこは、どう考えればよいのでしょうか。