VBA:为什么要使用属性而不是子程序或函数?

4

在VBA类中,我们为什么需要使用属性LetGetSet,而不能简单地通过子程序或函数传递和返回参数呢?


1
海报并不是在问为什么要使用类,他在问为什么我们在VBA类中应该使用Property Let、Get和Set而不是Subs & Functions。 - livefree75
到目前为止,以下问题似乎仍然没有回答我的问题,我期望类似于这个 .net 回答的功能效果:https://dev59.com/3UnSa4cB1Zd3GeqPRdbs - Jason K.
有些答案声称属性仅适用于类,但是属性也可以在常规代码模块中使用。子程序用于使某些事情发生,其中不需要返回值。函数也可以使某些事情发生,但会返回一些结果/值/对象。拥有属性意味着存在某个值/对象,用户可以Get以查看其外观或Set/Let以更改它。例如,Worksheet.Name是内置的Excel属性。像这样Get属性:Debug.Print ActiveSheet.Name或者像这样LetActiveSheet.Name = "My Report" - ChrisB
5个回答

4
我认为简短的答案是,属性是类的特征,而方法(子例程)是行动。
我的理解是,属性是“形容词”,方法是“动词”。我们可以做一个类比来帮助说明这一点: 我们有两个NHL守门员(让我们把他们创建为clsGoalie的成员),Carey Price和Dustin Tokarski。每个守门员都有一个特定于其唯一“守门员”对象的属性,我们称之为保存百分比(pSavePercentage)。两个守门员都需要完全相同的方法来阻止进攻射门(让我们说是Private Sub BlockShot),但他们独特的属性将影响该操作的性能。
为什么我们要用属性来定义类的特征而不是返回值的答案是,属性扩展了对象,或者本质上定义了对象。返回值不能用于引用它们起源的对象。回到我们的守门员类比...假设我们用子例程定义了每个守门员的保存百分比。我们可以让它工作,但在我们的主方法中需要更多的代码。首先,我们必须“Dim SavePercentage As Double”(已经可以看出我们已经走出了我们的对象)。接下来,“SavePercentage = Price.calcSavePercentage”。最后,我们必须编写一个全新的方法(在我们的Main或其他模块中),然后将我们的新变量类型double传递给它...这时我们甚至不知道谁在守门。是Price救了那个球还是Tokarski?令人困惑。在这种情况下,如果我们将保存百分比作为类“clsGoalie”的属性,我们将更好地利用面向对象编程(OOP)的优势: 清洁的代码和封装。
希望这有点帮助。

3

对于90%的应用程序,您不需要使用高级VBA技术,标准VBA就可以胜任。使用类,您可以更好地控制代码。

假设您有一个函数Function IsUnique(MyArg as String) as Boolean,它查找一个名为MyArg的人员表,并在表中未找到该名称时返回TRUE。例如,您可以调用此函数并传递用户选择的喜爱蔬菜的字符串。尽管此调用将始终返回TRUE,但您仍将获得一个语法上正确的程序。

现在假设您有一个包含函数(=属性)NameIsUnique()的类PersonClass

最终您可能想要这样的代码:

Dim MySpouse as PersonClass
    Set MySpouse = New PersonClass
    MySpouse.Name = "Fanny Hill"
    If MySpouse.IsUnique() Then
        MySpouse.Insert
    End If

看起来有些过度,但实际上将与Person相关的代码块、函数和变量(这里称为方法和属性)封装到一个类中,使得使用该类模板的变量更加明显,将更容易理解你正在做什么(即该类的一个实例)。
典型示例:IP地址算术......(添加IP地址,查找基础或广播地址,转换各种掩码表示法,检查两个范围是否重叠,找到环绕两个或多个IP地址的网络掩码等等)。在十几个应用程序中都需要:编写类模块一次,并进行测试后,就可以轻松地重复使用它。
类的另一个优点是,在VBA编辑器中输入代码时,代码完成会精确告诉您可以对类做什么(即所有属性和方法都显示在下拉列表中)——这是过程和函数所没有的便利(它们只告诉您参数名称和类型)。
够了吗?

1

属性是用于类的。所以我想你真正的问题更多的是:“为什么要使用类模块?”确实,你可以在很多年里构建出优秀的应用程序而不需要那个需求。
我开始使用它们来处理非常特定的用途,比如读取复杂的文本文件(主机打印报告,逻辑记录跨越几个物理行)或从庞大而复杂的Excel工作表中获取特定信息。
一旦你完成了一个模拟你想要读取的项目的类,你就可以将该类从应用程序重用到应用程序,并集中精力处理你特定应用程序的逻辑,而不是处理同样的旧文件读取逻辑。


1
我为类创建了以下简单指南:
> has _return?
  |_ yes > has parameter?
  |        |_ yes: Function
  |        |_ no > likely verb?
  |                |_ yes: Function
  |                |_ no: Get
  |_ no > has parameter?
          |_ yes > likely verb?
          |        |_ yes: Sub
          |        |_ no > uses _object?
          |                |_ yes: Set
          |                |_ no: Let
          |_ no: Sub

它基于以下假设/定义:

Get

  • 返回值:是
  • 参数:否
  • 词形:形容词或不清楚

Function

  • 返回值:是
  • 参数:是/否
  • 词形:动词

Set/Let

  • 返回值:否
  • 参数:是
  • 词形:形容词或不清楚

Sub

  • 返回值:否
  • 参数:是/否
  • 词形:动词

0
此外,Let/Get组合或Set/Get组合为参数类型(Let/Set)和返回值(Get)设置了一种规范,以便可以在赋值语句的左侧使用函数。使得编程更加简洁!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接