MS Access VBA 中未触发事件

发布于 2024-09-20 00:08:38 字数 1154 浏览 9 评论 0原文

我在 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/< /a>

I have a form in MS Access which has an image. The image has an Click event which opens a modal form. The modal form has an OK and Cancel button. When you click the OK button, an event is supposed to fire which tells the main form which button was clicked. (This is to simulate the DialogResult functionality in C#). However, the code in the event handler never runs.

The modal form has the following in the general declarations:

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

and the following code where the OK button is clicked:

RaiseEvent OnDialogBoxClose(NewHardwareBaseItemID, dlgresBtnOKClicked)

The main form has the following in the general declarations:

Dim WithEvents RespondQuickAddClose As Form_qckfrmHardwareBaseItemCreate

and the following event handler:

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

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

End Sub

Can someone explain why the event handler is never called?
Thanks!

Background:

The purpose of all this is to allow a modal dialog box to add an entry, then return the ID of the entry back to the main form to set the value of controls. For instance, imagine you are filling out an insurance form, and you need to select a brand of car this is not there. You click on an icon which pops up with the modal dialog box to allow you to add the car brand. Then when you click OK, it takes you back to the insurance form and selects the brand of car you just created.

This follows an example I found here:
http://database.itags.org/ms-access-database/80292/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何处潇湘 2024-09-27 00:08:38

将不同开发环境中的概念应用到 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>> 和 CONTINUE>>。并取消。 CANCEL 按钮将表单的标记设置为“Cancel”,并将表单的 .Visible 属性设置为 False。继续>>按钮什么也不做,只是将表单的 .Visible 属性设置为 False。单击这些按钮中的任何一个都可以在使用 acDialog 开关打开表单后继续执行该行代码。

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

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

You're making your life way too complicated by applying concepts from a different development environment to Access VBA. While VBA does support WithEvents/RaiseEvent, there's no reason to get that complicated here.

The usual way to work with dialogs in Access is that instead of closing them, you hide them. This allows the code after the form was open to run while leaving the values in the form available for use in that code.

Sample code in the OnOpen event of a report that opens a form for collecting values to filter the report:

  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

The dialog form has two command buttons, CONTINUE>> and CANCEL. The CANCEL button sets the form's tag to "Cancel" and sets the form's .Visible property to False. The CONTINUE>> button does nothing but set the form's .Visible property to False. Clicking either of those buttons allows the code to continue on the line after the form is open with the acDialog switch.

My philosophy is to make the dialogs as stupid as possible. The calling code has to know what it's looking for in the forms (i.e., you need to know the names of the controls you're reading data out of), but that could be gotten around by adding customer properties to the form. But then you have to know the property names, so you've just moved the ball.

I have also implemented this kind of thing by wrapping the dailog form in a class module, and then the calling context simply initializes an instance of the class and then pulls the values out of it at the appropriate time. But that's actually more complicated that the approach above.

难以启齿的温柔 2024-09-27 00:08:38

好吧,我不同意

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

我从事过各种 VB6 和 VBA 项目。最近我在 excel 中编写了 VBA,其中我从 winform 引发了一个事件。这样做时需要考虑的事情很少。

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

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

well I don't agree to

"While VBA does support WithEvents/RaiseEvent, there's no reason to
get that complicated here."

I have worked on various VB6 and VBA project. Recently I coded VBA in excel where I raised an event from winform. Few things to be considered when doing so.

  1. If you are calling non-modal winform in VBA with
    withevents/raiseevent. It should work normally as expected. No major
    workaround is needed
  2. If you are calling modal winform in VBA. Withevents/raiseevents may
    not function as per requirement. A quick workaround is to transfer data using public variables declared in the module file.

You will need to use the workaround and I believe it will work absolutely fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文