電子書籍の厳選無料作品が豊富!

いつもお世話になってます。

この度Excelvba2013で、標準モジュールから最初のユーザーフォームtest1を呼び出し、CommandButton1をクリックしてさらに別のユーザーフォームtest2を呼び出し、test1で使用していた変数をそのまま使いたいのですが、標準モジュールにPublicで宣言すると使えるという方法があるそうですが、その方法を使いたくない場合、どのようにすればよいか分かりませんでした。
どのようにすれば宜しいでしょうか?
また、test1からtest2を呼び出した時に、test2のラベルの内容に、test1で取得していたdictionaryオブジェクトの値を表示したいのですが、どのようにすれば宜しいでしょうか?
お手数をおかけしますが、ご教授下さい。

★★★標準モジュール記載
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")
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
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.Show vbModeless
End Sub

★★★フォーム2つ目(test2)test1から呼び出し
----test1で使用していた変数やオブジェクトを使用したい
----test2を呼び出したタイミングで、[Label1.Caption = UBound(mydicKey)]のような表示を行いたい

Private Sub Label2_Click()
Dim i As Long
For i = LBound(mydicKey) To UBound(mydicKey)
Debug.Print mydicKey(i)
Debug.Print mydicitem(i)
Next i
End Sub

Private Sub Label3_Click()'test2終了してtest1へ戻る
Load test1
test1.Show vbModeless
Unload Me
End Sub

質問者からの補足コメント

  • なるほど。
    ----test2を呼び出したタイミングで、[Label1.Caption = UBound(mydicKey)]のような表示を行いたい
    こちらは、うまくできました。
    ----test1で使用していた変数やオブジェクトを使用したい
    については、今自分で見直しています。何とかできそうです。

    No.1の回答に寄せられた補足コメントです。 補足日時:2019/03/10 09:33
  • どう思う?

    見直しました。文字数の関係で分けます。一応動作しました。
    ★★★フォーム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)

    '~以下省略
    End Sub

      補足日時:2019/03/10 09:52
  • どう思う?

    ★★★フォーム1つ目続きtest2呼び出し
    Private Sub CommandButton1_Click()
    Me.Hide
    Load test2
    Call test2.FormInit(UBound(mydicKey),ws, myDic, mydicKey, mydicitem, row)
    test2.Show vbModeless
    End Sub

    ★★★フォーム2つ目(test2)test1から呼び出し
    Public Sub FormInit(ByVal Value1 As Long)
    Label1.Caption = Value1
    End Sub

      補足日時:2019/03/10 09:54
  • どう思う?

    ★★★サブモジュール
    Function mydic_set(ByVal ws As Worksheet, myDic As Object, mydicKey As Variant, mydicitem As Variant, row As Long) As Object
    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

    以上

      補足日時:2019/03/10 09:55
  • どう思う?

    こんな感じでうまくいきました。
    変数の宣言は、最初のフォームで行っています。サブモジュールで、Dim c As Rangeのみ入れてあります。他のモジュールで別の使い方をする為引き継いでいません。
    これらを含め、問題ない書き方(引き継ぎ方)なのでしょうか?
    お手数をおかけしますが、ご確認していただければありがたいです。

      補足日時:2019/03/10 10:00
  • サブモジュールの宣言の最後にいらないのが付いていました。こっちが正しいですかね。
    ★★★サブモジュール
    Function mydic_set(ByVal ws As Worksheet, myDic As Object, mydicKey As Variant, mydicitem As Variant, row As Long)

    さて、今、続きを作っていて、Public Sub FormInit内で、 Value1を使用することができたのですが、
    例えばですが、フォーム2の別の所で、
    Private Sub TextBox1_Change()
    Label1.Caption = Value1
    End Sub
    などとすると、Value1の値は0に戻っていました。どうやれば、フォーム1から引き継いだ値をフォーム2の他のテキストボックスなどでも使えるのでしょうか?
    度々申し訳ございません。

      補足日時:2019/03/10 20:01

A 回答 (2件)

★★★フォーム1つ目続きtest2呼び出し


Private Sub CommandButton1_Click()
Me.Hide
Load test2
test2.Value2 = UBound(mydicKey)
test2.Show vbModeless
End Sub

★★★フォーム2つ目(test2)test1から呼び出し
Privete mValue2 As Long

Public Property Let Value2(ByVal Value1 As Long)
mValue2 = Value1
End Sub

Private Sub TextBox1_Change()
Label1.Caption = mValue2
End Sub

んな感じ。
    • good
    • 0
この回答へのお礼

何とかいけました。
Public Propertyの終わりは、End Propertyでした。
また、最初のコードとの組み合わせは、フォーム1のCall test2.FormInit(UBound(mydicKey))の前にtest2.Value2 = UBound(mydicKey)を入れることでできました。後ろでは、だめでした。
また、Public Property Letの方は、Value2 やらValue1 やらmValue2 やら名前が次々変化していてよく分からないのですが、これから動きを確認していこうと思います。
この度は、どうもありがとうございました。

お礼日時:2019/03/13 02:12

★★★フォーム1つ目(test1)


Private Sub CommandButton1_Click()
Me.Hide
Load test2
Call test2.FormInit(UBound(mydicKey))
test2.Show vbModeless
End Sub

★★★フォーム2つ目(test2)test1から呼び出し
Public Sub FormInit(ByVal Value1 As Long)
Label1.Caption = Value1
End Sub

んな感じ。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!