0

我在 MS Access 中有一个带有图像的表单。该图像有一个 Click 事件,它打开一个模态表单。模态表单有一个确定和取消按钮。当您单击 OK 按钮时,应该触发一个事件,告诉主窗体单击了哪个按钮。(这是为了模拟 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/

4

2 回答 2

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。CANCEL 按钮将表单的标记设置为“取消”,并将表单的 .Visible 属性设置为 False。CONTINUE>> 按钮只是将表单的 .Visible 属性设置为 False。单击其中任何一个按钮都允许代码在使用 acDialog 开关打开表单后继续运行。

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

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

于 2010-09-16T23:47:17.117 回答
0

好吧,我不同意

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

我从事过各种 VB6 和 VBA 项目。最近我在 excel 中编写了 VBA 代码,在那里我从 winform 提出了一个事件。这样做时要考虑的事情很少。

  1. 如果您在 VBA 中使用 withevents/raiseevent 调用非模态 winform。它应该按预期正常工作。不需要主要的解决方法
  2. 如果您在 VBA 中调用模态 winform。Withevents/raiseevents 可能无法按要求运行。一个快速的解决方法是使用模块文件中声明的公共变量来传输数据。

您将需要使用解决方法,我相信它绝对可以正常工作。

于 2016-11-09T11:39:18.990 回答