当VBE(代码窗口)没有打开时,为什么VBE.ActiveCodePane.CodeModule不起作用?

时间:2015-09-23 20:32:54

标签: vba ms-access access-vba

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

MsgBox (VBE.ActiveCodePane.CodeModule)

此消息出现。

enter image description here

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

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

enter image description here

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

但是当你关闭整个应用程序并重新打开它时,关闭VBE就会出错。

为什么呢?这里发生了什么?

4 个答案:

答案 0 :(得分:4)

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

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

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

你可以像这样激活任何VBC组件。

答案 1 :(得分:2)

当第一次打开应用程序时VBE关闭时,没有ActiveCodePane,您可以在加载表单时以条件方式检查:

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

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

Access and VBE are open, but no <code>CodePane</code> is open, therefore the <code>ActiveCodePane</code> is still Nothing

这是有道理的。你试图通过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

答案 2 :(得分:1)

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

显然,当用户使用该程序时,VBE不会打开。引用活动代码窗格只能在开发和调试时完成,而且从不在生产中。

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

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

答案 3 :(得分:0)

方法

由于有时无法避免使用VBE功能,因此对我而言,一般的解决方案是...

  1. 确保初始化/ 激活相关的工作簿VB项目(组件)
  2. 请确保在打开其他工作簿VB项目(组件)后初始化/ 激活如果它们的VBE属性/代码可能在此过程的后面与之相关)< / li>

VbeInit的用法

要做到这一点,可以打电话(见下面的代码)

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

示例案例

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

  • 如果允许用户重新Name重新填写某些工作表,但VB应用程序仍应通过其CodeName
  • 对其进行唯一标识
  • 将此类工作表(例如用作模板工作表)复制(sheet.Copy ...)到其他工作簿。

然后,如果已激活工作表 VBComponent (例如,通过CodeName或在VBE中打开包含源工作表的工作簿,则将仅复制工作表myVBComponent.Activate )。

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