【问题标题】:VBA Userform set Controls as Private instead of PublicVBA 用户窗体将控件设置为私有而不是公共
【发布时间】:2013-09-16 12:38:39
【问题描述】:

总结: 在 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

【问题讨论】:

  • 为标准用户表单创建一个包装器。您自己的具有私有属性的类

标签: vba private public userform


【解决方案1】:

根据我所读的内容(在 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

【讨论】:

  • 尤其是我最喜欢的初始化捕获:)
猜你喜欢
  • 2015-06-09
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 2017-12-09
  • 2020-04-04
相关资源
最近更新 更多