
先日、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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Microsoft Formsの「個人情報や...
-
ユーザーフォームを表示中にシ...
-
Excelにて、ユーザーフォームで...
-
ACCESSのフォーム、開くんです...
-
クリックイベントなのに、2回ク...
-
Form_Load と Form_Activate の...
-
パソコンの画面に合わせてユー...
-
c# Windows Form App テーブル...
-
EXCEL VBA ユーザーフォームの...
-
ACCESSでストップウォッチの作成
-
Hideについて(.NET)
-
クリックするたびに、フォーム...
-
VBのフォームをスクロールさせ...
-
フォームを同期的に
-
[ExcelVBA] Application.Dialog...
-
アニメGifが止まってしまう?
-
ユーザーフォームのラベルに時...
-
VBAでユーザーフォームを再表示...
-
VB.NETでフォーム間でのコント...
-
VBA コンボボックスとテキスト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ユーザーフォームを表示中にシ...
-
ExcelVBAのユーザーフォームの...
-
クリックイベントなのに、2回ク...
-
Microsoft Formsの「個人情報や...
-
Form_Load と Form_Activate の...
-
ユーザーフォーム上に現在日時...
-
VB.NETでフォームロード中のエ...
-
Hideについて(.NET)
-
VBAでユーザーフォームを再表示...
-
Excelにて、ユーザーフォームで...
-
VBAのテキストフォームの折り返...
-
モーダルフォームとモードレス...
-
ユーザーフォームのラベルに時...
-
VBA(エクセル)のユーザー...
-
コントロールの存在確認
-
ACCESSのフォーム、開くんです...
-
エクセルVBAのフォームを最...
-
Accessで、一つのフォーム画面...
-
【VBAユーザーフォームで閉じる...
-
パソコンの画面に合わせてユー...
おすすめ情報
うーん、ちょっと難しく使いこなせていません。
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 という入れ物に入っています。そこは、どう考えればよいのでしょうか。