每当用户在列表中添加新行(Worksheet.ListObjects
()返回该实例的列表的类型)时,我想在Excel 10工作表中执行VBA事件处理程序,例如通过在列表的最后一行下输入数据(这会通过向列表中添加新行来扩展列表)。
我该怎么做?除其他外,我想为新行的特定单元格设置默认值。
我目前的想法是处理Worksheet_Change
,并检查Target
参数是否在我感兴趣的.Range
的{{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的名称的情况。这留给读者练习