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

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

我怎么做?除此之外,我想为新行的特定单元格设置默认值.

我目前的想法是处理Worksheet_Change,并检查Target参数是否在我感兴趣的ListObject的.Range中.

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

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

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

我建议跟踪ListOjects中的行数,以便检测它们何时发生变化.为此,请尝试为每个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的名称的情况.这留给读者练习

点赞