VBScript嵌套类数据结构

时间:2011-07-03 21:06:47

标签: arrays class vbscript nested-class

我的问题可以在下面的示例代码中说明,该代码设置了一个朋友的数据数组,每个朋友都可以有多个电话号码:

Class clsPhoneNo
  Dim strType
  Dim strNumber
End Class

Class clsPerson
  Dim strName
  Dim aclsPhoneNo()
End Class

Dim clsFriends()
ReDim clsFriends(3)
Set clsFriend(0) = New Person
clsFriend(0).strName = "Fred"
Set clsFriends(0).aclsPhoneNo(0) = New clsPhoneNo
ReDim clsFriend(0).aclsPhoneNo(2)
Set clsFriend(0).aclsPhoneNo(0).strType = "Home"
Set clsFriend(0).aclsPhoneNo(0) = "01234567890"
Set clsFriend(0).aclsPhoneNo(1).strType = "Work"
Set clsFriend(0).aclsPhoneNo(1) = "09876543210"

然而,VBScript说

Microsoft VBScript compilation error: Expected end of statement

之前。在第二个ReDim声明

我需要让aclsPhoneNo元素变量长度,因为我的代码实际上并不是一本地址簿,但这是一个证明问题的简单例子。

有什么想法吗?

2 个答案:

答案 0 :(得分:14)

数组是解决此问题的错误数据结构。它们是其他语言的首选武器,它们不属于VBScript,因为它们非常不灵活。

请考虑使用Dictionaries。并放弃匈牙利人。

Dim phoneBook: Set phoneBook = New ObjectList

With phoneBook.Append(New Person)
  .Name = "fred"
  .AddPhoneNo "Home", "01234567890"
  .AddPhoneNo "Work", "09876543210"
End with

Dim pers: Set pers = phoneBook.Item(1)

For Each id In pers.PhoneNos.List
  Set num = pers.PhoneNos.List(id)
  WScript.Echo pers.Name & " #" & id & ": " & _
               num.Number & " (" & num.Label & ")"
Next

' ------------------------------------------------------
Class ObjectList
  Public List

  Sub Class_Initialize()
    Set List = CreateObject("Scripting.Dictionary")
  End Sub

  Sub Class_Terminate()
    Set List = Nothing
  End Sub

  Function Append(Anything) 
    List.Add CStr(List.Count + 1), Anything 
    Set Append = Anything
  End Function

  Function Item(id) 
    If List.Exists(CStr(id)) Then
      Set Item = List(CStr(id))
    Else
      Set Item = Nothing
    End If
  End Function
End Class

' ------------------------------------------------------
Class PhoneNo
  Public Label
  Public Number
End Class

' ------------------------------------------------------
Class Person
  Public Name
  Public PhoneNos

  Sub Class_Initialize()
    Set PhoneNos = New ObjectList
  End Sub

  Function AddPhoneNo(Label, Number)
    Set AddPhoneNo = New PhoneNo
    With PhoneNos.Append(AddPhoneNo)
      .Label  = Label
      .Number = Number
    End With
  End Function
End Class 

请注意,我在这里使用了一些VB功能

  • 您可以在脚本中定义函数和类之前使用它们,因此请将所有管道放在底部。
  • 您可以拥有PublicPrivate类变量
  • 课程有InitiateTerminate事件,您可以对此作出反应
  • 函数名称是变量声明。无需在函数中声明临时返回变量,您可以使用函数名称。
  • With块也可以为您保存一个临时变量。
  • 即使字典比较方便,它仍然可以从便利包装中受益,所以我创建了一个。

答案 1 :(得分:1)

这是我所做的,感谢Tomalak的帮助。

Class PhoneNo_Class
  Dim strType
  Dim strNumber
End Class

Class Person_Class
  Dim strName
  Dim aclsPhoneNo()

  Sub Class_Initialize()
    strName = ""
    ReDim aclsPhoneNo(0)                 'Set up entry 0 which is never used but prevents errors accessing UBound etc.
    Set aclsPhoneNo(0) = New PhoneNo_Class
  End Sub

  Sub AddPhoneNo(ByRef rstrType, ByRef rstrNumber)
    ReDim Preserve aclsPhoneNo(UBound(aclsPhoneNo) + 1)
    Set aclsPhoneNo(UBound(aclsPhoneNo)) = New PhoneNo_Class
    With aclsPhoneNo(UBound(aclsPhoneNo))
      .strType   = rstrType
      .strNumber = rstrNumber
    End With
End Sub

End Class

Dim clsFriends()
ReDim clsFriends(3)
Set clsFriends(1) = New Person_Class
With clsFriends(1)
  .strName = "Fred"
  .AddPhoneNo "Home", "01234567890"
  .AddPhoneNo "Work", "09876543210"
  WScript.Echo .strName & "'s " & .aclsPhoneNo(2).strType & " phone number is " & .aclsPhoneNo(2).strNumber
End With

这使我的结构保持不变,并且有点简单(无论如何,我的想法)

我想你可以在Person_Class中发明某种ReDim函数来对其数组成员执行ReDim。那太好了......