vba - 在 VBA 中,无法从工作簿事件处理程序 Workbook_BeforeClose 或 Workbook_Deactivate() 调用工作表中的子例程
问题描述
我正在制作一个启用 Excel VBA 的工作簿(RES Project Perspective)有一个主表/工作表(RES Project Sheet),每行都有一个超链接可以打开另一个工作簿(0520-077-LACOFD-FJF-log.xlsm)使用同样启用了 VBA的Sheet1(项目日志) 。当workbook(..log.xlsm ) 和Sheet1(Project Log)填写辅助表时,我希望在主表(RES Project Sheet)中更新其中的一些更改。
更新子例程UpdateMainProjectTable在Sheet1(Project Log)中。它在从 Worksheet_changed 事件调用时起作用,但是当我尝试从工作簿事件Workbook_BeforeClose(Cancel As Boolean)或 Workbook_Deactivate()调用更新子例程时,我收到编译错误“未定义子或函数”。确定它是一个范围错误我也尝试命名子例程Sheet1.UpdateMainProjectTable,但后来我得到“运行时错误 1004 应用程序定义或对象定义错误”。
以下是工作簿中使用的四个事件处理程序示例。我尝试了每一个,他们在尝试调用UpdateMainProjectTable时都产生了一个错误。在前两个ex中,他们只是放在一起,以供参考。我还包括了项目结构的图片和参考的错误。
下面的两个子例程都在工作簿中,所以我在 Sheet1 前面加上前缀。在他们尝试调用Sheet1.UpdateMainProjectTable时,我都收到“运行时错误 1004 应用程序定义或对象定义错误”。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Me.Saved = False Then Me.Save
Application.EnableEvents = False
Sheet1.UpdateMainProjectTable
Application.EnableEvents = True
End Sub
Private Sub Workbook_Deactivate()
Application.EnableEvents = False
Sheet1.UpdateMainProjectTable
Application.EnableEvents = True
End Sub
下面的两个子例程都在 Woorkbook 中,我不给子例程加前缀。在他们尝试调用UpdateMainProjectTable时,我都收到编译错误“未定义子或函数”。
Private Sub Workbook_Deactivate()
Application.EnableEvents = False
UpdateMainProjectTable
Application.EnableEvents = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Me.Saved = False Then Me.Save
Application.EnableEvents = False
UpdateMainProjectTable
Application.EnableEvents = True
End Sub
根据答案的建议,我尝试了这个。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If Me.Saved = False Then Me.Save
Application.EnableEvents = False
With Sheet1
Call UpdateMainProjectTable
End With
Application.EnableEvents = True
End Sub
但我得到“编译错误子或未定义函数”。下面是我在 Sheet1(Project Log) 中的子程序,它被声明为Public。
Public Sub UpdateMainProjectTable() 'This is the Main function to update the main table when the log is updated
'it open's the RES Project table if not open and
Dim fileName As String
Dim projId As String
Dim logEntry As String
Dim waitingNotCleared As Boolean
Dim rowWithMatch As Integer
Dim wbOpenOnEntry As Boolean
Dim wb As Workbook
'gets Projectlog filename-- this filename
fileName = ActiveWorkbook.Name
'check if RES Project Perspective.xlsm is open. If not then open and close later at end of sub
wbOpenOnEntry = CheckIfWBOpen("RES Project Perspective.xlsm")
If wbOpenOnEntry = False Then
Set wb = Workbooks.Open(ActiveWorkbook.Path & "/../../RES Project Perspective.xlsm")
End If
'uses filename to determine projid
projId = ExtractProjectIDFromFilename(fileName)
Debug.Print "projId = ExtractProjectIDFromFilename(fileName) " & projId
'rowWithMatch = FindRowWithProjIDMatch(projId)
rowWithMatch = GetMatchRowNumber(projId)
Debug.Print "rowWithMatch = GetMatchRowNumber(projId) " & rowWithMatch
MakeLogEntry (rowWithMatch)
'check if RES Project Perspective.xlsm is open. If not then open and close later at end of sub
If wbOpenOnEntry = False Then
wb.Close savechanges:=True
End If
End Sub
我希望这有帮助!
解决方案
为了从工作表模块调用Sub
/ ,它不能是并且您必须显式调用它。Function
Private
Sheet1.UpdateMainProjectTable
如果您的程序不Private
存在并且存在于 中Sheet1
,则问题应该在被调用的内部Sub
(我认为可能性较小)。
我觉得有必要还强调一下,Sheet1
不是表名!它是工作表模块名称。我的意思是,在 VBE 中查看您的工作表模块时,您会看到如下内容:Sheet1 (Your sheet name)
. 如果Sheet1
是括号之间的名称,那就错了……除非两者相同。
编辑:我可以看到(现在)你的潜艇。讨论Workbook_Deactivate
事件调用:
fileName = ActiveWorkbook.Name
没有同样的意义,因为停用后,另一个工作簿处于活动状态。因此,请尝试fileName = ThisWorkbook.Name
改用。对 做同样的Workbooks.Open(ActiveWorkbook.Path & ...
事情,将其转换为Workbooks.Open(ThisWorkbook.Path & ...
.
最好也发布CheckIfWBOpen
功能代码,或者至少检查其代码中是否存在类似的东西。
ExtractProjectIDFromFilename
使用错误的工作簿名称(活动工作簿之一)调用。我不知道它的代码中还可能存在哪些其他引用。
由于还有一些其他函数调用(GetMatchRowNumber
, MakeLogEntry
),因此也必须从类似的角度分析这些过程。
现在,我建议您尝试通过以下方式调试此事件中的调用:
ActiveWorkbook
按照ThisWorkbook
建议更改;在特定行上放一个断点,然后按 F8 逐行运行代码,当代码在停用后停止时,看看它在哪一行引发错误...
推荐阅读
- python - Python Tkinter - 由函数创建的对象的名称
- c# - C#字符串配对方法(外部文件)
- android - 在用例的构造函数中注入接口
- c# - 加入在 EntityFramewrok Core 中不起作用
- c++ - sync_queue 类编译错误
- php - AWS SNS 无法在使用 PHP AWS SDK 的实时 ec2 服务器上运行
- r - 如何在R中导入具有不规则空格的文本文件
- python - 在字典中按升序保存每个人名字的平均值
- jquery - Jquery在MVC Razor中定位所有索引ID
- wordpress - 带有上传文件选项的免费 WordPress 表单插件