将表单控件链接到类

Posted

技术标签:

【中文标题】将表单控件链接到类【英文标题】:Linking form controls to class 【发布时间】:2019-01-24 00:59:43 【问题描述】:

我正在尝试链接我在类模块中创建的表单上的控件,但无法使其正常工作。

'Class Name is CustForm  

Option Explicit

Private WithEvents btnTest as CommandButton

Public Function showForm()  

    Dim tempForm as Form  
    Dim formName as String  
    Set tempForm = CreateForm  
    formName = tempForm.Name  
    Set btnTest = CreateControl(formName, 
    acCommandButton,acDetail,,,300,300,1000,500)
    Dim btnName As String  
    btnName = btnTest.Name  
    Docmd.RunCommand acCmdFormView  

End Function

Private Sub btnTest_Click()
    MsgBox "Test"
End Sub

我在一个单独的表单中创建对象并在点击事件中调用 showForm

Private Sub Command0_Click()
    Dim tstForm as CustForm
    set tstForm= New CustForm
    tstForm.showForm
End Sub

但是当我点击在 CustForm 中创建的按钮时什么也没有发生 我尝试在 showForm 和 docmd.runco​​mmand acCmdFormView 之后使用临时命令按钮

set btnTest = Forms(formName).Controls(btnName)

假设当表单进入表单视图时,命令按钮的实例可能会发生变化。再一次没有快乐。

但是,如果我将其添加到 CustForm 类中

Public Function init(lclBtn as CommandButton)
    set btnTest = lclBtn
    btnTest.OnClick = "[Event procedure]"
End Function

然后我删除 OnClick 并将此代码添加到表单的模块中

Option Explicit
Dim tester as CustForm

Private Sub Form_Open(Cancel as Integer)
    Set tester = new CustForm
    tester.init Me.Command0
End Sub

然后当我单击按钮时它会触发 MsgBox。 但是我最终需要能够构建一个表单工厂类,它允许我动态地为类对象构建表单并处理对象类中的事件。我宁愿不为每个类制作一堆专门构建的表单,并让表单实例化该类。我想反过来做。类构建表单。

这个可以吗?

【问题讨论】:

【参考方案1】:

在documentation of the Form.HasModule property 中可以看到,有两种表单和报告:没有类模块且不支持事件的轻量级表单和报告,以及具有类模块和支持事件。

这意味着您仍然需要切换此属性以支持事件:

Private WithEvents btnTest as CommandButton

Public Function showForm()  
    Dim tempForm as Form  
    Dim formName as String  
    Set tempForm = CreateForm
    tempForm.HasModule = True
    formName = tempForm.Name  
    Set btnTest = CreateControl(formName, acCommandButton,acDetail,,,300,300,1000,500)
    btnTest.OnClick = "[Event Procedure]"
    Dim btnName As String  
    btnName = btnTest.Name  
    DoCmd.RunCommand acCmdFormView  
End Function

Private Sub btnTest_Click()
    MsgBox "Test"
End Sub

请注意,设置 Form.HasModule 会修改 Access 数据库的 VB 项目部分(它添加了一个类模块),因此每次执行此操作时,都需要重新编译数据库。通常,您希望避免这种情况,因为它可能会导致问题。

相反,我建议使用一个包含模块和所有您可能想要的控件的表单。然后,您可以移动控件、更改它们的标题、调整它们的大小、将它们绑定到表字段并设置事件处理程序,所有这些都无需修改数据库后面的 VB 项目(请注意,您不能将控件添加到完整的在不修改 VB 项目的情况下形成或更改控件的名称)。

请注意,第二个问题是类对象的持久性。目前,没有对该类的引用,因此它已被销毁。您可以使用以下代码轻松地让您的课程无限期地持续存在:

Private WithEvents btnTest as CommandButton
Private Myself As Object

Public Function showForm()
    Set Myself = Me 'Circular reference, object won't get destroyed until myself is set to nothing

有关优雅地处理引用表单的类的更多信息,您可以查看我的this answer。您可能应该收听Form_Unload 事件并在发生时进行清理。

【讨论】:

请注意,没有类模块的轻量级表单和报表实际上可以支持事件。事件处理程序可以使用语法 =MyGlobalFunction() 调用全局 VBA 函数。也可以调用宏。

以上是关于将表单控件链接到类的主要内容,如果未能解决你的问题,请参考以下文章

Java 获取Excel中的表单控件

C#/VB.NET 获取Excel中的表单控件

Access 2007 使用选项卡将多个子表单链接到主表单的最佳方式

如何将表单控件添加到 Django 表单?

Angular 11 ReactiveForm:如何将表单控件更改为表单数组(表单数组内的表单数组)

如何将值从一个表单传递到另一个表单的动态创建的控件