IN VBA 无法从工作簿事件处理程序 Workbook_BeforeClose 或 Workbook_Deactivate() 调用 Sheet 中的子例程
IN VBA unable to call subroutine in Sheet from Workbook event handlers Workbook_BeforeClose or Workbook_Deactivate()
我正在制作一个 Excel VBA 启用 工作簿(RES 项目视角) 有一个主要的 table/sheet (RES 项目 Sheet) 其中每一行都有一个超链接,用于打开另一个 工作簿(0520-077-LACOFD-FJF-log.xlsm) 与 Sheet1(项目日志) 也启用了 VBA。
当 workbook(..log.xlsm) with Sheet1(Project Log) 辅助 table 是填写完毕后,我希望在主要 table (RES 项目 Sheet) 中更新其中的一些更改。
更新子程序 UpdateMainProjectTable 在 Sheet1(Project Log) 中。它在从 Worksheet_changed 事件调用时起作用,但是当我尝试从工作簿事件 Workbook_BeforeClose(Cancel As Boolean) 或 [=40= 调用更新子例程时]Workbook_Deactivate(),我得到编译错误"Sub or Function not defined"。
弄清楚这是一个范围错误我也尝试命名子例程 Sheet1.UpdateMainProjectTable,但后来我得到 "runtime error 1004 Application Defined or object defined error".
以下是工作簿中使用的事件处理程序的四个示例。我尝试了每一个,但在尝试调用 UpdateMainProjectTable 时,它们都产生了错误。前两个ex放在一起仅供参考。我还附上了项目结构的图片和参考错误。
下面的两个子程序在Woorkbook里,所以我加前缀Sheet1。当他们尝试调用 Sheet1.UpdateMainProjectTable 时,我收到了 "runtime error 1004 Application Defined or object defined error"。
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 时,我收到了编译错误 "Sub or Function not defined"。
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
但我得到 "Compile Error Sub or Funtion not defined"。
下面是我在 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
希望对您有所帮助!
确保你的潜艇是 Public
:
Public Sub UpdateMainProjectTable()
End Sub
然后 Call
这个子只做:
With Sheet1
Call UpdateMainProjectTable
End With
所以你的代码应该如下:
Private Sub Workbook_Deactivate()
Application.EnableEvents = False
With Sheet1
Call UpdateMainProjectTable
End With
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
为了从 sheet 模块调用 Sub
/Function
,它不能是 Private
并且你必须显式调用它。
Sheet1.UpdateMainProjectTable
如果你的程序不是Private
并且存在于Sheet1
,问题应该在被调用的Sub
内部(我认为可能性较小)。
我觉得有必要再强调一下,Sheet1
不是sheet名称!是sheet模块名称。我的意思是,在 VBE 中查看 sheet 模块时,您会看到类似这样的内容:Sheet1 (Your sheet name)
。如果 Sheet1
是括号之间的名称,那将是错误的...除非两者相同。
已编辑:我(现在)可以看到你的潜艇。讨论 Workbook_Deactivate
事件调用:
fileName = ActiveWorkbook.Name
没有同样的意义,因为停用后,另一个工作簿处于活动状态。因此,尝试使用 fileName = ThisWorkbook.Name
代替。对 Workbooks.Open(ActiveWorkbook.Path & ...
执行相同操作,将其转换为 Workbooks.Open(ThisWorkbook.Path & ...
.
最好也 post CheckIfWBOpen
函数代码,或者至少检查其代码中是否不存在类似的东西。
ExtractProjectIDFromFilename
使用错误的工作簿名称(活动工作簿名称)调用。我不知道它的代码中还可能存在哪些其他引用。
由于还有一些其他函数调用(GetMatchRowNumber
,MakeLogEntry
)这些程序也必须从类似的角度分析。
现在,我建议您尝试通过以下方式调试此事件中的调用:
按照建议将ActiveWorkbook
改为ThisWorkbook
;
在特定行打个断点,然后按F8逐行运行代码,停用后代码停止,看看在哪一行引发错误.. .
我正在制作一个 Excel VBA 启用 工作簿(RES 项目视角) 有一个主要的 table/sheet (RES 项目 Sheet) 其中每一行都有一个超链接,用于打开另一个 工作簿(0520-077-LACOFD-FJF-log.xlsm) 与 Sheet1(项目日志) 也启用了 VBA。 当 workbook(..log.xlsm) with Sheet1(Project Log) 辅助 table 是填写完毕后,我希望在主要 table (RES 项目 Sheet) 中更新其中的一些更改。
更新子程序 UpdateMainProjectTable 在 Sheet1(Project Log) 中。它在从 Worksheet_changed 事件调用时起作用,但是当我尝试从工作簿事件 Workbook_BeforeClose(Cancel As Boolean) 或 [=40= 调用更新子例程时]Workbook_Deactivate(),我得到编译错误"Sub or Function not defined"。 弄清楚这是一个范围错误我也尝试命名子例程 Sheet1.UpdateMainProjectTable,但后来我得到 "runtime error 1004 Application Defined or object defined error".
以下是工作簿中使用的事件处理程序的四个示例。我尝试了每一个,但在尝试调用 UpdateMainProjectTable 时,它们都产生了错误。前两个ex放在一起仅供参考。我还附上了项目结构的图片和参考错误。
下面的两个子程序在Woorkbook里,所以我加前缀Sheet1。当他们尝试调用 Sheet1.UpdateMainProjectTable 时,我收到了 "runtime error 1004 Application Defined or object defined error"。
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 时,我收到了编译错误 "Sub or Function not defined"。
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
但我得到 "Compile Error Sub or Funtion not defined"。 下面是我在 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
希望对您有所帮助!
确保你的潜艇是 Public
:
Public Sub UpdateMainProjectTable()
End Sub
然后 Call
这个子只做:
With Sheet1
Call UpdateMainProjectTable
End With
所以你的代码应该如下:
Private Sub Workbook_Deactivate()
Application.EnableEvents = False
With Sheet1
Call UpdateMainProjectTable
End With
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
为了从 sheet 模块调用 Sub
/Function
,它不能是 Private
并且你必须显式调用它。
Sheet1.UpdateMainProjectTable
如果你的程序不是Private
并且存在于Sheet1
,问题应该在被调用的Sub
内部(我认为可能性较小)。
我觉得有必要再强调一下,Sheet1
不是sheet名称!是sheet模块名称。我的意思是,在 VBE 中查看 sheet 模块时,您会看到类似这样的内容:Sheet1 (Your sheet name)
。如果 Sheet1
是括号之间的名称,那将是错误的...除非两者相同。
已编辑:我(现在)可以看到你的潜艇。讨论 Workbook_Deactivate
事件调用:
fileName = ActiveWorkbook.Name
没有同样的意义,因为停用后,另一个工作簿处于活动状态。因此,尝试使用 fileName = ThisWorkbook.Name
代替。对 Workbooks.Open(ActiveWorkbook.Path & ...
执行相同操作,将其转换为 Workbooks.Open(ThisWorkbook.Path & ...
.
最好也 post CheckIfWBOpen
函数代码,或者至少检查其代码中是否不存在类似的东西。
ExtractProjectIDFromFilename
使用错误的工作簿名称(活动工作簿名称)调用。我不知道它的代码中还可能存在哪些其他引用。
由于还有一些其他函数调用(GetMatchRowNumber
,MakeLogEntry
)这些程序也必须从类似的角度分析。
现在,我建议您尝试通过以下方式调试此事件中的调用:
按照建议将
ActiveWorkbook
改为ThisWorkbook
;在特定行打个断点,然后按F8逐行运行代码,停用后代码停止,看看在哪一行引发错误.. .