2015-01-06 2 views
9

У меня есть Excel User с динамически добавленными флажками. Добавить флажки рано с кодом, который выглядит следующим образом:Удалить динамически добавленные элементы управления из Userform

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 

Но я получаю следующее сообщение об ошибке: Error MEssage

любая помощь будет принята с благодарностью.

+0

одна из проблем здесь может быть paranthesese в «(» Галочка «& J)» –

+1

проверка на Wich J он терпит неудачу и убедитесь, что это флажок, добавленный во время выполнения, а НЕ в режиме разработки. –

+0

Оглядываясь назад, то, что, вероятно, исправил мой код, не был проверкой, но выход на тот момент, когда он нашел правильный. Вероятно, @PatrickLepelletier прав, это, вероятно, проверка неправильного флажка. При этом, приведенный ниже код Криса должен исправить эту проблему в любом случае. – ale10ander

ответ

12

Лучшим подходом может быть отслеживать управление вы создаете (например, в коллекции), и использовать его чтобы удалить их.

Таким образом, ваш код не привязан к формату имени и может применяться и к другим типам управления.

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 
+1

Могу также изменить переменную * chkbox * name. +1 для прохладного использования коллекции. – L42

+1

Thx @ L42. Да, я бы использовал обобщенное имя.Просто сохранил его, чтобы сделать его более ясным для OP, как это относится к его исходному коду. –

+0

Я ценю предложение! В этом конкретном приложении мне захотелось удалить флажки, созданные во время выполнения (и, следовательно, имело эту конкретную схему именования), оставив при этом все остальные элементы управления. Но вы правы, это чище и более общий код. +1 – ale10ander

1

Добавление проверки для управления, казалось, исправить это. Не совсем уверен, почему, но это работает.

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 
+2

Что это за цикл внутри цикла? –

+0

Внутренний цикл проверяет количество каждого элемента управления. Во внешнем цикле я получил контроль над A, но я не уверен, что он контролирует 1. Поэтому я проверяю каждое число, пока не найду нужный номер. – ale10ander

+0

Это не проверка контроля, которая зафиксировала это, а скорее выход - когда я нахожу то, что ищу, я перестаю смотреть. Так получилось, что мои флажки были проверены раньше всего. Принятый ответ более стабилен; он не полагается на удачу :) – ale10ander

1

Предполагая, что нет Othe названий элементов управления, начиная с «галочкой»,

For Each cont In Me.Controls 
    If InStr(cont.Name, "Checkbox") = 1 Then 
     Me.Controls.Remove cont.Name 
    End If 
Next cont 
+0

Хороший подход, очень простой, но эффективный. – JCO9

2

Если вы уже знаете название элементов управления, тип и сколько, почему двойной цикл?

Обратите внимание, что элементы управления, созданные только во время выполнения, могут быть удалены.

'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 
0

я переписал оригинальный код, используя командные кнопки, а просто добавил„Me.Controls.Count“, а не„NumControls“и определенный «Конт» в качестве элемента управления. Кажется, это работает для меня. Пожалуйста, дайте мне знать, если это работает для вас:

->

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