创建一个运行以下代码的表单。
MsgBox (VBE.ActiveCodePane.CodeModule)
此消息出现。
现在保存,关闭并重新打开数据库,并看到以下消息:
运行时错误' 91':对象变量或未设置块变量
如果打开Visual Basic编辑器,它将再次运行。即使你关闭VBE,它仍会运行。
但是当你关闭整个应用程序并重新打开它时,关闭VBE就会出错。
为什么呢?这里发生了什么?
答案 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'属性。
这是有道理的。你试图通过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功能,因此对我而言,一般的解决方案是...
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