ほげーむわーく

宿題をゲームのように楽しむブログ

【エクセルVBA】ユーザーフォーム間で配列を受け渡す方法

f:id:takehito33711:20181222141643j:plain



今回はエクセルVBAユーザーフォーム間で配列の受け渡しをする方法をご紹介していきます。


VBAでは往々にしてプロシージャ間で変数や配列をやりとりする場合がありますが、
ユーザーフォームではそのやりとりが一筋縄ではいかないんですよね。


まずはプロシージャ間で変数や配列する場合には、プロシージャ名の()のところに渡したい変数や配列を入れて、
呼び出してやれば簡単に受け渡しができます。



次の例はプロシージャ①で配列を設定し、プロシージャ②にその配列を渡す例です。
プロシージャ②の()の中に、「ByRef 受け渡し名 as 受け渡す型」を入れます。
配列はVariant型なので受け渡す型=Variantとして設定してやります。


プロシージャ①でプロシージャ②をCallします。
「Call プロシージャ名()」の()の中に渡したい変数や配列を入れます。

Option Explicit
Public Sub プロシージャ①()
    
    Dim myAry(2) As Variant
    
    myAry(0) = "リンゴ"
    myAry(1) = "イチゴ"
    myAry(2) = "バナナ"
    
    Call プロシージャ②(myAry)
    
End Sub

Public Sub プロシージャ②(ByRef A() As Variant)
    
    Stop
    
End Sub


プロシージャ①を実行すると、プロシージャ②でStopがかかり、イミディエイトウインドウの中に配列の中身が確認できます。


f:id:takehito33711:20191104162437p:plain



つまりプロシージャ間で変数や配列をやり取りしたい場合には、プロシージャ名()の()の中に受け渡したいものを入れるだけでOKなんですが、
ユーザーフォームではこのやり方ができないんですよね。

それをユーザーフォームでも変数や配列のやり取りをしたいというのが今回の記事の内容です。

変数や配列のやり取りですが、「ユーザーフォーム⇔ユーザーフォーム」は出来ませんが、「ユーザーフォーム⇔プロシージャ」は可能です。

そこで、

送り側のユーザーフォームで配列を設定する

送り側ユーザーフォームからプロシージャに配列を渡す

受け側のユーザーフォームから配列が設定されたプロシージャを読み出す


このようにしてプロシージャを介することでユーザーフォーム間で変数や配列のやり取りができます。


それでは実際にやってみましょう。

ステップ①~送り側ユーザーフォームの設定~

まずユーザーフォーム①を作成し、コマンドボタンをつけておきます。
コマンドボタンを押すと設定した配列がユーザーフォーム②に送られるようにします。


f:id:takehito33711:20191104161143p:plain


ユーザーフォーム①に以下のコードを記述します。

Private Sub CommandButton1_Click()
    
    Dim myAry(2) As Variant
    
    myAry(0) = "リンゴ"
    myAry(1) = "イチゴ"
    myAry(2) = "バナナ"
    
    Call SendArray(myAry)
    
    Unload Me
    
    UserForm2.Show
    
End Sub

9行目で設定した配列をプロシージャに引数付きで渡します。
そして受け側であるユーザーフォーム②を開きます。

ステップ②~受けと送りのプロシージャを作成

ここではユーザーフォームから送られてきた配列を受け取るプロシージャと、受け取った配列をユーザーフォームに渡すプロシージャを作成します。
新しいモジュールを作成し、以下のコードを記述します。

Option Explicit
Private RcvAry() As Variant

Public Sub SendArray(ByRef SendAry() As Variant)
    
    RcvAry = SendAry
    
End Sub

Public Function PostAry() As Variant
    
    PostAry = RcvAry
    
End Function


コード記述の実際の画面はこんな感じです。


f:id:takehito33711:20191104232142p:plain


まず送られてくる配列の受けを担うプロシージャを作成します。

4行目のプロシージャで、Callで送られてきた引数(SendAry)をPrivate変数で受けます。
Private変数は同モジュール内でプロシージャを超えて使える変数です。モジュールの一番上に宣言してます。(プロシージャの中でしか使えないものはDimで宣言します。)
送られてきた配列はVariant型なので、Private変数の方もVariant型で宣言します。
このようにしてCallで送られてきた配列SendAryを、Private変数で受けてやることで、このモジュール内のどのプロシージャでもSendAryを保持して使えるようになります。

次に配列を送るプロシージャを作成します。

10行目のようにFunctionプロシージャを作成します。
ここではPostAryをFunctionの名前にします。FunctionにすることでPostAryをそのまま使用することができます。
送られてきた配列はPrivate変数で保持されているので、PostAry=Private変数とすることでPostAryに配列をセットすることができました。

ここまでの流れとしては、
ユーザーフォームからSendAryをCallで送る

SendAryをPrivate変数RcvAryで受ける(SendAry=RcvAry)

Private変数RcvAryをPostAryに変換する(RcvAry=PostAry)


SendAry→RcvAry→PostAryと配列がリレーしています。

ステップ③~ユーザーフォームで配列を受ける~


最後のステップです。

配列の受け側での処理を実装していきます。
ここではInitializeの画面にコードを書いていきます。

Private Sub UserForm_Initialize()
    
    Dim ChkAry() As Variant
    
    ChkAry = PostAry
    
    Stop
    
End Sub


実際に配列が送られてきているかどうかチェックしましょう。
変数宣言でChkAryを設定します。
ChkAry=PostAryとして送られてきた配列を受けます。

それでは実際に動かしてみて確認していきましょう。

ユーザーフォーム①のコマンドボタンをクリックすると、ユーザーフォーム②が開いてStop画面になり、イミディエイトウインドウに送られてきた配列の中身が確認できるかと思います。

f:id:takehito33711:20191104235054p:plain

まとめ


今回はユーザーフォーム間で配列を受け渡す方法をご紹介しました。
ユーザーフォームに配列を受け渡すにはプロシージャを介することでできるようになります。
そのプロシージャは配列と受けと送りの役割をそれぞれ持たせ、Private変数を活用することで配列をリレーさせることがポイントでした。

機会があればまた他のVBAテクニックをご紹介できればと思います。
お疲れ様でした。