IN VBA无法从工作簿事件处理程序Workbook_BeforeClose或Workbook_Deactivate()调用工作表中的子例程

坦率

我正在制作启用Excel VBA的工作簿(RES项目透视图),具有一个主表/工作表(RES项目表),每行都有一个超链接来打开另一个工作簿(0520-077-LACOFD-FJF-log.xlsm)Sheet1(项目日志),也启用了VBA。带有Sheet1(Project Log)workbook(.. log.xlsm填满辅助表时,我希望其中一些更改在主表(RES Project Sheet)中进行更新

更新子例程UpdateMainProjectTableSheet1(Project Log)中从Worksheet_changed事件调用时,它可以工作,但是当我尝试从工作簿事件Workbook_BeforeClose(取消布尔值)Workbook_Deactivate()调用更新子例程时,出现编译错误“未定义子或函数”。弄清楚这是一个范围错误,我也尝试命名子程序Sheet1.UpdateMainProjectTable,但是随后出现“运行时错误1004 Application Defined或Object Defined Error”。

下面是工作簿中使用的事件处理程序的四个示例。我尝试了每个,尝试调用UpdateMainProjectTable时它们都产生了错误在前两个ex中,它们仅供参考。此外,我还提供了项目结构的图片以及Referene的错误。

下面的两个子例程在Woorkbook中,因此我在Sheet1前面加上前缀。当他们都尝试调用Sheet1.UpdateMainProjectTable时,都收到“运行时错误1004 Application Defined或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 

但是我得到“未定义编译错误子或功能”下面是我在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使用错误的工作簿名称(活动的工作簿之一)调用。我不知道在其代码中还可能存在哪些其他引用。

由于还有其他一些功能的调用(GetMatchRowNumberMakeLogEntry)这些程序也必须从类似的观点分析了点。

现在,我建议您尝试通过以下方式调试此事件中的呼叫:

  1. 更改ActiveWorkbookThisWorkbook所建议的;

  2. 在特定的行上放置一个断点,然后按F8键逐行运行代码,在停用后代码停止时,看看它在哪一行引发错误...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章