Структура данных вложенного класса VBScript - PullRequest
3 голосов
/ 04 июля 2011

Моя проблема может быть проиллюстрирована в следующем примере кода, который устанавливает массив данных друзей, каждый из которых может иметь несколько телефонных номеров:

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 ]

14 голосов
/ 04 июля 2011

Массивы - это неправильная структура данных для решения этой проблемы.Они являются оружием выбора на других языках, их нет в VBScript, поскольку они общеизвестно негибки.

Подумайте об использовании Словари .И отбросьте венгерский.

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

  • Вы можете использовать функции и классы до того, как они будут определены в скрипте, поэтому поставьтевся ваша сантехника внизу.
  • Вы можете иметь Public и Private переменные класса
  • Классы имеют события Initiate и Terminate, которые вы можете отреагировать на
  • Имена функций являются объявлениями переменных.Не нужно объявлять временную переменную возврата в функции, вы можете использовать имя функции для этого.
  • Блок With может также сохранить временную переменную.
  • Даже еслисловарь сравнительно удобен, он все еще может быть полезен для удобства, поэтому я создал его.
1 голос
/ 07 июля 2011

Вот что я сделал, спасибо Томалаку за помощь.

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

Это сохраняет мою структуру такой же, и немного проще (на мой взгляд, в любом случае)

Я полагаю, вы могли бы изобрести какую-то функцию ReDim в Person_Class, чтобы выполнить ReDim для его элементов массива.Это было бы хорошо ...

...