Как удалить несколько выбранных строк данных из списка, который использует объект списка в качестве источника строк в Excel VBA?

У меня есть пользовательская форма со списком, использующая объект списка в качестве источника строк.

Я хочу выбрать несколько строк данных из списка, удалить соответствующие данные из списка, а затем обновить список.

Private Sub Delete_Click()

'Option Explicit is enabled

    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim myListBox As MSForms.listbox
    Dim i As Long
    
    Set ws = ThisWorkbook.Worksheets("Data")
    Set tbl = ws.ListObjects("Table1")
    Set myListBox = Me.listbox
    
    With myListBox
        For i = .ListCount - 1 To 0 Step -1
            If .Selected(i) Then
                tbl.ListRows(i + 1).Delete
            End If
        Next i
    End With
    
    myListBox.RowSource = ""
    myListBox.RowSource = tbl
End Sub

У меня был код для удаления одной строки. Это для попытки удалить несколько строк.

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

Может попробовать добавить одну переменную... dim rgU as range. rgU используется для сбора всех выбранных строк таблицы на основе выбранного элемента в списке. Затем используйте такую ​​петлю For i = 0 To .ListCount - 1:If .Selected(i) and i<>0 Then If rgU Is Nothing Then Set rgU = tbl.ListRows(i).Range Else Set rgU = Union(rgU, tbl.ListRows(i).Range):next, затем добавьте rgU.delete:ListBox1.RowSource = .Range.Address:end with. Обратите внимание, что источник строки списка использует диапазон tbl.address. Итак, списки начинаются с 1 (это строка 2, поскольку строка 1 является заголовком таблицы), поэтому она нужна and i<>0

karma 10.04.2023 11:20

Спасибо карме! На самом деле это сработало очень хорошо! Я столкнулся с двумя проблемами, которые я пытаюсь понять. Первая ошибка заключается в том, что я получаю ошибку времени выполнения '91' Объектная переменная или переменная блока, не установленная в rgU.Delete. Эта проблема возникает, когда у меня осталась одна строка с данными внутри нее, и я пытаюсь ее удалить. Вторая ошибка возникает, когда я удаляю несколько строк. Он удалит все строки, кроме нижней. Он подталкивает эти данные к вершине. Я просто пытаюсь понять сейчас. Тем не менее, я взял концепцию, если это правильный термин, rgU и сделал код, который также работает примерно так же!

Vantan 11.04.2023 04:23

У меня есть код, который у меня есть в настоящее время, который несколько работает, но я не знаю надлежащего этикета для публикации нового кода или будет ли это теперь отдельным вопросом. Сказав это, вы мне очень помогли. Спасибо, Вантан.

Vantan 11.04.2023 04:28

Я допустил ошибку в этой строке ListBox1.RowSource = .Range.Address. Вот почему он выдает вам ошибку. Пожалуйста, посмотрите на мой ответ ниже. Без rgU вы удаляете строки таблицы одну за другой внутри цикла. С rgU вы собираете/объединяете строку таблицы внутри цикла. Затем после цикла вы сразу удаляете строки в rgU. Спасибо.

karma 11.04.2023 05:07
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
0
4
88
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я допустил ошибку в коде в своем комментарии, а именно в этой строке ListBox1.RowSource = .Range.Address. Должно быть ListBox1.RowSource = tbl.Range.Address. И лучше, если данные листа не активны: ListBox1.RowSource = ws.Name & "!" & tbl.Range.Address

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

Dim ws As Worksheet
Dim tbl As ListObject

Private Sub UserForm_Initialize()
Set ws = ThisWorkbook.Worksheets("Data")
Set tbl = ws.ListObjects("Table1")
    With ListBox1
        .ColumnCount = 3
        .RowSource = ws.Name & "!" & tbl.Range.Address
        .ColumnWidths = "35,35,35"
        .MultiSelect = fmMultiSelectExtended
    End With
End Sub

Private Sub CommandButton1_Click()
Dim rgU As Range: Dim i As Integer
If Not tbl.DataBodyRange Is Nothing Then
    With ListBox1
        For i = 0 To .ListCount - 1
            If .Selected(i) And i <> 0 Then If rgU Is Nothing Then Set rgU = tbl.ListRows(i).Range Else Set rgU = Union(rgU, tbl.ListRows(i).Range)
        Next
        rgU.Delete: .RowSource = ws.Name & "!" & tbl.Range.Address
    End With
End If
End Sub

Источник строки для списка использует адрес таблицы, но в своем комментарии я забыл указать имя листа (который является данными листа) на случай, если данные листа не активны при отображении пользовательской формы. Теперь в приведенном выше коде я включаю имя листа (ws.name).

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

Спасибо карме за помощь. Я смог заставить его работать! Мне просто нужно было отключить свойство заголовка столбца listbox1. Я пытался заставить его работать с включенными заголовками, но это вызывает у меня много проблем. Я предпочитаю внешний вид заголовков столбцов в списке, но у меня проблемы с заголовками. Я получаю две строки с заголовками, являющимися второй строкой. Первая строка показывает по столбцам a,b,c и d. соответственно а, б, в и г. Если вы знаете, почему это так, я хотел бы знать, как последовательно заставить его работать! Если нет спасибо за помощь. Я собираюсь применить это не только к удалению.

Vantan 12.04.2023 03:11

Вы написали: я получаю две строки с заголовками, являющимися второй строкой. Предположим, что в строке 1 у вас есть a, b и c, а в строке 2 у вас есть AAA, BBB и CCC. На мой взгляд, возможно, когда вы создаете таблицу, вы включаете row1. Таким образом, ваши ListObjects ("Table1") начинаются с строки 1 с заголовком a, b, c. Может быть, поэтому в списке отображаются a, b, c и AAA, BBB, CCC. если при создании таблицы вы определяете диапазон, начинающийся со строки 2, то ваши ListObjects ("Table1") начинаются со строки 2, и вы не увидите в списке a, b и c, а AAA, BBB и CCC.

karma 12.04.2023 06:02

Это определенно имеет смысл, поскольку это была и моя мысль! Мне просто нужно выяснить, как заставить его работать правильно. Хотя я сделал так, чтобы информация заголовков помещалась в правильное место, когда включены заголовки столбцов, после этого все становится не так. Я попытаюсь что-нибудь удалить, а потом данные начнут перемещаться в разные места. С учетом сказанного я сделаю все возможное, чтобы это произошло, а если нет, я отправлю вопрос с моим кодом. Спасибо за помощь Карме, Вантан

Vantan 14.04.2023 02:58

Другие вопросы по теме