Код для удаления нескольких строк, выбранных в ListBox (VBA)

#excel #vba #listbox #userform

#excel #vba #listbox #пользовательская форма

Вопрос:

В настоящее время я нахожусь в проекте, где я застрял, написав код для упомянутого ниже действия.

Я создал пользовательскую форму со списком множественного выбора и командной кнопкой

a) ListBox заполняет элементы из источника таблицы двумя столбцами.

 Zone    Region
North   N1
North   N2
North   N3
North   N4
South   S1
South   S2
South   S3
South   S4
East    E1
East    E2
  

b) Командная кнопка предназначена для удаления элементов, выбранных в listbox.

Теперь, как только я нажимаю кнопку команды удаления, выбранные строки должны быть удалены в исходном источнике таблицы.

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что даже когда я выбираю 2 или более строк в listbox, удаляется только последняя выбранная строка.

 Private Sub Cmd_Del_Click()
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Worksheets("Sheet1")
    Dim i As Long


    For i = Me.LB_ZoneRegion.ListCount - 1 To 0 Step -1
        If Me.LB_ZoneRegion.Selected(i) = True Then
            sh.Range("A" amp; i   2 amp; ":B" amp; i   2).Select
            Selection.Delete
        End If
    Next i
    Call UserForm_Initialize
End Sub

Private Sub UserForm_Initialize()
    On Error Resume Next
    With Me.LB_ZoneRegion
        .Clear
        .ColumnCount = 2
        .ColumnHeads = True
        .ColumnWidths = "40;50"
        .RowSource = "ZoneRegion"
        .MultiSelect = fmMultiSelectMulti
    End With
End Sub
  

Нажмите на ссылку ниже, чтобы загрузить рабочий файл.
https://drive.google.com/open?id=1P5wiW6WVFAVQBgixPuA7gqyacR1aktvi

Пожалуйста, помогите мне в этом отношении.

Комментарии:

1. Вы пробовали пошагово просматривать свой код с помощью F8 клавиатуры и следить за своим Me.LB_ZoneRegion.Selected(i) значением на каждой итерации вашего цикла в окне Locals VBE? Пройдясь по коду, вы также можете проверить, что ваш код функционирует должным образом (например, цикл не завершается раньше, чем ожидалось … и т.д.).

Ответ №1:

Использование Union для предотвращения повторных удалений

Используя Union функцию, вы можете добавить все удаляемые строки в объект range (например, DelRng ) и, наконец, удалить их с помощью одной строки кода DelRng.Delete .

Пример кода, близкий к OP

 Private Sub Cmd_Del_Click()
    Dim sh As Worksheet
    Dim DelRng As Range
    Set sh = ThisWorkbook.Worksheets("Sheet1")
    Dim i As Long
    For i = 0 to Me.LB_ZoneRegion.ListCount - 1    ' no more need to loop backwards
        If Me.LB_ZoneRegion.Selected(i) = True Then
            If DelRng Is Nothing Then
                Set DelRng = sh.Range("A" amp; i   2 amp; ":B" amp; i   2)
            Else
                Set DelRng = Union(DelRng, sh.Range("A" amp; i   2 amp; ":B" amp; i   2))
            End If
        End If
    Next i
    Application.ScreenUpdating = False
    If Not DelRng Is Nothing Then DelRng.Delete    ' delete chosen rows (if any)
    Application.ScreenUpdating = True


End Sub
  

Примечание

Вы также должны предусмотреть случай, когда пользователь удаляет весь именованный диапазон.