0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Excel VBA 第9回 ユーザーフォームとモジュールのデータ引き渡しタイミング

Last updated at Posted at 2022-04-30

はじめに

最近は、Excel VBAでプログラミングをしておらず、作成済みのものを使用していました。
ふとした用途でユーザーフォームを使用してみたところ、ユーザーフォームとモジュールのデータ引き渡しタイミングで悩んでしまったので、備忘として残しておこうかと思いました。
どうでもいいですが、QiitaのMarkDown記載変わったんですね。本当に投稿していなかったなと今更に気づきました。

今回実施する内容

ユーザーフォーム(モーダル)を使用して、そこに何かの値を設定し、「OK」ボタンを押したときに、その値を取得するものを作ります。
今回は、テキストボックスの値を取得して、OKボタンを押すとMsgBoxを開くものにします。

UserForm.jpg

その値をどこに設定すべきなのか方法は色々ありますが、あまりPublic変数は使いたくないため、関数の戻り値として取得する方法でおこないます。

ソースコード(Git Hub)

UserFormDataTransfer

環境

OS:Windows 10 JP
Excel: Excel 2021 (64bit)

参考

Show メソッド

用語

特になし

標準モジュールのソース

Module1.bas
Option Explicit

Public Sub FormDataTransfer()
    Dim strTextValues() As String
    Dim i As Long
    Dim strMsg As String
    
    strTextValues = UserForm1.GetTextValues
    
    For i = LBound(strTextValues) To UBound(strTextValues)
        strMsg = strMsg & strTextValues(i) & vbCrLf
    Next
    
    MsgBox strMsg

End Sub

特に説明すべきこともないのですが、UserForm1.GetTextValuesで、ユーザーフォームを表示させて、そこからの戻り値をstrTextValuesの配列に代入しています。
その後のFor分は単なる取得したデータをつなげて表示しているだけです。

UserForm1の構成

ユーザーフォーム(UserForm1)は、今回のケースでは、テキストボックスを2つ作り(TextBox1TextBox2)、OKボタン(OKButton)ときキャンセルボタン(CancelButton)を作るシンプルなものです。

  • OKボタンを押すと、ユーザーフォームが閉じられ、2つのテキストボックスの値を応答します。
  • Cancelボタンを押すと、ユーザーフォームが閉じられ、やはり2つのテキストボックスの値を応答します。
  • 右上の「x」ボタンを押すと、ユーザーフォームが閉じられ、やはり2つのテキストボックスの値を応答します。

UserForm1のソース

UserForm1.frm
Option Explicit

Private strTextValues(1 To 2) As String


'OKボタンを押下したときに実行する。
Private Sub OKButton_Click()
    strTextValues(1) = TextBox1.Value
    strTextValues(2) = TextBox2.Value
    Me.Hide
End Sub

'Cancelボタンを押下したときに実行する。
Private Sub CancelButton_Click()
    Me.Hide
End Sub

'xボタンを押下したときに実行する。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        Cancel = True
        Me.Hide
    End If
End Sub


'モジュールから呼び出される。
'ユーザーフォームを開いて、テキストボックスに値を入れた後、OKボタン、もしくはCancelボタンを
'押下すると、そのテキストボックスの値を戻り値として返す。
Public Function GetTextValues() As String()
    Me.Show
    GetTextValues = strTextValues
End Function

OKButton_ClickCancelButton_ClickのSub関数は、OKボタンを押したとき、Cancelボタンを押したときに実施されます。
OKボタンを押したときは、テキストボックスの値を取得して、strTextValuesの配列に値を代入します。
その後、UserForm1を非表示にします。
Cancelボタンを押したときは、単にUserForm1を非表示にします。

UserForm_QueryCloseのSub関数は、「x」ボタンを押したときに実施されます。
CloseModevbFormControlMenuの場合は「x」ボタンを押したときのため、Cancel = Trueとして、Me.HideでUserForm1を非表示にします。

GetTextValuesの関数は、標準モジュールから呼び出され、UserForm1を表示し、UserForm1が閉じられると、strTextValuesの配列の値を応答します。

#データ引き渡しのタイミングについて
ユーザーフォームのデータ引き渡しで何に迷ったかといえば、2つありました。

  • UserForm1を閉じたときにどうやって値を戻すのか?UserForm1.Showってどうなると終わるのか?
  • OKボタンやCancelボタンを押したときにSub関数が発生しますが、これはSub関数であって戻り値がないので、どうやって値を渡すのか?

久しぶりに作った時は???となって困ったんです。考えれば大したことはないのですが。
Show メソッドをみると以下の記載があります。

UserForm がモーダルの場合、ユーザーはアプリケーションの他の部分を使用する前に応答する必要があります。 UserForm が非表示またはアンロードされるまで、その後のコードは実行されません。 UserForm が表示されたとき、アプリケーション内のその他のフォームになっていますが、その他のアプリケーションは無効ではありません。

上記の通り、モーダルの場合UserForm.Showが非表示、アンロードされるまではその後のコードは実行されませんから、それが終わってからテキストの値を取り出せばいいんだなということでした。
UserFormがアンロードされる場合は、Public変数のstrTextValuesも消えてしまうため、Unloadは使えないですね。したがって、Me.Hideで非表示にするようにしました。

また、OKボタンを押したとき、CanCelボタンを押したときについては、これもすでに上に記載した通りで、Me.Hideすれば、UserForm.Showが終わるわけですからそのあとに値を取得するだけでよかったのです。
「x」ボタンを押したときも同じですね。

GetTextValuesMe.Showの後にstrTextValuesを取得してその値を応答します。
GetTextValuesは、関数名で言えば値取得だけなのに、UserFormも表示させているため、思わしくないかもしれません。UserForm.Showはそれだけにして、あとからプロパティとして、strTextValuesを取得するでもよかったかもしれません。
いずれにせよ、ポイントは、

  • OKボタンを押したときに値を取得してPublic変数に保存しておく。
  • UserForm.Showが終わったらそのPublic変数の値を取得する。
    ってことかなと思いました。
    UserForm.Showの動きを忘れなければ問題ないはずなんですが・・・

#おわりに
ユーザーフォームとモジュールのデータ引き渡しタイミングについて記載しました。
モードれすで実施すると、Me.Showで止まらずすぐさまGetTextValues = strTextValuesが実行されてしまうため、問題です。まあなんとかすればいいんでしょう。

本ソースは、単なるポイントを記載したかっただけなので、MsgBoxがCancelでも表示されるとかは気にしていません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?