チェックボックスが動的に追加されたExcelユーザーフォームがあります。
次のようなコードでチェックボックスを追加します。
Set chkBox = Me.Controls.Add("Forms.Checkbox.1", "Checkbox" & i)
これらのチェックボックスをすべて削除したいと思います。
Dim j As Integer
'Remove all dynamically updated checkboxes
For Each cont In Me.Controls
For j = 1 To NumControls
If cont.Name = "Checkbox" & j Then
Me.Controls.Remove ("Checkbox" & j)
End If
Next j
Next cont
次のエラーメッセージが表示されます。
より良いアプローチは、作成したコントロール(たとえば、コレクション内)を追跡し、それを使用して削除することです。
このようにして、コードは名前形式にバインドされず、他のコントロールタイプにも適用できます。
Private cbxs As Collection
Private Sub UserForm_Initialize()
Set cbxs = New Collection
End Sub
' Remove all dynamicly added Controls
Private Sub btnRemove_Click()
Dim i As Long
Do While cbxs.Count > 0
Me.Controls.Remove cbxs.Item(1).Name
cbxs.Remove 1
Loop
End Sub
' Add some Controls, example for testing purposes
Private Sub btnAdd_Click()
Dim i As Long
Dim chkBox As Control
For i = 1 To 10
Set chkBox = Me.Controls.Add("Forms.CheckBox.1", "SomeRandomName" & i)
chkBox.Top = 40 + i * 20
chkBox.Left = 20
cbxs.Add chkBox, chkBox.Name ' <-- populate tracking collection
Next
' Demo that it works for other control types
For i = 1 To 10
Set chkBox = Me.Controls.Add("Forms.ListBox.1", "SomeOtherRandomName" & i)
chkBox.Top = 40 + i * 20
chkBox.Left = 60
chkBox.Add chkBox, chkBox.Name
Next
End Sub
「チェックボックス」で始まる他のコントロール名がないと仮定すると、
For Each cont In Me.Controls
If InStr(cont.Name, "Checkbox") = 1 Then
Me.Controls.Remove cont.Name
End If
Next cont
コントロールの名前、タイプ、および数がすでにわかっている場合、なぜ二重ループなのでしょうか。
削除できるのは、実行時に作成されたコントロールのみであることに注意してください。
'the following removes all controls created at runtime
Dim i As Long
On Error Resume Next
With Me.Controls
For i = .Count - 1 to 0 step -1
.Remove i
Next i
End With
Err.Clear: On Error GoTo 0
そしてあなたの場合: 'すべての命名が正しい場合
Dim j&
For j = 1 To NumControls
Me.Controls.Remove "Checkbox" & j
Next j
コントロールのチェックを追加すると、これが修正されたようです。理由は完全にはわかりませんが、動作します。
Dim j As Integer
'Remove all dynamically updated checkboxes
For Each cont In Me.Controls
If TypeName(cont) = "CheckBox" Then
For j = 1 To NumControls
If cont.Name = "Checkbox" & j Then
Me.Controls.Remove cont.Name
Exit For
End If
Next j
End If
Next cont
保持するコントロールと削除するコントロールを選択するもう1つの方法は、.Tag属性を使用することです。これにより、たとえば.Tagをビットフィールドとして使用することにより、追加されたコントロールを細かく制御できます。
作成時:
With Me.Controls.add("Forms.Label.1", Visible:=True)
{code}
.Tag = 1
{more code}
次に、片付けの時間が来たら、
For Each C In Me.Controls
If C.Tag = 1 Then Me.Controls.Remove C.Name
Next
コマンドボタンを使用して元のコードを書き直し、「NumControls」ではなく「Me.Controls.Count」を追加し、「Cont」をコントロールとして定義しました。それは私のために働いているようです。これがあなたのために働くかどうか私に知らせてください:
->
On Error Resume Next
Dim Cont As Control
Dim C As Integer
'Remove all dynamically updated checkboxes
For Each Cont In Me.Controls
For C = 1 To Me.Controls.Count
If Cont.Name = "CommandButton" & C Then
Me.Controls.Remove ("CommandButton" & C)
End If
Next C
Next Cont