在 Workbook_SheetChange 事件中使用 VBA
Using VBA in the Workbook_SheetChange Event
我正在尝试创建一个日志,记录特定作品sheet(名为 "FORMULAS")中的特定范围 (G2:G103) 何时对其进行了任何更改。这是一本很多人每天多次查看的工作簿,记录对相关范围进行更改的时间,我可以在幕后跟踪,这对我很有帮助。我希望更改日志包含在另一个工作sheet(名为"ActivityLog")中,从 E 列开始,用户名和现在的功能。
到目前为止,我编写的代码没有 return 错误,但根本没有做任何事情。我尝试了 worksheet_change 事件和 workbook_sheetchange 事件,并一直 运行ning 陷入同一个问题:什么也没做。关于我缺少什么以及我是否应该将代码放在 "FORMULAS" 模块或 "ThisWorkbook" 模块中的任何想法?
Application.EnableEvents = False
If Intersect(Target, Range("G2:G103")) Then
With Worksheets("ActivityLog")
Sheets("ActivityLog").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
Sheets("ActivityLog").Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
Application.EnableEvents = True
谢谢!
感谢@Jeeped,以上问题现已得到解答。但是,我 运行 遇到了另一个我决定采用这种方式的问题。由于所讨论的范围相当大,并且宏会在任何时候进行更改时向 ActivityLog sheet 发送重复报告(因为单元格已激活,并且值已更改,我猜这就是它加倍的原因) ,我正在尝试查看是否可以减轻巨大的 activity 日志,如果我真的只想查看是否发生了更改(不一定 发生了多少 更改).我有一个跟踪总变化值的公式单元格,所以我认为这可能会起作用,宏触发一次然后就不再起作用了……有什么想法吗? (这是 sheet 中的私有模块,我正在使用公式查看的单元格所在的位置。)
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("E14")) Is Nothing Then
Call Worksheet_Calculate
End If
Application.EnableEvents = True
End Sub
Sub Worksheet_Calculate()
Static oldval
If Range("E14").Value <> oldval Then
oldval = Range("E14").Value
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
End Sub
谢谢!
我最初对你的代码的评价有点仓促。检查目标是否在 G2:G103 内应该检查 If Not Intersect(Target, Range("G2:G103")) Is Nothing
,而不仅仅是 Intersect
。除此之外,该代码看起来不错。 (With ... End With 是多余的,但这不应该阻止它从 运行ning 开始)
Use a Worksheet_Change event macro in the worksheet code sheet or the Workbook_SheetChange in the ThisWorkbook workbook code sheets. They can both be there doing different things but they should not both be there trying to do the same thing. Pick one or the other from the two offered below.
在公式工作sheet代码sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("G2:G103")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
Application.EnableEvents = True
End Sub
在 ThisWorkBook 工作簿代码中 sheet:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name = "FORMULAS" Then
If Not Intersect(Target, Sh.Range("G2:G103")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
End If
Application.EnableEvents = True
End Sub
不过,.EnableEventws
是否卡在False的问题还是成立的。你有没有 运行 以前的尝试并在中途崩溃?转到 VBE 的即时 Window (Ctrl+G) 并粘贴 Application.EnableEvents = True
,然后按 Enter。如果在前面的代码中途发生崩溃,EnableEvents 可能会卡在 False。
我正在尝试创建一个日志,记录特定作品sheet(名为 "FORMULAS")中的特定范围 (G2:G103) 何时对其进行了任何更改。这是一本很多人每天多次查看的工作簿,记录对相关范围进行更改的时间,我可以在幕后跟踪,这对我很有帮助。我希望更改日志包含在另一个工作sheet(名为"ActivityLog")中,从 E 列开始,用户名和现在的功能。
到目前为止,我编写的代码没有 return 错误,但根本没有做任何事情。我尝试了 worksheet_change 事件和 workbook_sheetchange 事件,并一直 运行ning 陷入同一个问题:什么也没做。关于我缺少什么以及我是否应该将代码放在 "FORMULAS" 模块或 "ThisWorkbook" 模块中的任何想法?
Application.EnableEvents = False
If Intersect(Target, Range("G2:G103")) Then
With Worksheets("ActivityLog")
Sheets("ActivityLog").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
Sheets("ActivityLog").Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
Application.EnableEvents = True
谢谢!
感谢@Jeeped,以上问题现已得到解答。但是,我 运行 遇到了另一个我决定采用这种方式的问题。由于所讨论的范围相当大,并且宏会在任何时候进行更改时向 ActivityLog sheet 发送重复报告(因为单元格已激活,并且值已更改,我猜这就是它加倍的原因) ,我正在尝试查看是否可以减轻巨大的 activity 日志,如果我真的只想查看是否发生了更改(不一定 发生了多少 更改).我有一个跟踪总变化值的公式单元格,所以我认为这可能会起作用,宏触发一次然后就不再起作用了……有什么想法吗? (这是 sheet 中的私有模块,我正在使用公式查看的单元格所在的位置。)
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("E14")) Is Nothing Then
Call Worksheet_Calculate
End If
Application.EnableEvents = True
End Sub
Sub Worksheet_Calculate()
Static oldval
If Range("E14").Value <> oldval Then
oldval = Range("E14").Value
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
End Sub
谢谢!
我最初对你的代码的评价有点仓促。检查目标是否在 G2:G103 内应该检查 If Not Intersect(Target, Range("G2:G103")) Is Nothing
,而不仅仅是 Intersect
。除此之外,该代码看起来不错。 (With ... End With 是多余的,但这不应该阻止它从 运行ning 开始)
Use a Worksheet_Change event macro in the worksheet code sheet or the Workbook_SheetChange in the ThisWorkbook workbook code sheets. They can both be there doing different things but they should not both be there trying to do the same thing. Pick one or the other from the two offered below.
在公式工作sheet代码sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("G2:G103")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
Application.EnableEvents = True
End Sub
在 ThisWorkBook 工作簿代码中 sheet:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
If Sh.Name = "FORMULAS" Then
If Not Intersect(Target, Sh.Range("G2:G103")) Is Nothing Then
Application.EnableEvents = False
With Worksheets("ActivityLog")
.Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = Environ("username")
.Range("E" & Rows.Count).End(xlUp).Offset(0, 1).Value = Format(Now, "MM/dd/yyyy h:mm:ss_ AM/PM")
End With
End If
End If
Application.EnableEvents = True
End Sub
不过,.EnableEventws
是否卡在False的问题还是成立的。你有没有 运行 以前的尝试并在中途崩溃?转到 VBE 的即时 Window (Ctrl+G) 并粘贴 Application.EnableEvents = True
,然后按 Enter。如果在前面的代码中途发生崩溃,EnableEvents 可能会卡在 False。