Список ссылок и листы в Excel для удаления - VBA - PullRequest
0 голосов
/ 03 октября 2018

Я создаю список в Excel с VBA пользовательской формы.Его значения получены из листа в Excel.Как я могу удалить значения в листе «база данных» при удалении элемента списка ящиков?пожалуйста, помогите мне.

Private Sub UserForm_Initialize()
Dim ws      As Worksheet
Dim rng     As Range

Dim MyArray 
Set ws = Sheets("Database")

Set rng = ws.Range("K2:L" & ws.Range("K" & ws.Rows.Count).End(xlUp).Row)

With Me.ListBox1
.Clear
.ColumnHeads = False
.ColumnCount = rng.Columns.Count

 MyArray = rng

.List = MyArray

.ColumnWidths = "90;90"
.TopIndex = 0
End With
End Sub

Private Sub CommandButton2_Click()
For lItem = Me.ListBox1.ListCount - 1 To 0 Step -1
    If ListBox1.Selected(lItem) Then
        ListBox1.RemoveItem lItem
        If Me.ListBox1.MultiSelect = fmMultiSelectSingle Then
            Exit For
        End If
    End If
Next
End Sub

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Как удалить значения на листе «база данных»?

Когда вы назначаете элементы базы данных с помощью метода массива (не используя ControlSource), вы хотите знать, каксинхронизировать элементы списка со своей базой данных после удаления вручную.

Подход A) - Запишите все Listbox1.List

Если вам нужно зеркальное отображение элементов списка после цикла For - Next, выможно просто записать эти элементы обратно в заданный диапазон (конечно, вы также должны очистить «лишние строки») через следующий один вкладыш

    rng.Resize(Me.ListBox1.ListCount, 2) = Me.ListBox1.List

Вместо дублирования объявления диапазона данныхв CommandButton2_Click я бы предложил объявить это ОДИН РАЗ в главе объявления модуля кода Userform (и опустить это в Userform_Initialize):

Таким образом, полныйкод будет следующим:

Дополнительные примечания по комментарию

Вставьте эти две строки кода в top вашего модуля кода UserForm (и до любых процедур).

Option Explicit настоятельно рекомендуется в любом коде принудительно объявлять типы переменных (но вы не можете использовать этот оператор в Sub, как вы это сделали).Объявление Dim rng As Range ВНЕ других процедур (то есть сверху) позволяет любой процедуре в этом кодовом модуле знать переменную rng.

Option Explicit               ' declaration head of the UserForm module
Dim rng as Range              ' ONE database declaration only!
                              ' << OUTSIDE of following procedures 
' << Start of regular procedures                              
Private Sub UserForm_Initialize()
Dim ws      As Worksheet
' Dim rng   As Range    ' << not needed here, see top declaration
Dim MyArray
Set ws = Sheets("Database")
Set rng = ws.Range("K2:L" & ws.Range("K" & ws.Rows.Count).End(xlUp).Row)
With Me.ListBox1
    .Clear
    .ColumnHeads = False
    .ColumnCount = rng.Columns.Count

     MyArray = rng

    .List = MyArray
    .ColumnWidths = "90;90"
    .TopIndex = 0
End With
End Sub

Private Sub CommandButton3_Click()   
Dim lItem&
For lItem = Me.ListBox1.ListCount - 1 To 0 Step -1
    If ListBox1.Selected(lItem) Then
        ListBox1.RemoveItem lItem           ' remove item from listbox
        If Me.ListBox1.MultiSelect = fmMultiSelectSingle Then
            Exit For
        End If
    End If
Next

rng.Offset(Me.ListBox1.ListCount, 0).Resize(rng.Rows.Count, 2) = "" ' clear rows
rng.Resize(Me.ListBox1.ListCount, 2) = Me.ListBox1.List             ' write list back

End Sub

Примечание если строки физически не удаляются, результирующие элементы списка в двух целевых столбцах K:L сдвигаются только вверх (подход B также позволяет удалять целые строки) .

Подход B) - Справочная процедура в основном цикле

Использование того же объявления диапазона данных в заголовке объявления пользовательской формы ►, как показано выше (т. Е. ВНЕ процедур как Subs илиФункции), вы можете использовать справочную процедуру DelData, позволяющую различать два основных случая:

  • [1] Сдвиг удаленных ячеек в вашей базе данных
  • [2] Удалитьвесь ряд

процедура события CommandButton2_Click

Private Sub CommandButton2_Click()
' Purpose: delete items both from database and listbox
Dim lItem&
For lItem = Me.ListBox1.ListCount - 1 To 0 Step -1
    If ListBox1.Selected(lItem) Then
        DelData lItem, True     ' [1] True=delete items and shift up
       'DelData lItem, False    ' [2] False=delete entire row

        ListBox1.RemoveItem lItem           ' remove item from listbox
        If Me.ListBox1.MultiSelect = fmMultiSelectSingle Then
           Exit For                ' do it once in single select case
        End If
    End If
Next
End Sub

процедура помощи DelData

Sub DelData(ByVal indx&, Optional ByVal bShiftUp As Boolean = True)
' Purpose: delete indicated row items in database
' Note:    data set in OP includes header
    If bShiftUp Then    ' [1] bShiftUp = True: delete row items and shift up
       rng.Offset(indx).Resize(1, rng.Columns.Count).Delete xlShiftUp
    Else                ' [2] bShiftUp = False: delete entire row of indicated items
       rng.Offset(indx).Resize(1, rng.Columns.Count).EntireRow.Delete
    End If
End Sub

Примечание к сведению

Рекомендуется пройти квалификационный забегge ссылки, чтобы избежать получения данных из неправильных рабочих книг, поэтому я бы предложил следующее утверждение в вашей UserForm_Initialize процедуре:

Set ws = ThisWorkbook.Worksheets("Database")

Наслаждайтесь: -)

0 голосов
/ 03 октября 2018

Перед удалением элемента из ListBox вам нужно использовать значение, расположенное в ListBox.Selected, чтобы найти и удалить элемент из вашей «базы данных».

Примерно так:

Private Sub CommandButton2_Click()
  For lItem = Me.ListBox1.ListCount - 1 To 0 Step -1
    If ListBox1.Selected(lItem) Then
        DeleteItemFromDatabase ListBox1.Selected(lItem).Value
        ListBox1.RemoveItem lItem
        If Me.ListBox1.MultiSelect = fmMultiSelectSingle Then
          Exit For
        End If
    End If
  Next
End Sub

Тогда ваш Sub DeleteItemFromDatabase(ByVal itemToDelete As [type]) найдет itemToDelete в вашей "базе данных" и удалит его.

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

...