事件不在MS Access VBA中触发

时间:2010-09-16 21:16:34

标签: ms-access vba event-handling access-vba raiseevent

我在MS Access中有一个有图像的表单。该图像具有Click事件,可打开模态表单。模态表单有一个确定和取消按钮。当您单击“确定”按钮时,应该触发一个事件,该事件告诉主窗体单击了哪个按钮。 (这是为了模拟C#中的DialogResult功能)。但是,事件处理程序中的代码永远不会运行。

模态形式在一般声明中有以下内容:

Public Event OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)

以及单击“确定”按钮的以下代码:

RaiseEvent OnDialogBoxClose(NewHardwareBaseItemID, dlgresBtnOKClicked)

主要表格在一般声明中有以下内容:

Dim WithEvents RespondQuickAddClose As Form_qckfrmHardwareBaseItemCreate

以及以下事件处理程序:

Private Sub RespondQuickAddClose_OnDialogBoxClose(NewRecordID As Long, DialogResult As DialogResults)

    MsgBox "Responding to closing of the dialog box" 'Never happens
    Me.Requery

End Sub

有人可以解释为什么永远不会调用事件处理程序吗? 谢谢!

背景:

所有这一切的目的是允许模式对话框添加条目,然后将条目的ID返回到主窗体以设置控件的值。例如,假设您正在填写保险表格,并且您需要选择一个不存在的汽车品牌。单击弹出模式对话框的图标,可以添加汽车品牌。然后,当您单击“确定”时,它会将您带回保险表单并选择刚刚创建的汽车品牌。

这是我在这里找到的一个例子: http://database.itags.org/ms-access-database/80292/

2 个答案:

答案 0 :(得分:3)

通过将来自不同开发环境的概念应用于Access VBA,您的生活变得过于复杂。虽然VBA确实支持WithEvents / RaiseEvent,但没有理由在这里搞复杂。

在Access中使用对话框的常用方法是隐藏它们,而不是关闭它们。这允许表单打开后运行代码,同时保留表单中的值可用于该代码。

报表的OnOpen事件中的示例代码,用于打开用于收集值以过滤报表的表单:

  Private Sub Report_Open(Cancel As Integer)
    DoCmd.OpenForm "dlgDateRange", , , , , acDialog, "ThisYear"
    If IsLoaded("dlgDateRange") Then
       With Forms!dlgDateRange
         If .Tag = "Cancel" Then
            Cancel = True
         Else
            Me.Filter = "[InvoiceDate] Between #" & !txtStart & "# AND #" & !txtEnd & "#"
            Me.FilterOn = True
            Me!lblDateRange.Caption = StrConv(Trim(("from " + varZLStoNull(Format(!txtStart, "mm/dd/yyyy"))) _
                & (" to " + varZLStoNull(Format(!txtEnd, "mm/dd/yyyy")))), vbProperCase)
         End If
       End With
       DoCmd.Close acForm, "dlgDateRange"
    End If
  End Sub

对话框表单有两个命令按钮,CONTINUE>>和取消。 CANCEL按钮将表单的标记设置为“取消”,并将表单的.Visible属性设置为False。 CONTINUE>>按钮除了将表单的.Visible属性设置为False之外什么都不做。单击其中一个按钮可以在使用acDialog开关打开表单后继续执行代码。

我的理念是让对话尽可能愚蠢。调用代码必须知道它在表单中查找的内容(即,您需要知道您正在读取数据的控件的名称),但这可以通过向表单添加客户属性来实现。但是你必须知道属性名称,所以你刚刚移动了球。

我还通过在类模块中包装dailog表单来实现这种事情,然后调用上下文简单地初始化类的一个实例,然后在适当的时候从中拉出值。但这实际上比上述方法更复杂。

答案 1 :(得分:0)

我不同意

  

“虽然VBA支持WithEvents / RaiseEvent,但没有理由   在这里变得复杂。“

我参与过各种VB6和VBA项目。最近我在excel编写了VBA,我在winform中提出了一个事件。这样做时很少考虑。

  1. 如果你在VBA中调用非模态winform WITHEVENTS /的RaiseEvent。它应该按预期正常工作。没有专业 需要解决方法
  2. 如果你在VBA中调用modal winform。 Withevents / raiseevents可能会     不按要求运作。一个快速的解决方法是使用模块文件中声明的公共变量传输数据。
  3. 您将需要使用变通方法,我相信它将完全正常。

相关问题