2

摘要:在vba Userform中,有没有办法将表单上的元素设置为Private而不是Public?

原因:我的用户窗体是一个通用进度条,其他程序员可以在同一个 VBAProject 中使用它。我不希望他们直接访问元素来设置信息文本。

标签 lblInformation 的示例:

Sub Test()
    Dim MyProgressBar As New frmProgressBar
    MyProgressBar.Show vbModeless

我强迫他们使用的东西:

    MyProgressBar.setInformation = "Running ..."

我想避免的:

    MyProgressBar.lblInformation.Caption = "Running ..."

如何将 lblInformation 设置为 Private 而不是 Public?

(其余代码)

    Unload ProgressBar
End Sub

应用程序(无关紧要):Autodesk Inventor 2014 中的 VBA7

4

1 回答 1

2

根据我所读到的(在 Bovey 等人的 Professional Excel Development 以及其他来源中),对此的标准 VBA 解决方案是 1)使用类模块来定义一个接口,其中列出了函数(属性,子等)你想公开。2)在您的表单模块中,放置一个“实现”语句,然后添加将由接口中声明的公共例程访问的代码。3)然后,在您的应用程序中,使用界面而不是表单本身。

因此,在一个名为 iProgressBar 的类模块中,列出您想要公开的内容:

Public Property Let Information(ByVal sNew As String)
End Property

Public Property Get Information() As String
End Property

Public Sub UpdateProgress(ByVal dNew As Double)
End Sub

'etc...

那是你的界面。然后在你的 frmProgressBar 模块的顶部,把

Implements iProgressBar

获得该语句后,请查看代码窗口顶部的下拉菜单。从左侧下拉列表中选择 iProgressBar。然后,从右侧下拉列表中选择其中一个公共元素,将插入一个代码块(如下所示)。在此块中,您指定进度条的每个公共元素的作用。

Private Property Let iProgressBar_Information(ByVal str As String)

    Me.lblInformation.Caption = str 

    'Refresh the form
    Me.Repaint

End Property

Private Sub iProgressBar_UpdateProgress(ByVal dNew As Double)

    'Code to update progress on the form

End Property

然后,当您想要应用程序中的进度条时,将您的变量声明为类接口,但将表单的实例分配给该变量。

Sub Test()
    Dim MyProgressBar As iProgressBar
    Set MyProgressBar = New frmProgressBar

    'More code

    'This will work MyProgressBar was dim'ed as iProgressBar, which has an Information property
    MyProgressBar.Information = "Running ..."

    'This will not work because iProgressBar has no lbl...
    MyProgressBar.lblInformation.Caption = "Running ..."

    'More code
End Sub

这里唯一的限制是有人仍然可以进入您的项目并直接开始使用表单,而不是界面。我不认为有任何简单的 VBA-only 方法可以强迫人们在这里做你想做的事。这只是帮助简化协作和避免错误的 VBA“最佳实践”。(如果您编译一个库,强制执行您想要的行为可能很简单,但这会将您带到 VBA 之外)。

编辑:

实际上,我认为您可以采取另一个步骤来强制执行您想要的行为。您可能可以使用 TypeOf... Is... 表达式来防止表单自行打开。在 UserForm_Initialize 例程中,放置以下一些版本:

If Not TypeOf Me Is iProgressBar Then

    'Clever code that will cause initialization to fail.

End If
于 2013-09-30T18:01:27.233 回答