确定在Excel VBA中插入或删除行/单元格的时间

我试图找出在Worksheet_Change事件中如何确定何时在Excel中使用VBA插入或删除行(或列),并在此处查看主题。 但是,在那里给出的build议答案并没有完全捕获在工作表上插入或删除一行时的所有实例,包括:

  1. 虽然它们捕获插入或删除整行行的实例,但它们不会捕获仅插入或删除一组单元格的实例,从而将单元格向下或向上移动。

  2. 当它们捕获在USEDRANGE中插入或删除的行的实例时,它们不会捕获您在所使用范围之外插入的实例(例如,在input数据的地方插入一行)。

鉴于上述说法,我寻找更多的select,找不到任何。 然后,我想出了自己的解决scheme,我在这里帮助别人。 我也希望同时得到有关任何缺陷或改进领域的反馈意见。

下面的Excel VBA代码将确定用户是否已经插入或删除整个行或一组单元格(向上或向下移动单元格)全部在使用的范围之内或之外。

这里的代码(也可以转换为列):

Private Sub Worksheet_SelectionChange(ByVal Target As Range) Cells(Target.Row + Target.Rows.Count, Target.Item(1, 1).Column).ID = Target.Address End Sub Private Sub Worksheet_Change(ByVal Target As Range) If Target.Item(1, 1).ID <> "" Then MsgBox "deleted row" Else MsgBox "inserted row" End If Target.Item(1, 1).ID = "" Cells(Target.Row + Target.Rows.Count, Target.Item(1, 1).Column).ID = Target.Address End Sub 

实际上它非常简单,并使用单元格标记来跟踪用户可以使用哪些操作来确定是否发生了插入或删除操作。

“等待?!” 你可能会说。 “有一种方法来标记细胞?” 或者…“什么是细胞标记”。

那么确实没有一个单元格的“标签”属性,但你可以改造“Cell.ID”属性,并将其用作单元格的标签。 将Excel文件保存为networking表单时,将使用“Cell.ID”属性的初始意图,但如果您不打算创buildnetworking表单,它也可以作为标记使用。 唯一的缺点是在closures并保存文件时,无法用工作簿保存它的值。 但是,这没关系,因为无论如何你都不需要保存标签值。

无论如何,我认为它运作良好。 但是,请让我知道,如果你看到任何改善或缺陷的地方。

只有问题,我可以想到,如果你点击周围,它不断地标记的细胞,留下了大量的垃圾躺在周围,如果你最终没有改变一个单元格。 但是,closures工作簿时只会在打开文件时才会保存。

好的,我回来了。 仍在testing,但这是我迄今为止的状态。 它变得更加复杂,因为你必须跟踪一个额外的标签和清理后自己。 跟踪Excel对标记的单元格的作用(是否向下移动,向上移动等等)。 一旦这种模式被发现并完全被困住,那么我认为这应该起作用。 手指交叉。

 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Call TagCellManager(Target) End Sub Private Sub Worksheet_Change(ByVal Target As Range) Dim CurCel As Range, CurRow As Range Dim TagCel As Range, TagRow As Range Dim NxtCel As Range, NxtRow As Range Set CurCel = Target.Item(1, 1) Set CurRow = Cells(CurCel.Row, 1) Set TagCel = Cells(CurCel.Row + Target.Rows.Count, CurCel.Column) Set TagRow = Cells(CurCel.Row + Target.Rows.Count, 1) Set NxtCel = TagCel.Offset(Target.Rows.Count, 0) Set NxtRow = TagRow.Offset(Target.Rows.Count, 0) If TagCel.ID <> "" And TagRow.ID <> "" Then 'ignore me. i'm entering data ElseIf NxtCel.ID <> "" Or NxtRow.ID <> "" Then MsgBox "row inserted" Set Target = Range(NxtCel.ID) Call TagCellManager(Target) ElseIf CurCel.ID <> "" Or CurRow.ID <> "" Then MsgBox "row deleted" Set Target = Range(CurCel.ID) Call TagCellManager(Target) End If End Sub Sub TagCellManager(Target As Range) Dim CurCel As Range, CurRow As Range Dim TagCel As Range, TagRow As Range Dim NxtCel As Range, NxtRow As Range Set CurCel = Target.Item(1, 1) Set CurRow = Cells(CurCel.Row, 1) Set TagCel = Cells(CurCel.Row + Target.Rows.Count, CurCel.Column) Set TagRow = Cells(CurCel.Row + Target.Rows.Count, 1) Set NxtCel = TagCel.Offset(Target.Rows.Count, 0) Set NxtRow = TagRow.Offset(Target.Rows.Count, 0) CurCel.ID = "" CurRow.ID = "" TagCel.ID = Target.Address TagRow.ID = Target.Address NxtCel.ID = "" NxtRow.ID = "" End Sub