如何在列表中捕获新行添加?

时间:2011-12-28 16:52:14

标签: excel list events

每当用户在列表中添加新行(Worksheet.ListObjects()返回该实例的列表的类型)时,我想在Excel 10工作表中执行VBA事件处理程序,例如通过在列表的最后一行下输入数据(这会通过向列表中添加新行来扩展列表)。

我该怎么做?除其他外,我想为新行的特定单元格设置默认值。

我目前的想法是处理Worksheet_Change,并检查Target参数是否在我感兴趣的.Range的{​​{1}}范围内。

但是,如何判断用户是否正在创建一个包含他/她的单元格更改的新行,并将其与列表中现有单元格的编辑区分开来?

我可能在这里有点愚蠢。我希望有一个我可以陷阱的列表事件,但我找不到任何。

1 个答案:

答案 0 :(得分:3)

我认为你是对的,ListObject没有事件。使用Worksheet_Change似乎是正确的方法。要检测新行与现有行编辑,您需要使用自己的方法。

我建议跟踪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级别的事件,因此所有工作表只需要一个。 (添加到工作簿模块)

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的名称的情况。这留给读者练习