Вызовите «Получение свойства» в другой процедуре

#excel #vba

#превосходить #vba

Вопрос:

У меня есть эта форма пользователя, в которой я использую a property get . Это работает таким образом:

1.Если нажать кнопку «Ок», форма пользователя скрывается и запускается процедура в модуле.

2.Если ничего не выбрано, появится окно MsgBox, и форма пользователя будет отображаться снова, пока не будет выбрана опция

3.Если нажата кнопка «отмена», информация должна быть выгружена и выйти из макроса.

Проблема в том, что третьего шага не происходит. При нажатии кнопки «отмена» property get запускается. Кроме того, если пользователь не выбирает какой-либо параметр дважды, процедура в модуле все равно запускается, что приводит к ошибке. Я предполагаю, что проблема связана с тем, чтобы не вызывать property get внутреннюю процедуру «ОК». Есть какие-нибудь предложения, как мне это сделать?

В форме пользователя

 Private Sub cmdAceptar_Click()  Me.Hide End Sub  Private Sub cmdCerrar_Click()  Unload Me End Sub  Public Property Get Sup() As String   If optSupA = True Then  Sup = "SuplierA"  ElseIf optSupB = True Then  Sup = "SuplierB"  ElseIf optSupC = True Then  Sup = "SuplierC"  Else  MsgBox "A suplier should be selected", vbExclamation  Me.Show  End If   End Property  

В модуле

 Dim result as String Public Sub TEST()   'Show userform modal  frmSuplier.Show vbModal   result = frmSuplier.Sup     'Call Calculate_prices  Call Calculate_price(result)    'now unload the form  Unload frmSuplier   End Sub  

Ответ №1:

Мое предложение состоит в том, чтобы переместить все дерево IF/ELSE, чтобы оно находилось внутри Control_Change событий для любых частей формы пользователя, которые захватывают значение optSupA , optSupB , optSupC . Это Property Get Sup должно выглядеть так, как будто Sup = SavedValue нет MsgBox или взаимодействия с элементами управления формой пользователя.

Предполагая, что есть 3 кнопки выбора, вот как бы я это настроил:

 Private SupValue As String Private Sub cmdAceptar_Click()  If Me.OptionButton1.Value Or Me.OptionButton2.Value Or Me.OptionButton3.Value Then  Me.Hide  Else 'None of the options are currently selected  MsgBox "A suplier should be selected", vbExclamation  End If End Sub  Private Sub cmdCerrar_Click()  Unload Me End Sub  Public Property Get Sup() As String  Sup = SupValue End Property  Private Sub OptionButton1_Change()  If Me.OptionButton1.Value Then  Me.OptionButton2.Value = False  Me.OptionButton3.Value = False  SupValue = "SupplierA"  End If End Sub  Private Sub OptionButton2_Change()  If Me.OptionButton2.Value Then  Me.OptionButton1.Value = False  Me.OptionButton3.Value = False  SupValue = "SupplierB"  End If End Sub  Private Sub OptionButton3_Change()  If Me.OptionButton3.Value Then  Me.OptionButton1.Value = False  Me.OptionButton2.Value = False  SupValue = "SupplierC"  End If End Sub  

С этими изменениями кнопка отмена Выгружает форму пользователя, удаляя значение SupValue. Таким образом, в вашем модуле result будет пусто, и вы можете добавить if/else для обработки таких ситуаций, как If result = "" Then Exit Sub

Выгрузка с помощью кнопки «Отмена», а затем вызов frmSuplier.Sup фактически повторно инициализирует форму. Поэтому, чтобы избежать этой двойной инициализации и двойной выгрузки, измените кнопку отмена на:

 Private Sub cmdCerrar_Click()  SupValue = ""  Me.Hide End Sub  

Таким образом, вы все еще получаете result = "" , когда пользователь нажимает «Отмена», но вы выполняете только одну загрузку и выгрузку.

Комментарии:

1. Спасибо @Toddleson за ваше предложение, это было именно то, что я хотел сделать. Я немного новичок в использовании формы пользователя, но когда вы используете Me. объект для ссылки на объект формы пользователя, не так ли?

2. @vbabeginner Me ссылается на владельца модуля кода. Поэтому, если бы вы поместили этот код в модуль кода рабочего листа, он Me бы ссылался на объект рабочего листа. Поскольку мы помещаем его в модуль кода формы пользователя, он Me ссылается на объект формы пользователя. Мне нравится использовать Me , потому что это делает код универсальным и его можно легко копировать и вставлять между проектами.