По крайней мере, в Excel это можно сделать, добавив пользовательское событие в пользовательскую форму субпользователя, а затем добавив подчиненную форму в качестве объекта в родительской пользовательской форме.
Я создал макет, показанный ниже (командная кнопка на Родительской пользовательской форме предназначена главным образом для удержания начального фокуса, так как в этом макете форма открывается при вводе текстового поля):
'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