2015-06-25 1 views
0

Я хотел бы создать 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, поэтому мой код ненадежен. У меня есть некоторые идеи, как бороться с этим, но ни один из них не удовлетворяет меня:

  1. Изготовление IsCreated Публичная и установить его в значение False в Workbook_Open Sub - Я не люблю его, как это делает ProgressForm менее прост в использовании - Пользователь формы должен помнить, чтобы установить IsCreated в False в каждой книге, которая использует ProgressForm. Также: абстракция.
  2. Отказ от необходимости проверять, не используя флаг IsCreated.
  3. Положитесь на факт, что uninitialized Boolean по умолчанию установлен в False, поэтому по умолчанию IsCreated удобно установить значение False - это просто неправильно, очень, очень неправильно.
  4. Как-то нажатие инициализации IsCreated на ProgressForm_Initialize() метод. Однако, чтобы показать свою форму, мне сначала нужно позвонить P_Begin, чтобы установить цель. Но P_Begin полагается на переменную IsCreated ... Oops, круговая зависимость.
  5. Как-то обертывание ProgressForm в классе? Я просто предполагаю, я должен признать: я не знаю, как ООП работает в VBA.
  6. Как-то подсчет ProgressForms и настройка IsCreated на false в первом? Звучит немного грязно. Еще раз: это просто моя дикая догадка, основанная на this post, что я не совсем понимаю ...

Обычно, когда я сталкиваюсь с проблемой с по-видимому нет решения, это обычно означает, что моя идея в корне неверно. Может быть, лучше, VBA-путь для достижения желаемых результатов?

+0

Декларирование 'IsCreated', как Boolean будет автоматически назначать это значение по умолчанию 'False' - мне кажется, что все в порядке. –

+0

@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

+0

Это не «случайно», если вы полагаетесь на спецификацию языка, чтобы назначить значение по умолчанию. «Когда вы запускаете макрос, все переменные инициализируются значением. Числовая переменная инициализируется до нуля, строка переменной длины инициализируется нулевой строкой (« »), а строка фиксированной длины заполняется ASCII-код 0. Переменные-переменные инициализируются пустым. Пустая переменная представлена ​​нулем в числовом контексте и строкой нулевой длины ("") в контексте строки. " https://support.microsoft.com/en-us/kb/843144 –

ответ

0

Изменить следующим образом (возможное решение):

Private IsCreated As Integer 
... 
IsCreated = 99 ' in P_Begin 
... 
If (IsCreated <> 99) then ' raise error 
... 
IsCreated = 0 ' in P_End 

Это зависит от того, что VB не будет [вероятно] никогда не инициализировать целочисленную переменную до 99.

 Смежные вопросы

  • Нет связанных вопросов^_^