Access VBA: как подписаться на изменение элемента управления / поля, произошедшее из другого кода VBA, а не из взаимодействия с пользователем - PullRequest
0 голосов
/ 12 марта 2019

Я в странной ситуации.У меня есть форма с подчиненной формой.Когда значение в подчиненной форме изменяется, в после обновления я вызываю

If Not IsNull(Me.Parent) Then
   Me.Parent.ParentField.Value = Me.SubformField.Value
End If

В родительской форме я хочу, чтобы изменение в ParentField вызвало другое событие.Жаль, что изменение программно не вызывает ни события AfterUpdate, ни события onChange.

Поскольку та же самая подчиненная форма используется в более родительских формах, я не могу напрямую вызвать метод, который вызывается вafterUpdate

Есть ли что-то еще, на что я могу "подписаться"?

Ответы [ 2 ]

1 голос
/ 13 марта 2019

По крайней мере, в Excel это можно сделать, добавив пользовательское событие в пользовательскую форму субпользователя, а затем добавив подчиненную форму в качестве объекта в родительской пользовательской форме.

Я создал макет, показанный ниже (командная кнопка на Родительской пользовательской форме предназначена главным образом для удержания начального фокуса, так как в этом макете форма открывается при вводе текстового поля):

Sub and Parent Userforms

'SubUserForm code
Option Explicit
'Custom Events don't have to pass values, or can pass multiple values as desired
Public Event FormChange(newValue As Variant)

Private Sub TextBoxS_Change()
    'If I wanted the event to raise for various control changes,
    '    I could add it to multiple Change Events.
    RaiseEvent FormChange(TextBoxS.Value)

    'Or I could instead call a private sub such as
    '        ConditionalEvent(TextBoxS.Value)
    '    with the logic for checking if the event should
    '    be raised; especially helpful if
    '    logic depends on multiple changes or conditions
End Sub

Private Sub ConditionalEvent(vNew As Variant)
    If True Then 'More complicated checks, maybe changed private variables, etc.
        RaiseEvent FormChange(vNew)
    End If
End Sub

'This is to prevent the parent losing refernce to the sub form.
'The parent should be the one that creates an instance of this form,
'   as well as be the one to delete it.
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    Me.Hide
End Sub

'Parent UserForm code
Option Explicit
'The private instance of the subform needs to be of the
'    baseform itself, not a generic object or userform.
'    Otherwise the custom event won't carry through.
'    However, this also means that the only events carried through
'    will be the custom ones (at least as far as I could tell)
Private WithEvents subForm As SubUserForm

'This is the custom event from the subform
Private Sub subForm_FormChange(newValue As Variant)
    TextBoxP.Value = newValue
End Sub

'This is important. The default value of subform is Nothing,
'    so initialization is required.
Private Sub UserForm_Initialize()
    Set subForm = New SubUserForm
End Sub

'This sub is the mock-up logic and call to show the sub form for testing.
'It is not required for using custom events.
Private Sub TextBoxP_Enter()
    subForm.Show
End Sub

Private Sub UserForm_Terminate()
    'Terminates the subform on parent closure
    Set subForm = Nothing
End Sub

Для тестирования я использовал приведенный ниже код, чтобы показать родительскую форму пользователя.Обратите внимание, что я также изменил имена текстовых полей и пользовательских форм следующим образом:

  • Подформа: SubUserForm, TextBoxS
  • ParentForm: ParentUserFrom, TextBoxP

Если кто-то захочет использовать макет кода, после создания пользовательских форм им потребуется либо изменить имена текстовых полей и пользовательских форм, либо их ссылки в коде.

'In a generic module
Option Explicit

' Used to open the parent form for testing
Sub test()
    ' Using a with statement allows using a new instance of the form
    '    (instead of the "free instance" automatically provided)
    '    without having to assign the new instance to a variable to
    '    use, and then having to assign to variable to Nothing
    With New ParentUserForm
        .Show
    End With
End Sub
0 голосов
/ 12 марта 2019

Как правило, события управления не запускаются при изменении VBA.Это имеет смысл, поскольку для этого элемента управления может произойти множество событий, и поэтому определение того, когда и когда не следует запускать все эти события, было бы кошмаром.

Однако вы наверняка можете вызвать код и выполнить кодв родительской форме и запустите его.

Так что, если для данного элемента управления выполняется кнопка или какой-либо код события, просто вызовите этот код события для вызова открытого подпрограммы в родительской форме.

Такможно нажать кнопку или после обновления:

Call MySub

MySub - это просто общедоступная подпрограмма, которую код кнопки или события вызывает в главной форме.

Теперь в подформе выможет пойти:

Me.Parent.ParentField.Value = me.SomeField

Call me.Parent.MySub()

И я полагаю, что вы также можете использовать функцию и пойти:

My.Parent.MyFunctionToRun()

Так что настройте общую подпрограмму (подпрограмму или функцию) в родительской форме, чтокод события (или кнопка) звонков.А затем просто вызовите ту же самую процедуру, как указано выше, в форме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...