确定用户是添加还是删除行

thi*_*one 20 excel vba excel-vba

我有一个VBA宏来验证用户输入的数据(我没有故意使用数据验证/条件格式).

我正在使用Worksheet_Change事件来触发代码,我现在遇到的问题是,当有行更改时.我不知道它是否是删除/插入行.

无论如何要区分那两个?

bre*_*tdj 17

您可以定义范围名称,例如 RowMarker =$A$1000

然后,您的更改事件上的此代码将存储此标记相对于其先前位置的位置,并报告任何更改(然后存储新位置)

Private Sub Worksheet_Change(ByVal Target As Range)
    Static lngRow As Long
    Dim rng1 As Range
    Set rng1 = ThisWorkbook.Names("RowMarker").RefersToRange
    If lngRow = 0 Then
    lngRow = rng1.Row
        Exit Sub
    End If
    If rng1.Row = lngRow Then Exit Sub
    If rng1.Row < lngRow Then
        MsgBox lngRow - rng1.Row & " rows removed"
    Else
        MsgBox rng1.Row - lngRow & " rows added"
    End If
    lngRow = rng1.Row
End Sub
Run Code Online (Sandbox Code Playgroud)

  • fwiw我使用类似的非VBA方法来标记用户已经改变了一个coporate模板'= IF(ROW(538:538)= 538,"ok","行完整性!")'如果用户导致行,将标记该行538 [模型的底部]移动.你可以用'ROW(538:538)-538'来监控你的文件,它应该是0表示没有变化,1表示单行插入,-10表示10行删除等 (5认同)
  • @brettdj知道这肯定是一个迟到的答案,但我知道你仍然在这个网站上活跃,所以这里.你在哪里初始化"lngRow"?或者就此而言使用你必须为Sub提供的参数,目标作为范围?这看起来像是我刚刚解决的问题的一个巧妙的解决方案.这似乎是一种常见的做法,所以谷歌搜索它会得到这样的代码结果,而我需要一个描述. (2认同)

Rea*_*idy 5

试试这个代码:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim lNewRowCount As Long

    ActiveSheet.UsedRange
    lNewRowCount = ActiveSheet.UsedRange.Rows.Count

    If lOldRowCount = lNewRowCount Then
    ElseIf lOldRowCount > lNewRowCount Then
        MsgBox ("Row Deleted")
        lOldRowCount = lNewRowCount
    ElseIf lOldRowCount < lNewRowCount Then
        MsgBox ("Row Inserted")
        lOldRowCount = lNewRowCount
    End If

End Sub
Run Code Online (Sandbox Code Playgroud)

还要在ThisWorkBook模块中添加它:

Private Sub Workbook_Open()
    ActiveSheet.UsedRange
    lOldRowCount = ActiveSheet.UsedRange.Rows.Count
End Sub
Run Code Online (Sandbox Code Playgroud)

然后在其自己的模块中:

Public lOldRowCount As Long
Run Code Online (Sandbox Code Playgroud)

该代码假定您在第1行中有数据。请注意,第一次运行它时,您会得到错误的结果,这是因为该代码需要将lRowCount设置为正确的变量。一旦完成,从此以后就可以了。

如果您不想使用Public变量和工作表打开事件,则可以在工作表上的某个位置使用命名范围,并在其中存储行数(lRowCount)。

  • 您的意思是说效果不是很好? (3认同)

小智 5

经过一番搜索后决定自己解决。在工作表模块(例如 VBA 编辑器中 Microsoft Excel 对象下的 Sheet1)中插入以下内容:

Private usedRowsCount As Long 'use private to limit access to var outside of sheet

'Because select occurs before change we can record the current usable row count
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  usedRowsCount = Target.Worksheet.UsedRange.rows.count 'record current row count for row event detection
End Sub

'once row count recorded at selection we can compare the used row count after change occurs
'with the Target.Address we can also detect which row has been added or removed if you need to do further mods on that row
Private Sub Worksheet_Change(ByVal Target As Range)
  If usedRowsCount < Target.Worksheet.UsedRange.rows.count Then
    Debug.Print "Row Added: ", Target.Address
  ElseIf usedRowsCount > Target.Worksheet.UsedRange.rows.count Then
    Debug.Print "Row deleted: ", Target.Address
  End If
End Sub
Run Code Online (Sandbox Code Playgroud)