向UserFrom添加一个抽象层 - 我做得对吗?

时间:2015-06-25 14:52:33

标签: excel vba variables initialization userform

我想创建一个显示某些操作进度的UserForm(让我们称之为ProgressForm)。我还想让这个表单很容易在我和其他同事的多个工作簿中重用。最后,我想让ProgressForm尽可能简单。

为了使我的表单易于使用,我决定创建3个“方法”:

P_Begin(目标) - 设定目标并准备表格

P_Step() - 记录进度和更新表格

P_End() - 处理表单

现在,为了使它变得万无一失,我需要一些“系统”来防止在调用P_Begin之前使用P_Step或P_End(因为我们需要在尝试取得任何进展之前先设定目标)。

我的想法是使用一个标志(让我们称之为“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

看起来很漂亮吧?好吧,有一个“小”问题:当首次调用P_Begin时,IsCreated变量未初始化,因此我的代码不可靠。我有一些想法如何处理它,但没有一个满足我:

  1. 使IsCreated公开并在Workbook_Open Sub中将其设置为False - 我不喜欢它,因为它使得ProgressForm使用起来不那么简单 - 表单用户必须记住在使用ProgressForm的每个工作簿中将IsCreated设置为False。另外:抽象。
  2. 完全没有使用IsCreated标志,从而放弃了万无一失的要求。
  3. 依赖于未初始化的布尔值默认设置为False的事实,因此默认情况下将IsCreated设置为False - 这是错误的,非常非常错误。
  4. 以某种方式将IsCreated初始化推送到ProgressForm_Initialize()方法。但是,为了显示我的表单,我首先需要调用P_Begin来设置目标。但是P_Begin依赖于IsCreated变量......糟糕,循环依赖。
  5. 以某种方式在课堂上包装ProgressForm?这只是我的猜测,我必须承认:我不知道OOP如何在VBA中运行。
  6. 以某种方式计算ProgressForms并在第一个中将IsCreated设置为false?听起来有点乱。再一次:这只是基于this post的疯狂猜测,我完全不理解......
  7. 通常当我遇到一个显然没有解决方案的问题时,通常意味着我的想法从根本上说是错误的。也许有更好的,VBA方式来达到预期的效果?

1 个答案:

答案 0 :(得分:0)

更改如下(可能的解决方案):

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

这依赖于VB [可能]永远不会将整数变量初始化为99的事实。