VBA 用户窗体将控件设置为私有(private)而不是公共(public)

标签 vba private public userform

摘要: 在vba用户窗体中,有没有办法将窗体上的元素设置为私有(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

最佳答案

根据我所读到的内容(Bovey 等人的 Professional Excel Development 以及其他来源),标准 VBA 解决方案是 1) 使用类模块定义接口(interface),该接口(interface)列出您想要公开的函数(属性、子函数等)。 2) 在表单模块中,放置“Implements”语句,然后添加将由接口(interface)中声明的公共(public)例程访问的代码。 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。然后,从右侧下拉列表中选择其公共(public)元素之一,然后将插入一个代码块(如下所示)。在此 block 中,您指定进度条的每个公共(public)元素的用途。

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

然后,当您希望在应用程序中使用进度条时,将变量声明为类接口(interface),但分配表单的实例该变量。

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 的方法可以强制人们在这里做你想做的事。这只是一个 VBA“最佳实践”,有助于简化协作并避免错误。 (如果您编译一个库,强制执行您想要的行为可能很简单,但这会将您带到 VBA 之外)。

编辑:

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

If Not TypeOf Me Is iProgressBar Then

    'Clever code that will cause initialization to fail.

End If

关于VBA 用户窗体将控件设置为私有(private)而不是公共(public),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18758963/

相关文章:

module - 私有(private)内部模块返回私有(private)项给出 "private type in public interface"错误

module - 如何在 crate 中将 Rust 项目设为公开,但在其外部设为私有(private)?

excel - 隐藏多个工作表中的行

ms-access - 空列的 DMin

struct - 如何在不为每个字段重复 `pub` 的情况下创建所有字段都是公共(public)的公共(public)结构?

java - Satang api私有(private)http请求

java - SSL通信,能有多难?

arrays - 数组中的类型不匹配

vba - Excel 加载项从 ActiveWorkbook 调用子例程

java - 私有(private)访问? java