【问题标题】:How do Class definitions work in VBA类定义如何在 VBA 中工作
【发布时间】:2014-02-25 12:53:08
【问题描述】:

当我尝试学习 VBA 时,课程让我感到非常痛苦!!!

这是我的一本 VBA 书籍(VBA 和宏 Microsoft Excel 2010 - Bill Jelen,第 497 页),这绝对是奇特的:

  1. 我们在 VBE 中打开一个类模块

  2. 我们正在类模块clsEmployee中编写自定义对象的4个属性和1个方法:

    'Properites   
    Public EmpName As String             
    Public EmpID As String   
    Public EmpRate As Double         
    Public EmpWeeklyHrs As Double
    
    'Methods   
    Public Function EmpWeeklyPay() As Double  
        EmpWeeklyPay = EmpRate * EmpWeeklyHrs  
    End Function
    
  3. 书中写道自定义对象现已完成

  4. 现在这本书去打开一个简单的模块(不是类模块)来引用另一个模块的自定义对象,所以它是这样的:

    Dim Employee as clsEmployee
    
    Set Employee = New clsEmployee
    
  5. 不是它呈现所有代码块。这里真正尴尬的是 Dim Employee as clsEmployee在子程序之外!为什么?(所以这可以看作是次要问题)

    Option Explicit
    
    Dim Employee as clsEmployee 'why is this outside of the code block?
    
    Sub EmpPay()
        Set Employee = New clsEmployee
    
        With Employee
            .EmpName = "Tracy Syrstad"
            .EmpID = "1651"
            .EmpRage = 25
            .EmpWeeklyHrs = 40
    
            MsgBox .EmpName & " earns $" & .EmpWeeklyPay & " per week."
        End With
    
    End Sub
    
  6. 这本书优雅地说:

该过程将对象Employee 声明为clsEmployee 的新实例。然后,它为对象的四个属性赋值,并生成一个显示员工姓名和周薪的消息框。对象的方法EmpWeeklyPay 是 用于生成显示的工资。

我被困在这里的人

据我所知,当我们在一个对象之后放置一个属性(一个原始的 VBA 制作,而不是来自类模块的自定义一个)
Application.Name
...VBA 返回一个表示对象名称的字符串值。好的,所以 VBA 不知何故知道如何做到这一点。但我无法理解如何在书籍范式中创建自定义属性只是通过输入没有硬编码的内容

Public EmpName As String
Public EmpID As String
Public EmpRate As Double
Public EmpWeeklyHrs As Double

...正如 Name 属性与 Value 属性不同,是什么创建了 4 个不同的属性?我的意思是他们的机制有什么不同?是什么让属性EmpNameEmpID 不同??? 据我所知,它们只是在类模块中声明的变量。我们如何仅通过在类模块中声明变量来创建自定义对象属性???如果你愿意,我们不应该以某种方式输入机械师、分界线和底盘,所以当我使用/设置EmpID 时,它会查看员工 ID 而不是他的名字。实际上向我保证的是,当我调用 EmpRate 时,它不会使用 EmpWeeklyHrs 它是相同的数据类型,并且在类模块的“蓝图”中没有其他类型的代码来阻止事情变得不可靠.肯定有一些硬编码的东西使ValueName 属性不同,我们怎么能只在自定义对象中声明变量?这对我来说毫无意义

感谢您观看我的长长长长的问题

【问题讨论】:

  • 也许要意识到的一件事是像Application 这样的内置类(在功能意义上)与您的自定义类做同样的事情。您不会期望Application.NameApplication.Intersect 混淆,对吧?当然不是,原因是这些属性在 Application 类中有不同的声明,就像你的 EmpIDEmpRate 一样。
  • 命名法:在第一个代码块中,您所称的属性实际上是变量,而您所称的方法是属性。
  • Dim Employee As clsEmployee 声明了对象变量 Employee,它将具有在类 clsEmployee 中定义的属性和行为。与Dim sLabel As String 相同的方式使用内置类 String 定义的属性和行为声明变量 sLabel。变量 Employee 直到 Set Employee = New clsEmployee 才被实例化(创建)。

标签: vba class


【解决方案1】:

根据我对您所问问题的理解,这是我的回答:

第一个问题:

Dim Employee as clsEmployee '为什么在代码块之外?

执行此操作时,您可以从代码的不同部分(子)引用 Employee。以下代码可以访问它。这是可选的。只有在需要时,您才能通过在所需的 sub 中指定 in 来使用上述行。这个概念通常在变量引用范围的概念下讨论。它对类对象并不特殊,但您使用的任何变量都遵循相同的规则。看看:Scope of variables in Visual Basic for Applications.

第二个问题:

实际上是什么向我保证,当我调用 EmpRate 时它不会消失 对于 EmpWeeklyHrs,它是相同的数据类型,没有其他 他们的“蓝图”类模块中的代码类型,以阻止事情发生 变得不可靠了。

编译器和解释器对变量名非常具体。自从在 Assembler 中使用寄存器以来,命名就是编码的基本方面。当您指定 Employee.EmpRate 时,将使用分配给 Employee.EmpRate 的地址中的数据,我认为它不可能将 Employee.EmpRate 与 Employee.EmpWeeklyHrs 混淆。这两个变量/属性具有不同的名称,因此将有 2 个不同的存储位置。

编辑用一个非常非常简化的插图来解释(这当然是现在发生的事情,但它是为了说明这个想法): 现在,当你编码时

Doc = Employee.EmpName 

VBA 转到名为“Employee”的实例的存储位置,发现名为“Name”的属性存储在距离对象值 1000 的基地址 8 个字符的位置。然后它去分配在位置 1008 找到的字符串“Scott”到变量 Doc。

【讨论】:

  • 当你从一个类创建一个新对象时,每个属性都被分配了一个不同的内存位置。在给定的类中,对 EmpRate 的引用将意味着对象的 EmpRate,该对象是在运行时在类被实例化时确定的(当从类创建对象时)。
  • 蓝图只是一个蓝图(可以把它想象成一个物品的购物清单),它在运行时间之前不包含任何特定值,即在执行之前(你的购物篮开始被填充实际购物时从购物清单中选择)。当你进入运行时,当你创建一个蓝图对象时,内存是根据你的蓝图规范分配的。
  • 是的,你不能在没有对象名的情况下引用类之外的属性。在类之外,当您执行 EmpID=5 时会出现错误,您必须先创建一个对象,例如 Employee,然后再执行 Employee.Empid=5。在类代码中,您可以使用 EmpID=5。
  • 可以使用以下格式引用属性:ObjectName.PropertyName。如果您已创建对象,则在您从蓝图创建对象时会识别“蓝图”。由于对象内的属性名称是唯一的,因此返回该属性的对应值。
  • 几分钟后我会为你提供一个简单的图表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
相关资源
最近更新 更多