Передача переменной из формы в модуль в VBA

У меня есть следующая кнопка в форме:

Private Sub CommandButton1_Click()
 Dim pass As String
 pass = UserForm1.TextBox1
 Unload UserForm1
End Sub

Затем у меня есть модуль под названием Module1:

 Public Sub Login()

 ...

 UserForm1.Show
 driver.findElementByName("PASSWORD").SendKeys pass

 ...

End Sub

Идея - это любой пароль, который вводит пользователь в поле ввода, будет присвоен переменной pass. Однако у меня возникают проблемы с передачей pass из UserForm1 в модуль входа Module1.

Я бы подумал добавить что-то вроде Module1.Login (pass) в мою форму, прежде чем я выгружу его, но это ничего не изменит. Любая помощь приветствуется. Спасибо.

Ответы

Ответ 1

Не объявляйте переменную в пользовательской форме. Объявите его как Public в модуле.

Public pass As String

В пользовательской форме

Private Sub CommandButton1_Click()
    pass = UserForm1.TextBox1
    Unload UserForm1
End Sub

В модуле

Public pass As String

Public Sub Login()
    '
    '~~> Rest of the code
    '
    UserForm1.Show
    driver.findElementByName("PASSWORD").SendKeys pass
    '
    '~~> Rest of the code
    '
End Sub

Возможно, вы захотите также добавить дополнительную проверку непосредственно перед вызовом строки driver.find...?

If Len(Trim(pass)) <> 0 Then

Это гарантирует, что пустая строка не будет передана.

Ответ 2

Ответ Сиддхарта хорош, но полагается на глобальные переменные. Там лучший, более удобный для ООП способ.

UserForm - это модуль класса, как и любой другой. Единственное различие заключается в том, что он имеет скрытый атрибут VB_PredeclaredId, установленный в True, что делает VB создание переменной объекта глобальной области, названной в честь класса, - как вы может написать UserForm1.Show без создания нового экземпляра класса.

Отстаньте от этого и обработайте свою форму как объект - выведите Property Get участников и отвлеките элементы управления формы - код вызова все равно не заботится о элементах управления:

Option Explicit
Private cancelling As Boolean

Public Property Get UserId() As String
    UserId = txtUserId.Text
End Property

Public Property Get Password() As String
    Password = txtPassword.Text
End Property

Public Property Get IsCancelled() As Boolean
    IsCancelled = cancelling
End Property

Private Sub OkButton_Click()
    Me.Hide
End Sub

Private Sub CancelButton_Click()
    cancelling = True
    Me.Hide
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        cancelling = True
        Me.Hide
    End If
End Sub

Теперь вызывающий код может это сделать (если UserForm был назван LoginPrompt):

With New LoginPrompt
    .Show vbModal
    If .IsCancelled Then Exit Sub
    DoSomething .UserId, .Password
End With

Где DoSomething будет некоторая процедура, требующая двух строковых параметров:

Private Sub DoSomething(ByVal uid As String, ByVal pwd As String)
    'work with the parameter values, regardless of where they came from
End Sub