VBA for Access 2010:动态创建控件和链接事件处理程序

Posted

技术标签:

【中文标题】VBA for Access 2010:动态创建控件和链接事件处理程序【英文标题】:VBA for Access 2010: Dynamically creating a control and linking event handlers 【发布时间】:2015-11-05 21:37:59 【问题描述】:

在 Microsoft Access 2010 中,我尝试动态创建一个表单,然后向其中添加一个命令按钮。但是,我不知道如何将事件处理程序分配给该按钮的单击(或 onclick)事件?

通过阅读互联网上的摘录,我创建了以下 vba 模块代码:

Option Compare Database
Option Explicit

Public Sub ProduceForm()
  Dim aForm As Form
  Dim aButton As CustomButton
  Set aForm = CreateAForm("Table1")
  Set aButton = CreateAButton(aForm, "Click me!")
  DoCmd.Restore
End Sub

Private Function CreateAForm(table As String) As Form
  Set CreateAForm = CreateForm(, table)
  With CreateAForm
    .Caption = CreateAForm.Name
  End With
End Function

Private Function CreateAButton(aForm As Form, text As String) As CustomButton
  Set CreateAButton = New CustomButton
  Set CreateAButton.btn = CreateControl(aForm.Name, acCommandButton)
  CreateAButton.SetupButton text
End Function

根据互联网的建议,我添加了以下类模块(我称之为“CustomButton”并在上面提到):

Option Compare Database

Public WithEvents btn As CommandButton

Public Sub SetupButton(text As String)
 If IsNull(btn) = False Then
    With btn
        .Caption = text
        .OnClick = "[Event Procedure]"
    End With
 End If
End Sub

Public Sub btn_OnClick() ' or should this method just be called btn_Click()?
  MsgBox "Happy days"
End Sub

但是,当我运行此代码然后单击按钮(在表单视图中)时,什么也没有发生?

我注意到对类似问题的解释,但对于 excel 2010,通过将代码编写为“CodeModule”中的字符串来提供替代解决方案,我认为它与“vbComponents”对象相关联。这个解决方案应该对我有用,但我在 Access 2010 中找不到这个功能?

无论如何,对于这个问题的任何帮助将不胜感激。

谢谢

【问题讨论】:

【参考方案1】:

编辑 - 我最初的回答假设 Access 的行为类似于 excel,但似乎并非如此......

您不需要自定义类来处理事件 - 您只需将字符串传递给按钮的 OnClick 属性即可。

这对我有用——不过可能需要整理一下。

Public Sub ProduceForm()
  Dim aForm As Form, strName As String
  Dim btn As CommandButton

  Set aForm = CreateAForm("Table1")

  Set btn = CreateAButton(aForm, "Click me!", "=SayHello()")
  btn.Top = 100
  btn.Left = 100

  Set btn = CreateAButton(aForm, "Click me too!", "=SayHello('World')")
  btn.Top = 1000
  btn.Left = 100

  DoCmd.OpenForm aForm.Name, , , , , acDialog

  DoCmd.Restore
End Sub

Private Function CreateAForm(table As String) As Form
  Set CreateAForm = CreateForm(, table)
  With CreateAForm
    .Caption = CreateAForm.Name
  End With
End Function

Private Function CreateAButton(aForm As Form, txt As String, proc As String) As CommandButton
  Dim btn As CommandButton
  Set btn = CreateControl(aForm.Name, acCommandButton)
  btn.OnClick = proc
  btn.Caption = txt
  Set CreateAButton = btn
End Function

'has to be a Function not a Sub
Public Function SayHello(Optional arg As String = "")
    MsgBox "Hello " & arg
End Function

【讨论】:

嗨,蒂姆,感谢您的回复。我移动了 aButton 声明,使其直接位于“Option Explicit”(因此是全局的)下方,但是当代码运行并按下按钮时,事件处理程序仍然不会触发?或者如果我需要将它移动到表单代码模块,那么当表单(aForm)也是动态创建时我该怎么做?

以上是关于VBA for Access 2010:动态创建控件和链接事件处理程序的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 2010 vba 查询

如何创建将传递查询导出为 XML 文件的 VBA 函数(用于 Access 2010)?

Microsoft Access VBA 2010 如何创建组合框和数组?

access 2010找不到我的VBA函数?

使用 VBA 在 Access 2010 中的表单上显示记录集

运行时错误“3264”访问 2010 VBA