VBAにおいて、フォームにコントロール(ボタンなど)を動的に配置する方法がわかりにくかったので、恥ずかしながらQAサイトなどからコードのかけらを集めてサンプルプログラムを書いてみました(3時間前に発見していたら嬉しかっただろうというものです)。
Dictionaryに格納した複数の文字列をボタンとして配置したフォームをポップアップさせます。
ボタンを押下すると、そのボタンに設定したnameプロパティをmsgboxで出力します。
(ここで押した場合の値を後で使用するにはグローバル変数に格納するのがよさそう?
SelectSortBookForm
'' ユーザフォームに空フォームを定義しておく。キャプションなど必要であればプロパティから変更しておく。
Private Sub SelectForm()
End Sub
MyButton
'' コマンドボタンの実態をクラスモジュールに作成しておく
Public WithEvents button As CommandButton
'' クリックイベント発生時の動作
Private Sub button_Click()
pub_clickedButtonName = button.name
Unload SelectForm'フォームをメモリから解放する
End Sub
module1
'' Dictionary型を引数にとって全要素をボタンにしたFormを作成する
Sub make_form(dictionary As Object)
Dim i As Integer
Dim btn As Control
Dim NewBtn() As New MyButton ''ボタンオブジェクトを動的配列
ReDim NewBtn(1 To dictionary.Count) '' 配列の長さを動的に決定
With SelectForm
i = 1
For Each Key In dictionary
Set btn = .Controls.Add("Forms.CommandButton.1", dictionary(Key))
'' 第一引数はコマンドボタンを表し、第二引数がnameプロパティになる
With btn
.Top = 5 + (i - 1) * 20
.Left = 5
.Height = 20
.Width = 60
.Caption = "No." & i & ":" & dictionary(Key)
End With
Set NewBtn(i) = New MyButton
Set NewBtn(i).button = btn
i = i + 1
Next Key
.Height = i * 20 + 10
.Width = 70
.Show ' フォームを起動する
End With
End Sub
'' テストメソッド
' フォームで押されたボタンの名前を呼び出し元で利用するためにはpublicで変数を作成しておく必要がある。
Public pub_clickedButtonName As String
Sub test_make_form()
Dim targetDictionary As Object
Set targetDictionary = CreateObject("Scripting.Dictionary")
targetDictionary(0) = "ビアンカ"
targetDictionary(1) = "フローラ"
targetDictionary(2) = "ルドマン"
Call make_form(targetDictionary)
msgbox pub_clickedButtonName
End Sub
雑感
- VBA系の公式ドキュメント、えらいわかりにくいorさがしにくい
- コントロールなどGUI系の用語よくわかっていない