- 締切済み
Form オブジェクトの戻り値の設定
はじめまして。Porome です。 Excel 2003 の VBA を使ってプログラミングをしています。 Form オブジェクトの戻り値の設定方法/受取方法について教えてください。 実装したいプログラムの概要は、以下の通りです。 標準モジュールに記載したサブルーチンから Form オブジェクトを 生成し、Form オブジェクトで入力されたデータを標準モジュール側 で取得する…というものです。 書きたいソースコードのイメージは以下の通りです。 Sub MySub1() dim i_Form As New MyForm1 dim i_Name As String dim i_Age As String dim i_Ret As Integer 'MyForm1OK, MyForm1Cancel が戻ってくるまで、じっと待つ i_Ret = i_Form.Show, vbModal Select Case i_Ret 'MyForm1 で OK ボタンが押された Case MyForm1OK: i_Name = i_Form1.txtName.Value i_Age = i_Form1.txtAge.Value MsgBox(i_Name & " さんの年齢は " & i_Age & " 歳です") 'MyForm1 で Cancel ボタンが押された Case MyForm1Cancel: MsgBox("処理はキャンセルされました") 'MyForm1 では、MyForm1 では、MyForm1OK, MyForm1Cancel 以外は '戻さない仕様とします。 Case Else '何もしない(ここには来てはいけない) End Select End Sub こういったことを実現するためには ・MyForm1 では、 OK ボタンを押したら、MyForm1OK を Show メソッドの戻り値として セットし、処理を MySub1 に戻す Cancel ボタンを押したら、MyForm1Cancel を Show メソッドの戻り値としてセットし、処理を MySub1 に戻す OK ボタン、Cancel ボタン Click 以外の Form イベントでは、MyForm1 での処理が継続され、MySub1 は MyForm1 の戻り値(MyForm1OK/MyForm1Cancel)を、じっと待つ といったことが必要になってくるかと思います。 こういった処理を実装するには、呼び出し元 (MySub1)、呼び出し先 (MyForm1) では、それぞれどのようなコードを記載すればよろしいでしょうか? 説明が下手で申し訳ありませんが、アドバイスをお願いいたします
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんばんは。 解説はコードにあるコメントを読んで下さい。基本的な Tips はだい たい盛り込んであるかと。。 ' ■ 標準モジュール ----------------------------------------- Option Explicit ' // 標準モジュールで Public 定数として宣言しておく必要がある Public Const MyForm1OK As Long = 1 Public Const MyForm1Cancel As Long = 2 Sub MySub1() Dim i_Form As MyForm1 Dim i_Name As String Dim i_Age As String Dim i_Ret As Integer ' // i_Form のインスタンスを生成 ' // フォームがメモリにロードされて表示される ' // Dim xxxx As New MyForm1 はインスタンスが残る可能性がある ' // ので、意味をよく分かっていない場合は使うべきでない。 ' // 次のように Set ステートメントで New を使う Set i_Form = New MyForm1 'MyForm1OK, MyForm1Cancel が戻ってくるまで、じっと待つ ' ↓ ' // 単純にフォームを表示するだけで良い ' // Form が閉じられるか、Hide されると次行に処理フローが戻る i_Form.Show vbModal ' // [X]で閉じられた場合は、プロパティーを参照するとエラーが ' // 発生するので、エラーハンドラに飛ばして Cancel 扱いの ' // 処理をおこなう On Error GoTo Err_UserClose i_Ret = i_Form.Value ' <------ココ。エラー発生の可能性あり ' // エラーハンドラから Resume Next でここに戻る ' // エラー処理の初期化 On Error GoTo 0 ' // i_Ret の値で条件分岐処理 Select Case i_Ret Case MyForm1OK: 'MyForm1 で OK ボタンが押された i_Name = i_Form.txtName.Value i_Age = i_Form.txtAge.Value MsgBox (i_Name & " さんの年齢は " & i_Age & " 歳です") Case MyForm1Cancel: 'MyForm1 で Cancel ボタンが押された MsgBox ("処理はキャンセルされました") Case Else '何もしない(ここには来てはいけない) End Select ' // フォームをメモリーから開放 Unload i_Form Terminate: ' // 終了処理 ' // オブジェクト変数の破棄 Set i_Form = Nothing Exit Sub Err_UserClose: ' // [X]ボタンによるエラーハンドラ ' // キャンセル扱いとする i_Ret = MyForm1Cancel ' // エラーハンドラから処理を戻すときは必ずエラーをクリアする Err.Clear Resume Next End Sub ' ■ MyForm1モジュール ------------------------------------- Option Explicit ' // Value プロパティー用のモジュールレベル変数 Private mlValue As Long ' // Value プロパティー(読み取り専用)を用意 Public Property Get Value() As Long Value = mlValue ' // Public 変数を使うという手もあるが Property プロシージャ ' // にした方が様々な処理を同時に行える。読み取り専用の ' // プロパティー、書き込み専用プロパティーなど柔軟な処理が ' // 可能。 End Property ' // イベントプロシージャ Private Sub UserForm_Initialize() ' // 初期値などを設定する mlValue = MyForm1Cancel End Sub Private Sub CommandButton1_Click() mlValue = MyForm1OK ' // Hide すると処理フローは MySub1 に戻るが MyForm1 は ' // オンメモリのままなので、Unload されるまでは、 ’// プロパティー等にアクセス可能。 Me.Hide End Sub Private Sub CommandButton2_Click() mlValue = MyForm1Cancel Me.Hide End Sub
- Nayuta_X
- ベストアンサー率46% (240/511)
Public を使用します。 例: 以下の様にすると Public で、宣言された、変数は、Form からでも モジュールからでも 使用できます。 Public i_Form As New MyForm1 Public i_Name As String Public i_Age As String Public i_Ret As Integer Sub MySub1()
お礼
返事が遅くなって大変失礼しました。 たしかに、Public な(グローバルな)変数を定義してしまえば 機能としては十分だと思います。 今回、私が考えていたのは、事前に、VbMsgBoxResult (MsgBox の戻り値) のようなものを定義しておき、 UserForm から VbMsgBoxResult のような戻り値を 返してもらって、その値によって、呼び出し側で 処理を変更する(UserForm のプロパティを参照する) といったことができないかな…ということでした。 わかりにくい説明で申し訳ありませんでした。
お礼
なるほど。 たくさんのエッセンスが盛り込まれていて、サンプルコードを 読ませていただくだけで、すごく勉強になります。 エラーハンドリングを除くと、ポイントとなるのは ・Form.Hide を実行したタイミングで、呼び出し元に処理が戻る。 ただし、Hide にしただけではオンメモリのままなので、呼び出し元 で、Unload するまでは、プロパティアクセスが可能 ということですね。 インスタンスの生成やエラーハンドリングなど、細かいところまで アドバイスをいただき、お忙しいところお手数をおかけして申し訳 ありませんでした。 ソースコードはコメントのおかげもあって、ほぼ理解できました。 ありがとうございました。