2011-12-28 1 views
4

Я хочу выполнить обработчик события VBA в листе Excel 10 всякий раз, когда пользователь добавляет новую строку в список (вид списков, который Worksheet.ListObjects() возвращает экземпляры) на этом листе, например, путем ввода данных под последним строка списка (это расширяет список, добавляя новую строку в список).Как уловить новые добавления строк в список?

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

Моя текущая идея состоит в том, чтобы справиться с Worksheet_Change, и проверить, если параметр Target находится в пределах .Range от ListObject Меня интересует.

Однако, как бы мне узнать, если пользователь создает новую строку с изменение его/ее ячейки и отличить это от изменений существующих ячеек в списке?

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

ответ

2

Я думаю, что вы правы, нет событий для ListObject. Использование Worksheet_Change кажется правильным путем. Чтобы обнаружить редактирование New Row vs Existing Row, вам нужно будет запустить свой собственный метод.

Я бы предложил отслеживать количество строк в ListOjects, чтобы определить, когда они меняются. Чтобы сделать это, попробуйте добавить скрытый named range для каждого ListOject для хранения текущего количества строк. Заполните их в файл открытым и проверьте их на Worksheet_Change.

Это добавит или обновить скрытые именованные диапазоны на открытом файле (добавить в рабочую книгу модуля)

Private Sub Workbook_Open() 
    Dim oList As ListObject 
    Dim sh As Worksheet 
    Dim nm As Name 
    Dim strName As String 

    For Each sh In Me.Worksheets 
    For Each oList In sh.ListObjects 
     'oList.ListRows.Count 
     strName = oList.Name & "Rows" 
     Set nm = Nothing 
     On Error Resume Next 
     Set nm = Me.Names(strName) 
     On Error GoTo 0 
     If nm Is Nothing Then 
      Set nm = Me.Names.Add(strName, CStr(oList.ListRows.Count)) 
     Else 
      nm.RefersTo = CStr(oList.ListRows.Count) 
     End If 
     nm.Visible = False 
    Next oList, sh 
End Sub 

Это определит, какой тип изменений было сделано. Я сделал это событием уровня WorkBook, поэтому для всех листов требуется только один. (Добавить в модуль Workbook)

Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range) 
    Dim oList As ListObject 
    Dim nm As Name 
    Dim strName As String 

    For Each oList In sh.ListObjects 
     strName = oList.Name & "Rows" 
     If Not Application.Intersect(Target, oList.DataBodyRange) Is Nothing Then 
      Set nm = Nothing 
      On Error Resume Next 
      Set nm = Me.Names(strName) 
      On Error GoTo 0 
      If nm Is Nothing Then 
       Set nm = Me.Names.Add(strName, CStr(oList.ListRows.Count)) 
       nm.Visible = False 
      End If 
      If oList.ListRows.Count <> Val(Replace(nm.Value, "=", "")) Then 
       nm.RefersTo = CStr(oList.ListRows.Count) 
       MsgBox "List " & oList.Name & " changed" & vbCrLf & "New Line" 
      Else 
       MsgBox "List " & oList.Name & " changed" & vbCrLf & "Existing Line" 
      End If 
     End If 
    Next 
End Sub 

Примечания: это не обрабатывает случай, когда изменяется имя существующего ListObject. Это остается как упражнение для читателя.

+0

Слишком плохо, кажется, не лучше. более компактный способ. Но спасибо. – TheBlastOne

Смежные вопросы