Даже если это сработало, вы не хотите использовать такие переменные.Им должна быть предоставлена самая узкая область действия, чтобы избежать вероятности того, что вы забудете (или кто-то другой, обслуживающий ваш код, забудет), что они объявлены глобально.
Как уже упоминалось в комментариях, объявления, разделенные запятыми, похожи на это ...
Public x, xmax As Integer
... строго типизированы только для тех, которые имеют As {Type}
после них.В этом случае xmax
является Integer
, а x
неявно является Variant
, поскольку тип не был объявлен.
Пользовательские формы являются классами в VBA, и как классы они могут быть расширены с помощьюпубличные методы и свойства.Проблема в том, что вы используете экземпляр формы по умолчанию вместо создания новых экземпляров в цикле.Когда вы вызываете Unload
из внутри формы, вы делаете именно это, и вся информация просто теряется.
Решение состоит в том, чтобы явно создавать экземпляры ваших форм.Таким образом, вы можете настроить их с помощью пользовательских инициализаторов или свойств и легко передавать информацию от вызывающей стороны.Код формы будет выглядеть примерно так:
'indes
Option Explicit
Private incdescript As String
Private incmg As String
Private userEntry
Public Sub LoadValues(descript As String, incoming As String)
expend.Caption = descript & ": " & incoming
incdescript = descript
incmg = incoming
End Sub
Public Property Get UserDescription() As String
UserDescription = incdescript = incmg & " " & incans.Text
End Property
Private Sub OKButton_Click()
Me.Hide
End Sub
Несколько замечаний - в этой форме ничто не зависит от глобальных переменных.Вся конфигурация обрабатывается передачей параметров в процедуру LoadValues
, а «возвращаемое значение» предоставляется через пользовательское свойство UserDescription
.
Также обратите внимание, что кнопка OK не Unload
форма.Это важно, потому что вы собираетесь использовать это для передачи информации назад вызывающей стороне.
Код вызова будет выглядеть примерно так:
Dim x As Integer, xmax As Integer
Dim incmng(1 To 100) As Variant
Dim incdescript(1 To 100) As String, inctot As String
' add in the incoming payments with user entered short description
inctot = ""
Dim paymentDialog As indes
For x = 1 To xmax
Set paymentDialog = New indes
paymentDialog.LoadValues incdescript(x), incmng(x)
paymentDialog.Show vbModal
inctot = paymentDialog.UserDescription & "; " & inctot
Unload paymentDialog
Cells(r - 2, 7) = inctot
Next x
Вы создаетеновый экземпляр формы, передайте ему значения, необходимые для формы, прежде чем показывать ее.Когда форма вызывает Me.Hide
, управление переходит обратно к вызывающей процедуре, а затем вы запрашиваете у формы , что вводил пользователь.Затем вызывающая процедура выгружает ее.
Обратите внимание, что это всего лишь приблизительный набросок того, что я бы назвал "лучшими практиками" для обработки UserForm
.Для более подробного описания я бы посмотрел на этот ответ @MathieuGuindon и прочитал его пост в блоге здесь .