Событие не запускается в MS Access VBA

У меня есть форма в MS Access с изображением. Изображение имеет событие Click, которое открывает модальную форму. Модальная форма имеет кнопки «ОК» и «Отмена». Когда вы нажимаете кнопку OK, должно срабатывать событие, которое сообщает основной форме, какая кнопка была нажата. (Это для имитации функциональности DialogResult в C#). Однако код в обработчике событий никогда не запускается.

Модальная форма имеет следующее в общих объявлениях:

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

и следующий код, где нажимается кнопка OK:

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

Может кто-нибудь объяснить, почему обработчик событий никогда не вызывается? Спасибо!

Задний план:

Цель всего этого — позволить модальному диалоговому окну добавить запись, а затем вернуть идентификатор записи обратно в основную форму, чтобы установить значение элементов управления. Например, представьте, что вы заполняете форму страховки, и вам нужно выбрать марку автомобиля, которой там нет. Вы нажимаете на значок, который появляется с модальным диалоговым окном, позволяющим добавить марку автомобиля. Затем, когда вы нажмете «ОК», вы вернетесь к форме страхования и выберете марку автомобиля, которую вы только что создали.

Это соответствует примеру, который я нашел здесь: http://database.itags.org/ms-access-database/80292/


person Tim    schedule 16.09.2010    source источник
comment
Я предлагаю вам вернуться и посмотреть ссылку, которую Альберт Д. Калал разместил в первом ответе. Вышеупомянутое совсем не так, как работает VBA. VBA намного проще.   -  person Fionnuala    schedule 17.09.2010
comment
Что касается добавления элемента, вы можете посмотреть на событие «Нет в списке» для комбо.   -  person Fionnuala    schedule 17.09.2010
comment
Ключом к этой работе является тот факт, что использование acDialog останавливает выполнение кода в основной форме. Я попробую это завтра, но похоже, что это должно сработать. Тем не менее, это не объясняет, почему обработчик событий не выполняется!   -  person Tim    schedule 17.09.2010


Ответы (2)


Вы слишком усложняете свою жизнь, применяя концепции из другой среды разработки к 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

В диалоговой форме есть две командные кнопки: ПРОДОЛЖИТЬ>> и ОТМЕНА. Кнопка ОТМЕНА устанавливает для тега формы значение «Отмена» и устанавливает для свойства .Visible формы значение False. Кнопка ПРОДОЛЖИТЬ>> не делает ничего, кроме установки свойства формы .Visible в значение False. Нажатие любой из этих кнопок позволяет коду продолжить работу в строке после того, как форма будет открыта с помощью переключателя acDialog.

Моя философия состоит в том, чтобы сделать диалоги настолько глупыми, насколько это возможно. Вызывающий код должен знать, что он ищет в формах (т. е. вам нужно знать имена элементов управления, из которых вы считываете данные), но это можно обойти, добавив в форму свойства клиента. Но тогда вам нужно знать имена свойств, так что вы только что сдвинули мяч.

Я также реализовал такого рода вещи, обернув форму ежедневного журнала в модуль класса, а затем вызывающий контекст просто инициализирует экземпляр класса, а затем извлекает из него значения в соответствующее время. Но на самом деле это сложнее, чем описанный выше подход.

person David-W-Fenton    schedule 16.09.2010
comment
Спасибо! Я действительно не понимал, как это может работать, пока не вернулся и не посмотрел ссылку в первом ответе на странице, на которую я ссылался (как предложил Рему в своем комментарии к моему вопросу выше). Ключом к этому является то, что acDialog останавливает код в основной форме. В противном случае мне все еще нужны события (или что-то еще). Я также могу выделить это в модуль класса, как вы упомянули... как только я заработаю, конечно! - person Tim; 17.09.2010
comment
Этот ответ помог мне. Для более подробной реализации перейдите на stackoverflow.com/a/22158511/122139. - person Smandoli; 07.03.2014

ну я не согласен

«Хотя VBA поддерживает WithEvents/RaiseEvent, здесь нет причин усложнять».

Я работал над различными проектами VB6 и VBA. Недавно я закодировал VBA в excel, где поднял событие из winform. Несколько вещей, которые следует учитывать при этом.

  1. Если вы вызываете немодальную форму winform в VBA с withevents/raiseevent. Он должен работать нормально, как и ожидалось. Не требуется серьезного обходного пути
  2. Если вы вызываете модальную winform в VBA. Withevents/raiseevents могут не работать в соответствии с требованиями. Быстрый обходной путь — передать данные с помощью общедоступных переменных, объявленных в файле модуля.

Вам нужно будет использовать обходной путь, и я считаю, что он будет работать абсолютно нормально.

person user3242959    schedule 09.11.2016