如何在不打开编辑器的情况下在 VBA 编辑器中动态打开 Class 对象?
How do I open Class Objects dynamically in the VBA editor without opening the editor?
编辑:请参阅下面我的评论以获得部分解决方案。
编辑 2:我找到了关闭 VBA 编辑器的合适解决方案,但只是想看看是否有人知道如何让它一直完全不可见。我发现的内容可以满足我的需要,但我会将此线程留给任何想要详细说明另一种方法或扩展我的方法的人。
原文Post:我有一个创建表、查询和表单的函数。对于表单,它复制模板表单并调用动态替换表单 VBA 代码的函数。我创建的以下函数效果很好,但是,如果我没有在编辑器中打开 class 对象表单,我会收到 运行-Time 错误“2516”:“Microsoft Access 找不到模块'SPCInputFormVBA.',其中 SPCInputFormVBA 是 class 对象名称的变量。为了进一步详细说明行为,如果我关闭了编辑器,只要模块或 class 对象在编辑器中打开,它仍然可以工作。我希望能够在编辑器中激活相应的 Form_xyz 对象而不打开编辑器,这样我就可以使用这个函数做一堆东西到它。我正在使用模板表单,因为其中嵌套了很多东西并且有很多事情要做。我可以更改记录源和其中的各种其他东西的表单很好,但是 VBA 到目前为止,这部分对我来说是难以捉摸的。我认为打开对象很容易,但我遇到了很多麻烦,无法找到一种方法来描述导致我找到解决方案的问题。
Public Function InputFormVBA(SPCInputFormVBA)
DoCmd.OpenModule (SPCInputFormVBA)
Dim i As Integer
With Application.Modules(SPCInputFormVBA)
For i = 1 To .CountOfLines
If InStr(.Lines(i, 1), "TempTable") > 0 Then
' .ReplaceLine i, " If DCount( ""serial"", """ & tblName & """, _"
End If
'If Instr(.Lines(i, 1), "
Next i
End With
End Function
我最接近的是尝试使用此功能进行各种操作,以帮助我了解 Access 将如何对我在网上找到的不同潜在解决方案做出反应:
Sub PrintOpenModuleNames()
Dim i As Integer
Dim modOpenModules As Modules
Set modOpenModules = Application.Modules
For i = 0 To modOpenModules.Count - 1
Debug.Print modOpenModules(i).Name
'DoCmd.OpenModule (modOpenModules(i).Name)
Next
End Sub
'DoCmd.OpenModule (modOpenModules(i).Name)
在此示例中被注释掉并会打开内容,但它只能看到已经打开的内容,这对我没有帮助。我知道有不同类型的模块,但我不确定如何区分,在线文档解释了一般差异,但没有透露任何联系 Class 对象的方法,除非它在编辑器已经。希望有人可以帮助甚至更正我的术语(如果它已关闭)并引导我使用网站其他地方的现有解决方案。
您可以使用 VBE 对象模型来访问表单的代码模块,而无需在 VB 编辑器中打开它。使用这种方法,VB 编辑器 window 不需要可见或打开。如果 VB 编辑器 window 没有打开,以这种方式访问模块将不会打开它。所以我认为这满足了您问题的主要 objective。
可以将 VBE 与后期绑定结合使用,但是由于您不熟悉它,您可能希望改用早期绑定。如果是这样,请将 Microsoft Visual Basic for Applications Extensibility 添加到项目的引用中。
这是一个非常简单的过程,它只向您展示了如何按名称引用代码模块并打印模块的两个属性。
Public Sub InputFormVBA(ByVal SPCInputFormVBA As String)
Dim objModule As CodeModule
Set objModule = Application.VBE.VBProjects(1).VBComponents(SPCInputFormVBA).CodeModule
With objModule
Debug.Print .CountOfDeclarationLines
Debug.Print .CountOfLines
End With
End Sub
如果您的数据库只包含一个 VB一个项目,VBProjects(1)
将引用它。但是如果数据库包含多个 VB 项目,您可能需要给 VBProjects()
一个不同的编号。我想你很快就会明白这一点。 :-)
一个 CodeModule
对象具有您应该会觉得有用的方法,包括:
DeleteLines
; Find
; InsertLines
;和 ReplaceLine
。但是我真的不知道你想用模块的代码做什么,所以就这样吧。
编辑:请参阅下面我的评论以获得部分解决方案。
编辑 2:我找到了关闭 VBA 编辑器的合适解决方案,但只是想看看是否有人知道如何让它一直完全不可见。我发现的内容可以满足我的需要,但我会将此线程留给任何想要详细说明另一种方法或扩展我的方法的人。
原文Post:我有一个创建表、查询和表单的函数。对于表单,它复制模板表单并调用动态替换表单 VBA 代码的函数。我创建的以下函数效果很好,但是,如果我没有在编辑器中打开 class 对象表单,我会收到 运行-Time 错误“2516”:“Microsoft Access 找不到模块'SPCInputFormVBA.',其中 SPCInputFormVBA 是 class 对象名称的变量。为了进一步详细说明行为,如果我关闭了编辑器,只要模块或 class 对象在编辑器中打开,它仍然可以工作。我希望能够在编辑器中激活相应的 Form_xyz 对象而不打开编辑器,这样我就可以使用这个函数做一堆东西到它。我正在使用模板表单,因为其中嵌套了很多东西并且有很多事情要做。我可以更改记录源和其中的各种其他东西的表单很好,但是 VBA 到目前为止,这部分对我来说是难以捉摸的。我认为打开对象很容易,但我遇到了很多麻烦,无法找到一种方法来描述导致我找到解决方案的问题。
Public Function InputFormVBA(SPCInputFormVBA)
DoCmd.OpenModule (SPCInputFormVBA)
Dim i As Integer
With Application.Modules(SPCInputFormVBA)
For i = 1 To .CountOfLines
If InStr(.Lines(i, 1), "TempTable") > 0 Then
' .ReplaceLine i, " If DCount( ""serial"", """ & tblName & """, _"
End If
'If Instr(.Lines(i, 1), "
Next i
End With
End Function
我最接近的是尝试使用此功能进行各种操作,以帮助我了解 Access 将如何对我在网上找到的不同潜在解决方案做出反应:
Sub PrintOpenModuleNames()
Dim i As Integer
Dim modOpenModules As Modules
Set modOpenModules = Application.Modules
For i = 0 To modOpenModules.Count - 1
Debug.Print modOpenModules(i).Name
'DoCmd.OpenModule (modOpenModules(i).Name)
Next
End Sub
'DoCmd.OpenModule (modOpenModules(i).Name)
在此示例中被注释掉并会打开内容,但它只能看到已经打开的内容,这对我没有帮助。我知道有不同类型的模块,但我不确定如何区分,在线文档解释了一般差异,但没有透露任何联系 Class 对象的方法,除非它在编辑器已经。希望有人可以帮助甚至更正我的术语(如果它已关闭)并引导我使用网站其他地方的现有解决方案。
您可以使用 VBE 对象模型来访问表单的代码模块,而无需在 VB 编辑器中打开它。使用这种方法,VB 编辑器 window 不需要可见或打开。如果 VB 编辑器 window 没有打开,以这种方式访问模块将不会打开它。所以我认为这满足了您问题的主要 objective。
可以将 VBE 与后期绑定结合使用,但是由于您不熟悉它,您可能希望改用早期绑定。如果是这样,请将 Microsoft Visual Basic for Applications Extensibility 添加到项目的引用中。
这是一个非常简单的过程,它只向您展示了如何按名称引用代码模块并打印模块的两个属性。
Public Sub InputFormVBA(ByVal SPCInputFormVBA As String)
Dim objModule As CodeModule
Set objModule = Application.VBE.VBProjects(1).VBComponents(SPCInputFormVBA).CodeModule
With objModule
Debug.Print .CountOfDeclarationLines
Debug.Print .CountOfLines
End With
End Sub
如果您的数据库只包含一个 VB一个项目,VBProjects(1)
将引用它。但是如果数据库包含多个 VB 项目,您可能需要给 VBProjects()
一个不同的编号。我想你很快就会明白这一点。 :-)
一个 CodeModule
对象具有您应该会觉得有用的方法,包括:
DeleteLines
; Find
; InsertLines
;和 ReplaceLine
。但是我真的不知道你想用模块的代码做什么,所以就这样吧。