类"让"卡在无限循环中

Gra*_*rry 4 excel vba excel-vba

原谅代码中的任何愚蠢错误,因为这是我第一次尝试使用类,我找不到任何在线教程,这些教程非常简单地用于像我这样的傻瓜.我尽力按照https://msdn.microsoft.com/en-us/library/aa716315(v=vs.60).aspx上的MS指南,但我真的不明白我是什么无论如何,这很难解释我应该改变什么.

我正在尝试创建一个存储三个数据,两个整数和一个字符串的类.我把它放在一个名为的类模块中tdata:

Sub tdata()

Dim tnumber As Integer, tacct As Integer
Dim ttype As String

Public Property Get t_acct() As Integer         'don't forget the account number!
    t_acct = tacct
End Property

Public Property Let t_acct(ByVal newval As Integer)
    t_acct = newval
End Property

Public Property Get t_numb() As Integer         'T1, T2, or T3 as applicable
    t_numb = tnumb
End Property

Public Property Let t_numb(ByVal newval As Integer)
    t_numb = newval
End Property

Public Property Get t_type() As String          'PF or MW
    t_type = ttype
End Property

Public Property Let t_type(ByVal newstr As String)
    t_type = newstr
End Property

End Sub
Run Code Online (Sandbox Code Playgroud)

然后我在我的函数中调用它

Set t_info = New tdata
t_info.t_acct = wb2.Sheets(1).Cells(d, 1)             'd is just a row counter in a for loop
t_info.t_numb = Right(wb2.Sheets(1).Cells(d, 4), 1)
t_info.t_type = wb2.Sheets(1).Cells(d, 6)
references(CStr(wb2.Sheets(1).Cells(d, 5))).Add t_info
Run Code Online (Sandbox Code Playgroud)

(当然,这不是所有代码,而只是调用它的部分)

我已经拥有了Option Explicit所有有趣的东西并且所有内容编译都很好,但是当它到达函数代码段的第二行时,它尝试使其t_info.t_acct等于某个东西,它将转向该Let函数,然后停留在那里. .永远.具体来说,它在两者之间反弹

Public Property Let t_acct(ByVal newval As Integer)
    t_acct = newval
Run Code Online (Sandbox Code Playgroud)

永远.为什么是这样?如何设置(错误,让)t_acct等于我想要的东西?

Mat*_*don 13

你的问题在这里:

Public Property Let t_acct(ByVal newval As Integer)
    t_acct = newval
End Property
Run Code Online (Sandbox Code Playgroud)

那应该是分配封装的field(tacct),而不是它自己.


我将给你我的秘方:每当我创建一个新的类模块时,我都会以私有类型开头:

Option Explicit
Private Type TData 'assuming class module is named 'Data'
    Number As Integer
    Account As Integer
    AccountType As String
End Type
Run Code Online (Sandbox Code Playgroud)

然后,我声明了一个这种类型的私有字段,命名为this:

Private this As TData
Run Code Online (Sandbox Code Playgroud)

有些人可能会争辩说,this因为this(私有字段)不是Me(对象实例)而在其他语言中this引用了对象实例等等 - 如果它让你感到困惑,那就给它你喜欢的任何名字(backing并且encapsulated是完全没问题!).

现在所有的属性都变得清晰,一致:

Public Property Get Number() As Integer
    Number = this.Number
End Property

Public Property Let Number(ByVal value As Integer)
    this.Number = value
End Property

Public Property Get Account() As Integer
    Account = this.Account
End Property

Public Property Let Account(ByVal value As Integer)
    this.Account = value
End Property

Public Property Get AccountType() As String
    AccountType = this.AccountType
End Property

Public Property Let AccountType(ByVal value As String)
    this.AccountType = value
End Property
Run Code Online (Sandbox Code Playgroud)

Property Get成员返回this.ThePropertyName,Property Let成员使用提供的- 总是分配 .如果属性需要是非get-only的对象类型,则需要提供成员:this.ThePropertyNamevalueProperty Set

Private Type TData
    '...
    SomeObject As Object
End Type
Private this As TData    

Public Property Get SomeObject() As Object
    Set SomeObject = this.SomeObject
End Property

Public Property Set SomeObject(ByVal value As Object)
    Set this.SomeObject = value
End Property
Run Code Online (Sandbox Code Playgroud)

避免使用dismvoweling,前缀和不可读/无意义的名称,PascalCase用于公共成员,支持一致性,以及做任何事情,避免公共类成员姓名中的下划线 - 否则您希望开始使用Implements的那一天就是您的代码停止编译的那一天.接下来,您的课程模块应该始终清晰.

  • 真的很有趣.当你有时间时,你应该考虑通过一些专门的线程分享对它的好处的全面讨论.这不仅仅是对问题的简单回答.感谢分享. (4认同)
  • 啊哈,这个私有类型的习语非常有趣。尽管我没有立即看到它的其他好处,但是我可以想象。它已经允许私有字段和属性获取器/字母的名称完全相同。还有“这个”名称,对于C ++ / Java程序员来说是一个极具挑战性的选择!真好 将采用。 (2认同)
  • @ASH的直接好处是命名的一致性,这使*错误*代码,*看起来错误*; 另一个可能不那么明显的好处是,序列化变得毫无疑问 - 你只需要把'fn ,,这个'放进去就完成了!在C#中我使用`private readonly int _someInt;`和`public int SomeInt {get {return _someInt; ` - 我只在C#中使用`this`,因为我需要*来引用类实例..这几乎从来没有(与VBA的"我"相同,来考虑一下). (2认同)
  • @ASH - 我是使用私有成员类型的转换(除了`this`部分).`this.Number`*看起来像是对我的C#眼睛的递归 - 我选择的名字是"支持`". (2认同)