Я хотел бы создать UserForm, показывая ход некоторой операции (назовем это ProgressForm). Я также хотел бы сделать эту форму простой для повторного использования в нескольких книгах мной и другими сотрудниками. Наконец, я хотел бы сделать мой ProgressForm максимально надежным.Добавление слоя абстракции в UserFrom - я делаю это правильно?
Для того, чтобы мой вид простой в использовании я решил создать 3 «методы»:
P_Begin (цель) - установить цель и подготовить форму
P_Step() - для записи прогресс и обновление формы
P_End() - отчуждать форму
Теперь, чтобы сделать дурака мне нужна «система», которая не позволяет использовать P_Step или P_End перед тем P_Begin называется (как нам нужно установить наша цель ПЕРВЫЙ, прежде чем мы попытаемся добиться какого-либо прогресса).
Моя идея - использовать флаг (назовем его «IsCreated»), который будет определять, был ли вызван P_Begin. Вот что у меня до сих пор:
Private IsCreated As Boolean
Private Goal As UInteger
Private Progress As UInteger
Function P_Begin(pGoal As UInteger)
If IsCreated Then
Err.Raise 5
End If
Goal = pGoal
Progress = 0
IsCreated = True
' Prepare ProgressForm elements here
Me.Show vbModeless
End Function
Function P_Step()
If Not IsCreated Then
Err.Raise 5
End If
Progress = Progress + 1
' Update ProgressForm elements here
End Function
Function P_End()
If Not IsCreated Then
Err.Raise 5
End If
IsCreated = False
Me.Hide
End Function
Это, как я полагаю, использовать пример:
Sub DoingSomething()
ProgressForm.P_Begin pGoal:=100
For i = 1 To 100
' Doing Something
ProgressForm.P_Step
Next i
ProgressForm.P_End
ProgressForm.P_Begin pGoal:=200
For i = 1 To 200
'Doing Something Else
ProgressForm.P_Step
Next i
ProgressForm.P_End
' and so on...
End Sub
выглядит довольно хорошо, не так ли? Ну, есть небольшая проблема: переменная IsCreated не инициализируется при первом вызове P_Begin, поэтому мой код ненадежен. У меня есть некоторые идеи, как бороться с этим, но ни один из них не удовлетворяет меня:
- Изготовление IsCreated Публичная и установить его в значение False в Workbook_Open Sub - Я не люблю его, как это делает ProgressForm менее прост в использовании - Пользователь формы должен помнить, чтобы установить IsCreated в False в каждой книге, которая использует ProgressForm. Также: абстракция.
- Отказ от необходимости проверять, не используя флаг IsCreated.
- Положитесь на факт, что uninitialized Boolean по умолчанию установлен в False, поэтому по умолчанию IsCreated удобно установить значение False - это просто неправильно, очень, очень неправильно.
- Как-то нажатие инициализации IsCreated на
ProgressForm_Initialize()
метод. Однако, чтобы показать свою форму, мне сначала нужно позвонить P_Begin, чтобы установить цель. Но P_Begin полагается на переменную IsCreated ... Oops, круговая зависимость. - Как-то обертывание ProgressForm в классе? Я просто предполагаю, я должен признать: я не знаю, как ООП работает в VBA.
- Как-то подсчет ProgressForms и настройка IsCreated на false в первом? Звучит немного грязно. Еще раз: это просто моя дикая догадка, основанная на this post, что я не совсем понимаю ...
Обычно, когда я сталкиваюсь с проблемой с по-видимому нет решения, это обычно означает, что моя идея в корне неверно. Может быть, лучше, VBA-путь для достижения желаемых результатов?
Декларирование 'IsCreated', как Boolean будет автоматически назначать это значение по умолчанию 'False' - мне кажется, что все в порядке. –
@TimWilliams Да, но он решает мою проблему только «случайно». Разве это не какая-то «плохая привычка» или «грязный трюк»? Тем более, что я не могу найти ничего о значении Boolean по умолчанию в документации VBA. Тип данных Boolean: https://msdn.microsoft.com/en-us/library/office/gg264308%28v=office.14%29.aspx ничего. Краткое описание типа данных: https://msdn.microsoft.com/en-us/library/office/gg251528%28v=office.14%29.aspx нет. – browning0
Это не «случайно», если вы полагаетесь на спецификацию языка, чтобы назначить значение по умолчанию. «Когда вы запускаете макрос, все переменные инициализируются значением. Числовая переменная инициализируется до нуля, строка переменной длины инициализируется нулевой строкой (« »), а строка фиксированной длины заполняется ASCII-код 0. Переменные-переменные инициализируются пустым. Пустая переменная представлена нулем в числовом контексте и строкой нулевой длины ("") в контексте строки. " https://support.microsoft.com/en-us/kb/843144 –