【问题标题】:Why doesn't VBE.ActiveCodePane.CodeModule work when the VBE (code window) isn't open?当 VBE(代码窗口)未打开时,为什么 VBE.ActiveCodePane.CodeModule 不起作用?
【发布时间】:2015-12-21 07:47:12
【问题描述】:

创建一个运行以下代码的表单。

MsgBox (VBE.ActiveCodePane.CodeModule)

然后出现这条消息。

现在保存、关闭并重新打开数据库,然后看到以下消息:

运行时错误“91”:对象变量或未设置块变量

如果您打开 Visual Basic 编辑器,它会再次运行。即使您关闭了 VBE,它仍然会运行。

但是当您关闭整个应用程序并重新打开它,同时关闭 VBE 时,您会收到错误消息。

为什么?这是怎么回事?

【问题讨论】:

  • 我在Workbook_Open() 处理程序中遇到了问题,下面Bas Verlaat...Activate 解决方案很好地解决了它。奇怪的是,Err 对象在此错误中不可用,因此调试非常奇怪。

标签: vba ms-access


【解决方案1】:

您引用了活动窗格对象。在激活窗格之前不会设置对象。因此,在您打开 VBE 之前,尚未设置对象。关闭 VBE 后,对象仍然存在,因此您仍然可以引用它。

要在不打开 VBE 的情况下获取 ActiveCodepane 对象的句柄,只需激活一个 VBComponent,如下所示:

VBE.ActiveVBProject.VBComponents("Module1").Activate

您可以像这样激活任何 VBComponent。

【讨论】:

    【解决方案2】:

    那么当VBE在第一次打开应用程序时关闭时,没有ActiveCodePane,你可以在加载表单时检查这个:

    If (Application.VBE.ActiveCodePane Is Nothing) Then MsgBox "ActiveCodePane is Nothing"
    

    VBE 存在并且可以使用属性和方法,但没有ActiveCodePane,这就是您收到空引用异常的原因。如果您在之前保存和关闭之前关闭了所有CodePanes,则仅打开VBE 仍会产生错误(除非出于某种原因存在模块)。您必须显式打开 CodePane,以设置“ActiveCodePane”属性。

    这是有道理的。您试图通过 ActiveCodePane 属性访问什么?或许我可以帮忙找到解决办法?

    编辑

    大概,当您开发此表单和相关模块时,您会知道它们的名称,并且可以使用与ActiveCodePane 不同的方法,例如@Bas Verlaat 提到的方法。或者,您可以遍历活动 VBProject 中的每个代码窗格并尝试匹配名称或其他内容:

    Option Compare Database
    Option Explicit
    
    Private vbProj As VBIDE.VBProject
    Private vbComp As VBIDE.VBComponent
    Private vbMod As VBIDE.CodeModule
    
    Private Sub Command0_Click()
    
        Set vbProj = Application.VBE.ActiveVBProject
    
        For Each vbComp In vbProj.VBComponents
            MsgBox vbComp.CodeModule
        Next
    
    End Sub
    

    【讨论】:

    • 我正在尝试获取代码模块名称。我只是觉得有点奇怪,代码在开发过程中运行良好,但在部署到生产环境时会中断,这发生在我身上。
    • 好的。我已经有一段时间没有看过 VBE 的东西了。我会看看我能想出什么。
    • 无论 VBE 或任何 CodePanes 是否打开,我都已更新我的答案以容纳一个短循环以访问 CodePanes/CodeModules。我注意到Application.VBE.CodePanes 实际上只是 open 代码窗格的集合,而不是全部。当 VBE 以前没有打开时,我的编辑中发布的方法有效。
    • 谢谢。这很漂亮。对于未来的读者,请记住添加对 Microsoft Visual Basic for Applications Extensibility 5.3 的引用。
    • 好点,感谢提及参考。如果其中任何一个答案对您有帮助,您是否介意将其中一个标记为答案,以便将来的读者知道什么对您最有帮助?
    【解决方案3】:

    正如 Bas Verlaat 所说,在您打开 VBE 之前,尚未设置对象。

    显然,当用户使用该程序时,VBE 不会打开。仅应在开发和调试时引用 Active Code Pane,而不应在生产中进行。

    例如,以下自定义错误消息非常适合调试,但如果部署到生产环境则会失败。

    ErrorHandler:
        MsgBox "Error " & Err.number & ": " & Err.Description & " in " & _
        VBE.ActiveCodePane.CodeModule, vbOKOnly, "Error"
    

    【讨论】:

      【解决方案4】:

      方法

      由于有时无法避免使用 VBE 功能,所以对我来说一般的解决方案是这样...

      1. 确保初始化/激活相关工作簿 VB 项目(组件)
      2. 确保在打开其他工作簿 VB 项目(组件)后对其进行初始化/激活如果它们的 VBE 属性/代码可能相关在此过程的稍后阶段)

      VbeInit用法

      要做到这一点,可以调用(见下面的代码)

      • VbeInit 在某些事件的开头(例如Workbook_Open() 事件)和
      • VbeInit someOpenedWorkbook 每当打开相关工作簿时(例如使用Workbooks.Open(...)

      示例案例

      它适用于上述更简单的情况。 一个更复杂的情况是,当您依赖工作簿中的工作表CodeName 时,这是非常明显和必要的。例如

      • 如果允许用户重新Name 一些工作表,但 VB 应用程序仍应通过其CodeName
      • 唯一地识别这些工作表
      • 此类工作表(例如用作模板工作表)被复制 (sheet.Copy ...) 到其他工作簿。

      只有当工作表 VBComponent 已被激活(例如通过 myVBComponent.Activate 或在 VBE 中打开包含源工作表的工作簿)时,才会复制工作表 CodeName

      VbeInit 过程

      Procedure VbeInit(Optional wb As Workbook)
      
          With Application.VBE
              Dim pj As VBProject:  For Each pj In .VBProjects
                  'ignore unsaved (=> fully initialized) workbooks
                  If Not wb Is Nothing Then If wb.FullName <> VBProjFilename(pj) Then GoTo continue
      
                  Dim c As VBComponent:  For Each c In pj.VBComponents
                      c.Activate
                  Next c
      
      continue:
              Next pj
          End With
      
      End Procedure
      
      
      Function VBProjFilename(pj As VBProject) As String
          On Error Resume Next  'leave result empty if workbook (code) not saved yet
          VBProjFilename = pj.Filename
      End Function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 2013-11-17
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多