第22回.コントロールの動的作成
ユーザーフォームは、事前に画面デザインを考えて、それにそって部品コントロールを配置するものです。
しかし、ユーザーの操作に応じて、動的に部品コントロールを変更したい場合があります。
・部品コントロールの表示/非表示を切り替える
・動的に部品コントロールを追加/削除する
コントロールの動的作成の動作説明
初期
コンボボックスは1~5が選択できるようにします。
コンボボックスの選択
チェックボックスのチェック
チェックを外すとテキストボックスを消します。
コントロールの表示/非表示を切り替える
・Visibleプロパティの値をTrueで表示/Falseで非表示
・コントロールをフォーム外へ移動することで非表示/所定位置に移動することで表示
以下では、Visibleプロパティの値を変更する方法でのVBAサンプルになります。
コントロールの名称
チェックボックス:chk01~chk05
テキストボックス:txt01~txt05
フォームモジュール
Option Explicit
'初期処理
Private Sub UserForm_Initialize()
With Me.cmb件数
.Style = fmStyleDropDownList
.List = Array(0, 1, 2, 3, 4, 5)
End With
Call ControlsUnVisibleAll
End Sub
'閉じるボタン
Private Sub btClose_Click()
Unload Me
End Sub
'コンボボックスで数値を選択
Private Sub cmb件数_Change()
Dim i As Long
For i = 1 To Me.cmb件数.Value
Me.Controls("chk" & Format(i, "00")).Visible = True
Next
Call ControlsUnVisible(Me.cmb件数.Value)
End Sub
'チェックボックスのチェックを変更
Private Sub chk01_Change()
Me.txt01.Visible = Me.chk01.Value
End Sub
Private Sub chk02_Change()
Me.txt02.Visible = Me.chk02.Value
End Sub
Private Sub chk03_Change()
Me.txt03.Visible = Me.chk03.Value
End Sub
Private Sub chk04_Change()
Me.txt04.Visible = Me.chk04.Value
End Sub
Private Sub chk05_Change()
Me.txt05.Visible = Me.chk05.Value
End Sub
'指定数値以降のチェックボックスとテキストボックスを非表示
Private Sub ControlsUnVisible(Optional ByVal cnt As Long = 0)
Dim i As Long
For i = cnt + 1 To 5
Me.Controls("chk" & Format(i, "00")).Visible = False
Me.Controls("chk" & Format(i, "00")).Value = False
Me.Controls("txt" & Format(i, "00")).Visible = False
Next
End Sub
'全てのチェックボックスとテキストボックスを非表示
Private Sub ControlsUnVisibleAll()
Dim ctl As Control
For Each ctl In Me.Controls
Select Case TypeName(ctl)
Case "CheckBox", "TextBox"
ctl.Visible = False
End Select
Next
End Sub
フォームモジュール名.Show
これだけで良いです。
テストするだけならフォームモジュールでF5でも構いません。
実際に動かしながら、動作と対応するVBAコードを確認してみてください。
動的に部品コントロールを追加/削除する
VBAクラスでWithEventsを使います。
コントロールの名称
クラスモジュール
Option Explicit
'イベントを発生させるクラス(オブジェクト)
Private WithEvents pCheckBox As MSForms.CheckBox
'コントロールの親であるフォーム
Private pForm As MSForms.UserForm
'対応するコントロールを設定するプロパティ
Public Property Set CheckBox(ByVal aCheckBox As MSForms.CheckBox)
Set pCheckBox = aCheckBox
Set pForm = aCheckBox.Parent
End Property
'WithEventsのイベントプロシージャー
Private Sub pCheckBox_Change()
Dim sNum As String
sNum = Right(pCheckBox.Name, 2)
Dim txt As MSForms.TextBox
Set txt = GetTextBox(sNum)
If txt Is Nothing Then
Set txt = pForm.Add("Forms.TextBox.1", "txt" & sNum)
With txt
'以下の数値はサンプル画像で使った数値です
.Top = sNum * 21 + 13
.Left = 30
.Height = 16.8
.Width = 168
End With
End If
txt.Visible = pCheckBox.Value
End Sub
'テキストボックスの存在確認:エラーを使った簡易コードにしています
Private Function GetTextBox(ByVal sNum As String) As MSForms.TextBox
On Error Resume Next
Set GetTextBox = pForm.Controls("txt" & sNum)
End Function
WithEventsのイベントプロシージャーは、
WithEvents変数名_イベント名
これはVBAの規則となっています。
MSForms.CheckBox
このように、MSFormsのメンバを使わなければなりません。
単にCheckBoxではエラーとなります。
フォームモジュール
Option Explicit
Private clsAry() As clsEvent
'初期処理
Private Sub UserForm_Initialize()
With Me.cmb件数
.List = Array(0, 1, 2, 3, 4, 5)
End With
ReDim clsAry(1 To 5)
End Sub
'閉じるボタン
Private Sub btClose_Click()
Unload Me
End Sub
'コンボボックスで数値を選択
Private Sub cmb件数_Change()
Dim ctl As Control
Dim max As Long
Dim num As Long
max = Me.cmb件数.Value
For Each ctl In Me.Controls
If IsNumeric(Right(ctl.Name, 2)) Then
num = Right(ctl.Name, 2)
If num > max Then
'コントロールの削除
Me.Controls.Remove ctl.Name
End If
End If
Next
'チェックボックスの動的追加
For num = 1 To max
Call AddCheckBox(num)
Next
End Sub
'チェックボックスの動的追加
Private Function AddCheckBox(ByVal num As Long) As MSForms.CheckBox
'チェックボックスの存在確認
Set AddCheckBox = GetCheckBox(num)
If Not AddCheckBox Is Nothing Then Exit Function
'チェックボックスをフォームに追加
Dim sName As String
sName = "chk" & Format(num, "00")
Set AddCheckBox = Me.Controls.Add("Forms.CheckBox.1", sName)
With AddCheckBox
.Top = num * 21 + 13
.Left = 10
.Height = 16.8
.Width = 18
.Caption = ""
End With
'追加したチェックボックスをクラスに設定
Set clsAry(num) = New clsEvent
Set clsAry(num).CheckBox = AddCheckBox
End Function
'チェックボックスの存在確認
Private Function GetCheckBox(ByVal num As Long) As MSForms.CheckBox
On Error Resume Next
Set GetCheckBox = Me.Controls("chk" & Format(num, "00"))
End Function
フォームモジュール名.Show
これだけで良いです。
テストするだけならフォームモジュールでF5でも構いません。
実際に動かしながら、動作と対応するVBAコードを確認してみてください。
コントロールの動的作成の最後に
基本的には、「コントロールの表示/非表示を切り替える」こちらの方法が良いでしょう。
画面に収まる範囲内で同時に表示できる数には限度がありますし、最大数は決まっているはずです。
最大数をあらかじめ配置しておき、表示/非表示での切替と位置移動だけで全て対応できます。
とはいえ、コントロールの動的追加はユーザーフォームを扱う上では必要な技術ですので、いざと言う時に使えるように習得しておくと良いでしょう。
同じテーマ「ユーザーフォーム入門」の記事
第18回.2段階のコンボボックス
第19回.数値専用のテキストボックス
第20回.テキストボックスの各種イベント
第21回.ユーザーフォームの各種イベント
第22回.コントロールの動的作成
第23回.イベントプロシージャーの共通化
第24回.イベントプロシージャーの共通化(Enter,Exit)
第25回.簡易音楽プレーヤーの作成
第26回.プログレスバーを自作する
第27回.インクリメンタルサーチの実装
第28回.テンキーのスクリーンキーボード作成
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.メッセージボックス(MsgBox関数)|VBA入門
8.セルのクリア(Clear,ClearContents)|VBA入門
9.ブック・シートの選択(Select,Activate)|VBA入門
10.条件分岐(Select Case)|VBA入門
- ホーム
- マクロVBA応用編
- ユーザーフォーム入門
- コントロールの動的作成
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。