はじめまして。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) では、それぞれどのようなコードを記載すればよろしいでしょうか?
説明が下手で申し訳ありませんが、アドバイスをお願いいたします
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
こんばんは。
解説はコードにあるコメントを読んで下さい。基本的な 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
なるほど。
たくさんのエッセンスが盛り込まれていて、サンプルコードを
読ませていただくだけで、すごく勉強になります。
エラーハンドリングを除くと、ポイントとなるのは
・Form.Hide を実行したタイミングで、呼び出し元に処理が戻る。
ただし、Hide にしただけではオンメモリのままなので、呼び出し元
で、Unload するまでは、プロパティアクセスが可能
ということですね。
インスタンスの生成やエラーハンドリングなど、細かいところまで
アドバイスをいただき、お忙しいところお手数をおかけして申し訳
ありませんでした。
ソースコードはコメントのおかげもあって、ほぼ理解できました。
ありがとうございました。
No.1
- 回答日時:
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 のプロパティを参照する)
といったことができないかな…ということでした。
わかりにくい説明で申し訳ありませんでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- 英語 和訳を教えてください 4 2022/06/16 12:01
- 留学・ワーキングホリデー どちらが正しいですか? 1 2023/05/13 00:57
- 英語 英文について教えて下さい。 2 2022/06/14 10:37
- 英語 the fee is a bit too large considering our interne 3 2022/06/18 14:02
- 英語 【 論・表 英訳 】 問題 次の文を英訳せよ。ただし、その文は単独であり、前後に文はないとする。 父 1 2022/07/25 17:03
- フランス語 下記のフランス語の英訳は文法的に合っていますか? J’ai donné à mon père le 1 2023/06/25 19:21
- 英語 下記の英語は正しいですか? 2 2022/07/04 16:38
- 英語 和訳を教えてください 4 2022/12/07 08:25
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
private subモジュールを他のモ...
-
【C#/Java?】try-catchでcatch...
-
マクロで、次のコードへ行く前...
-
特定のファイルを他のプロセス...
-
IF文に時間(何時から何時ま...
-
特定の名前のオートシェイプの...
-
シグナル 6(SIGABRT)とは?
-
Excelプロセスが消えない
-
Excel VBA セルの名前があるか...
-
順番に処理させたい
-
vbaのエラー対応(実行時エラー...
-
Word VBA。各マクロの間に待ち...
-
Pentium4とPentiumD、どちらが...
-
途中で処理を中断させたい (ア...
-
COBOL OCCURSで指定したデータ...
-
フォルダのアクセス権確認について
-
VB6にてネットワーク上にある共...
-
VB6のロストフォーカス時の処理...
-
VBAでBook読み込み時の非表示方...
-
【C#】Page_Loadさせない方法に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【C#/Java?】try-catchでcatch...
-
IF文に時間(何時から何時ま...
-
private subモジュールを他のモ...
-
vbaのエラー対応(実行時エラー...
-
マクロで、次のコードへ行く前...
-
どう増強すべきか
-
特定の名前のオートシェイプの...
-
シグナル 6(SIGABRT)とは?
-
Excel VBA セルの名前があるか...
-
ExcelのVBAで、選択したファイ...
-
どうやってもFor文を抜けてしま...
-
シェルスクリプトでファイル内...
-
ドリブン??
-
特定のファイルを他のプロセス...
-
VB6にてネットワーク上にある共...
-
【VBA】エラー処理で別プロシー...
-
Functionで戻り値を複数返す方法
-
Word VBA。各マクロの間に待ち...
-
エクセル VBAで複数セル選択時...
-
VBA 複数の行を高速で削除する...
おすすめ情報