没有表单实例如何访问Access VBA用户窗体控件

3
我有一个朋友做Excel VBA项目。该项目有很多弹出窗体,可以在使用电子表格时执行各种功能。其中一些具有复杂的Form_Initialize方法,这些方法依赖于已经存在的其他内容(当预期使用项目时,这不是问题)。
我们尝试打印出应用程序中每个窗体上每个控件的名称。我们的问题是VBA.UserForms集合只包含已经被实例化的窗体,而我们不能实例化所有窗体而没有它们的Form_Initialize方法执行。
例如:
For Each f In VBA.UserForms
    Debug.Print f.Name
    Debug.Print "----------------------"

    For Each c In f.Controls
        Debug.Print c.Name
    Next c
Next f

如果没有使用/加载表单,则不执行任何操作。以下是代码:

For Each c in frmConfig.Controls
    Debug.Print c.Name
Next c

首先执行 frmConfig.Form_Initialize(),然后循环遍历表单上的控件并打印它们的名称。由于在此表单可用之前需要发生的事情尚未发生,因此会崩溃。

是否可能在不实例化表单(避免执行frmConfig.Form_Initialize())的情况下获取表单上控件的名称?

非常感谢任何帮助!


1
+1 很棒的问题.. 让我思考了一段时间 :) - Siddharth Rout
你有没有考虑添加第二个(可选的)构造函数来进行初始化? - user2140173
@mehow:是的,我们考虑过这个问题,但这只是我们想要做的一次性操作,将构造函数逻辑转移到另一个函数中几乎和在设计视图中打开所有表单并手动写下所有控件名称一样耗时... - Alex McMillan
我仍然很感兴趣,想知道这是否可能... - Alex McMillan
如果只是一次性的话,为什么不能将代码放在子程序中,在所有代码结束后调用它。在文件被使用后(用户窗体初始化),您将在立即窗口中拥有所有控件名称?或者我理解错了什么? - user2140173
@mehow:这是一个庞大而复杂的项目,包含许多不经常使用的表单。代码库实际上并没有遵循任何编程标准,因此手动获取控件名称比您建议的方法更有效率。但还是感谢您的建议 :) - Alex McMillan
1个回答

2

你是想尝试这个吗?

Option Explicit

Sub FindObjects()
    Dim vbc As VBIDE.VBComponent
    Dim frm As Object
    Dim Ctrl As MSForms.Control

    For Each vbc In ThisWorkbook.VBProject.VBComponents
        If vbc.Type = vbext_ct_MSForm Then
            With VBA.UserForms
                On Error Resume Next
                Set frm = .Add(vbc.Name)
                Debug.Print "Found userform :" & vbc.Name
                If Err.Number = 0 Then
                    For Each Ctrl In frm.Controls
                        Debug.Print "Controls in Userform " & vbc.Name & _
                        " - " & Ctrl.Name
                    Next Ctrl
                End If
                On Error Go To 0
            End With
        End If
    Next vbc
End Sub

注意:

  1. 设置对Microsoft Visual Basic For Applications Extensibility的引用。
  2. 在Excel选项中,设置“信任对VBA项目对象模型的访问”。

屏幕截图

enter image description here

后续操作

由于这是一次性的操作,请按照以下步骤进行:

  1. 打开VBA项目。
  2. 按下CTRL+F
  3. 按照下面的屏幕截图进行操作,然后运行代码。
  4. 在得到所需内容后不保存关闭文件。

enter image description here


在你的表单中添加一个包含 Debug.Print "Hello"Private Sub UserForm_Initialize 方法,你会看到它出现在你的输出中 :( 不过还是谢谢! - Alex McMillan
我刚刚注意到你上面提到这只是一次性的事情。这是正确的吗?如果是,那么我可能有一个解决方案给你... - Siddharth Rout
1
请查看我在上面帖子中发布的后续内容 :) - Siddharth Rout
太棒了!我为什么没想到呢? :) 这甚至可以用原始电子表格的副本来完成,这意味着没有撤销它的问题。谢谢! - Alex McMillan
如果我早知道这只是一次性的事情,我就早就建议了 :P - Siddharth Rout
抱歉 - 我想我应该在我的原始问题中提到这一点。这是一个相当重要的信息...感谢您的帮助 - 真的很感激! - Alex McMillan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接