VBA公共变量和属性之间的区别 [英] VBA difference between public variable and property

查看:149
本文介绍了VBA公共变量和属性之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者之间有什么区别

Public Variable As Integer

Private pVariable As Integer

Public Property Let Variable(ByVal lVariable As Integer)
    pVariable = lVariable
End Property

Public Property Get Variable()
    Variable = pVariable
End Property

在VBA类模块中?

那我为什么要使用第二个版本?

解决方案

尽管VBA是面向对象的,但仍然在很多方面受到限制,但就本示例而言,仅了解VBA的基本知识就足够了. VBA中的OOP.

您的代码

Private pVariable As Integer

Public Property Let Variable(ByVal lVariable As Integer)
    pVariable = lVariable
End Property

Public Property Get Variable()
    Variable = pVariable
End Property

错误有点不必要.

注意:您可以在想要处理错误/验证输入数据的情况下执行此操作,但是通常,只要设置和获取值就这么简单,就可以. >

如果同时公开Let/Set和Get属性,为什么还需要一个私有后备字段?您所需要做的就是公共变量本身,而不需要属性.

当您只需要公开其中一个属性而不必公开另一个属性(即,仅setter或getter)时,故事将改变360度.通过一个示例也许更容易理解...

示例

让我们从一个简单的银行业务"示例开始(显然,在现实生活中您不会这么做,但是作为基础评估是一个好概念)

想象一下,您必须构建一个类来模拟银行帐户.您还需要一种从帐户中显示balance的货币depositwithdraw的方法.

通常,您不会balance字段中输入setter,因为不允许任何人显式地set余额. (如果您知道允许这样做的银行,请告诉我;)).实际余额应为私有变量.应该有一个公开它的属性,这就是您应该在这里考虑的所有内容.

考虑VBA类(接口)

IAccountServices.cls

Sub Deposit(amount As Double)
End Sub

Sub WithDraw(amount As Double)
End Sub

和另一个代表帐户的类

Account.cls

Implements IAccountServices

' balance should be private
' cause you should only have a getter for it
' you should only be able to set the balance inside this class
' based on the operations
Private accBalance As Double

' see Getter only - no setter
Public Property Get Balance() As Double
    Balance = accBalance
End Property

Public Function Deposit(amount As Double)
    accBalance = accBalance + amount
End Function

Public Function WithDraw(amount As Double)
    accBalance = accBalance - amount
End Function

Private Sub IAccountServices_Deposit(amount As Double)
    accBalance = accBalance + amount
End Sub

Private Sub IAccountServices_WithDraw(amount As Double)
    accBalance = accBalance - amount
End Sub

注意:这显然是简单示例中的最简单的,并且没有任何错误处理或检查余额是否足以提取等.生活应用.

有了这个封装,我马上就能知道

  • accBalance是一个班级以外的任何地方都无法访问的私有字段.

  • 我只能检索balance(),而不能在Account类的实例上显式设置它.

  • 我可以从帐户中使用deposit()withdraw()钱(可公开访问的方法)


即使在具有标准智能感的标准模块(模块1)中,您也会列出.Balance,这是您的库/类用户所必须担心的.

现在具有用于测试两个类的标准编码模块(模块1)

Sub Main()

    Dim myAccount As Account
    Set myAccount = New Account

    Debug.Print "Starting Balance: " & myAccount.Balance

    myAccount.Deposit (2000)
    Debug.Print "Deposited: 2000"

    myAccount.WithDraw (250)
    Debug.Print "Withdrew: 250"

    Debug.Print "Ending Balance: " & myAccount.Balance

    ' can't set balance
    ' myAccount.Balance = 999999999999999999999999
End Sub

要获得VBA OOP简介,我可以推荐:

As much as VBA is object-oriented it's still limited in many ways, but as far as this example goes it should be sufficient to just understand the basics of the OOP in VBA.

Your code

Private pVariable As Integer

Public Property Let Variable(ByVal lVariable As Integer)
    pVariable = lVariable
End Property

Public Property Get Variable()
    Variable = pVariable
End Property

is wrong a bit unnecessary.

NOTE: You may do that in cases where you want to handle errors / validate data coming in but generally if it's as simple as setting and getting the value you wouldn't do that.

Why would you ever need a private backing field if you are exposing both the Let/Set and Get properties? All you need for this is the public variable itself and no need for properties.

The story changes 360 degrees when you have to only expose one of the properties and not the other (ie. either setter or getter only ). Maybe it's easier to understand by working through an example...

Example

Let's start by working through an easy "banking" example (obviously you wouldn't do that in VBA in real-life but it's a good concept to evaluate as a base)

Imagine you have to build a class to simulate a bank account. You need a way to deposit and withdraw money from the account as well display balance.

Normally you wouldn't have a setter for the balance field because no-one should be allowed to explicitly set the balance. (if you know a bank that allows this please let me know ;)) . The actual balance should be a private variable. There should be a property which exposes it and that's all you should consider here.

Consider a VBA class (an interface)

IAccountServices.cls

Sub Deposit(amount As Double)
End Sub

Sub WithDraw(amount As Double)
End Sub

and another class to represent the account

Account.cls

Implements IAccountServices

' balance should be private
' cause you should only have a getter for it
' you should only be able to set the balance inside this class
' based on the operations
Private accBalance As Double

' see Getter only - no setter
Public Property Get Balance() As Double
    Balance = accBalance
End Property

Public Function Deposit(amount As Double)
    accBalance = accBalance + amount
End Function

Public Function WithDraw(amount As Double)
    accBalance = accBalance - amount
End Function

Private Sub IAccountServices_Deposit(amount As Double)
    accBalance = accBalance + amount
End Sub

Private Sub IAccountServices_WithDraw(amount As Double)
    accBalance = accBalance - amount
End Sub

NOTE: This obviously is the simplest of simple examples and it does not have any error handling or checking whether the balance is sufficient to withdraw etc. This is just for demonstration purposes and not to be used in a real-life application.

With this encapsulation I see/know right away

  • accBalance is a private field not accessible anywhere outside the class.

  • I can only retrieve the balance() and not explicitly set it on an instance of the Account class.

  • I can deposit() and withdraw() money from the account (publicly accessible methods)


In you standard module (module1) even with intelli-sense you get the .Balance listed and that's all your library/class user ever have to worry about.

Now having a standard coding module to test both classes (Module1)

Sub Main()

    Dim myAccount As Account
    Set myAccount = New Account

    Debug.Print "Starting Balance: " & myAccount.Balance

    myAccount.Deposit (2000)
    Debug.Print "Deposited: 2000"

    myAccount.WithDraw (250)
    Debug.Print "Withdrew: 250"

    Debug.Print "Ending Balance: " & myAccount.Balance

    ' can't set balance
    ' myAccount.Balance = 999999999999999999999999
End Sub

To get an intro to VBA OOP I could recommend:

这篇关于VBA公共变量和属性之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆