实例需求:工作表中的表格(ListObject)名称为Table1
,表格列数不确定,需要实现如下功能:
- 当用户完成最后一行最后一列输入之后(如果该单元格为空,则视为输入未完成),表格自动扩展一行
- 扩展行中,第一列填充自动序号,其他列填充NA
- 如果用户双击表格中最后一行的任意单元格,那么删除该行,并相应调整表格单元格范围
效果如下所示。
示例代码如下。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim oTab As ListObject, oListRow As ListRow
Const TAB_NAME As String = "Table1"
If Target.CountLarge = 1 And Len(Target.Cells(1).Value) > 0 Then
Set oTab = Me.ListObjects(TAB_NAME)
With oTab
If Not Application.Intersect(.Range.Columns(.ListColumns.Count), Target) Is Nothing Then
If Target.Offset(1).ListObject Is Nothing Then
Set oListRow = .ListRows.Add
Application.EnableEvents = False
mRow.Range.Value = "NA"
oListRow.Range(1) = .ListRows.Count
Application.EnableEvents = True
End If
End If
End With
End If
End Sub
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim oTab As ListObject
Const TAB_NAME As String = "Table1"
If Target.ListObject.Name = TAB_NAME Then
Set oTab = Target.ListObject
If Target.Offset(1).ListObject Is Nothing Then
Application.EnableEvents = False
oTab.ListRows(oTab.ListRows.Count).Delete
Cancel = True
Application.EnableEvents = True
End If
End If
End Sub
【代码解析】
第1~18行代码为工作表的Change事件,实现扩展表格新增行。
第3行代码定义表格名称。
第4行代码判断发生变化Range(参数Target)为单个单元格,并且单元格内容不为空。
第5行代码获取表格对象。此处并未检查是否存在指定名称的ListObject,因此有可能产出运行时错误。
第7行代码代码判断Target是否位于表格的最后一列,由于表格的总列数不确定,因此需要使用.Range.Columns(.ListColumns.Count)
获取最后一列的对象,其中.ListColumns.Count
为表格的列数。
第8行代码判断Target之下相邻单元格是否在表格中,如果满足条件,说明Target位于表格的最后一行。这个也不是严谨逻辑判断,如果两个表格上下相邻,那么就会出现误判,如果需要严谨判断,那么需要进一步对比表格名称。
第9行代码扩展表格,增加一行。
第10行代码禁止系统事件激活。
第11行代码将新增行中的单元格全部填充为NA。
第12行代码更新第一列单元格内容为自动序号。
第13第行代码恢复允许系统事件激活。
第19~31行代码为工作表的BeforeDoubleClick事件,实现删除最后行。其中与Change事件相同的代码不再赘述。
第22行代码判断Target位于指定名称的表格中。
第26行代码删除表格的最后一行,同时表格范围将自动缩减。
第27行代码取消双击操作。