goo blog サービス終了のお知らせ 

道草日記

通勤幾星霜…寄り道回り道の日記です。

VBA:ユーザーフォームを組み込みダイアログのように使う

2009-01-04 | VBA
 MsgBoxやInputBoxを使えば、標準モジュールの処理中にユーザーから入力を受けた後、処理を継続することができる。しかし、複雑な入力には対応できない。
 そこで、組み込みダイアログと同様な処理を、ユーザーフォームで行う。
 ポイントは以下の通り。
  1. 標準モジュール側にデータ交換用のグローバル変数を宣言
  2. フォーム側に、呼び出し用の関数(下例ではRetfnc関数)を作り、その中で自分自身のフォームをMe.Showする。
  3. フォーム表示以降、どこでUnloadしても、呼び出し関数のMe.Showの次の行に制御が移るので、戻り値処理等をする。
  4. ただし、データ交換用のグローバル変数を使えば戻り値はなくともいい。
 コードとしてはかっこ悪いが、標準モジュール側にデータ交換用のグローバル変数を使うほうが、戻り値を複数使えるので楽チン。

(例)
' ==================================
'  標準モジュール側
' ==================================
Option Explicit

Public Retstr As Variant  ' グローバル変数として宣言

Sub sample1()
  Dim mystr As Variant
     ' ユーザーフォームの関数を呼び出し、その中でShowする。
  mystr = UserForm1.Retfnc("<入力してください>")
  MsgBox mystr
    ' 実はMsgBox Retstrでも同じこと
End Sub

' ==================================
'  ユーザーフォーム側
' ==================================
Option Explicit

' TextBox1       :テキスト入力ボックス
' CommandButton1 :OKボタン

Public Function Retfnc(Msg As String) As Variant
  Me.TextBox1.Value = Msg
  Me.Show           ' 自分自身を Show
  Retfnc = Retstr  ' フォームを閉じるとき、入力したデータを戻り値として返す。
      ' ただし、Retstrはグローバルなので本当は不要
End Function

Private Sub CommandButton1_Click()
  Retstr = Me.TextBox1.Value
  Unload Me
    ' フォームを閉じるとき、自分を表示したRetfnc関数の 「Me.Show」の次の行に飛ぶ
    ' フォーム側で確保した変数の文字列領域はUnload以降アクセスできない(※)
    ' ので、グローバル変数に保存する必要がある。
End Sub

' --------------------------------------------

※ ただし、Boolean(True/False)など、記憶領域を参照しない型の変数はUnload後もアクセスできるらしい。

(例)
' ==================================
'  標準モジュール側
' ==================================
Option Explicit

Sub sample2()
  Dim ret As Boolean
     ' ユーザーフォームの関数を呼び出し、その中でShowする。
  ret = UserForm1.Retfnc
  If ret = True Then
    MsgBox "正解"
  End If
End Sub

' ==================================
'  ユーザーフォーム側
' ==================================
Option Explicit

' CommandButton1 :OKボタン
' CommandButton2 :キャンセルボタン

Dim frmRet as Boolean

Public Function Retfnc() As Boolean
  Me.Show
  Retfnc = frmRet  ' Unload後も、まだ値を維持。
End Function

Private Sub CommandButton1_Click()
  frmRet = True
  Unload Me
End Sub

Private Sub CommandButton2_Click()
  frmRet = False
  Unload Me
End Sub

' --------------------------------------------



最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。