我有一个我在工作簿关闭时调用的宏。它在单独的工作表上检查两个表中的列,并根据它找到的内容分配行号。
Worksheet_Change
处理程序位于具有Projects
范围的工作表上。 Database
范围位于同一工作簿中的另一个工作表中。
每当我在其他地方调用宏时,它会产生错误或导致excel被部分冻结的常见错误(任何人都知道这到底是什么?!?!?!)。
无论如何,我放弃之前的最后一招是将宏更改为工作表更改事件,我想知道是否可以获得一些帮助来创建它。
原始宏:
Sub FindRow()
'This module verifies row numbers in the database by matching them to the opportunities in the Projects
'worksheet. It then assigns row numbers in the Projects worksheet.
Application.ScreenUpdating = False
Dim LastRow As Long
LastRow = Application.ThisWorkbook.Sheets("Projects").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim rng As Range
Dim foundRng As Range
For Each rng In Sheets("Projects").Range("B2:B" & LastRow)
Set foundRng = Sheets("Database").Range("C:C").Find(rng, LookIn:=xlValues, lookat:=xlWhole)
If Not foundRng Is Nothing Then
rng.Offset(0, -1) = foundRng.Row
End If
Next rng
Application.ScreenUpdating = True
End Sub
我建议的改变:
Public Sub Worksheet_Change(ByVal Target As Range)
Dim Records As Range
Set Records = Range("Records")
If Not Application.Intersect(Records, Range(Target.Address)) Is Nothing Then
Application.ScreenUpdating = False
Dim LastRow As Long
LastRow = Application.ThisWorkbook.Sheets("Projects").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim rng As Range
Dim foundRng As Range
For Each rng In Sheets("Projects").Range("B2:B" & LastRow)
Set foundRng = Sheets("Database").Range("C:C").Find(rng, LookIn:=xlValues, lookat:=xlWhole)
If Not foundRng Is Nothing Then
rng.Offset(0, -1) = foundRng.Row
End If
Next rng
Application.ScreenUpdating = True
End If
End Sub
但是,我在定义变量LastRow
的行上一直收到错误
我得到了一个应用程序定义的错误,即使之前已经正确定义了所有错误。
提前致谢。
答案 0 :(得分:3)
Worksheet_Change
个句柄位于Projects
范围的工作表上。数据库范围位于同一工作簿中的另一个工作表上。 - Remi 1分钟前
这意味着rng
表单上还有Projects
:
For Each rng In Sheets("Projects").Range("B2:B" & LastRow)
(BTW Me.Range("B2:B" & LastRow)
在这里不那么模棱两可了)
您正在Worksheet_Change
工作表上处理Projects
事件,只要Projects
工作表上的单元格值发生更改,Excel就会触发该事件。然后在该处理程序中,你这样做:
rng.Offset(0, -1) = foundRng.Row
rng
工作表上的Projects
是一个范围,您正在进行工作表更改的递归循环,而 可能会导致您的代码崩溃。
当您在处理工作表更改时更改工作表时,您需要告诉Excel“它没关系,我得到了这个”,阻止它每次重新触发Worksheet.Change
事件:
Application.EnableEvents = False
'...code...
Application.EnableEvents = True
此外,当你切换Application.ScreenUpdating = False
时,你告诉Excel“在我这么说之前不要重新粉红” - 在很多情况下可以大大加快速度,但这也意味着你需要如果发生了不好的事情,请手动将其切换回来。
您可以通过实现错误处理程序来避免这种情况 - 这是原则:
Sub DoSomething()
On Error GoTo CleanFail
Application.EnableEvents = False
Application.ScreenUpdating = False
'...code...
CleanExit:
Application.EnableEvents = True
Application.ScreenUpdating = True
Exit Sub
CleanFail:
Debug.Print Err.Description
Stop
Resume CleanExit
Resume 'F8 takes you to the error-throwing statement
End Sub
答案 1 :(得分:0)
您尚未指出哪个工作表是包含worksheet_change事件的活动工作表。
无论如何,这是一个代码,用于查找B列表“Projects”
中的最后一行 Dim LastRow As Long, sh As Worksheet
Set sh = Sheets("Projects")
LastRow = sh.Cells(sh.Rows.Count, "B").End(xlUp).Row
MsgBox LastRow & " is the last row in Column B Sheet Projects!"