开发者

Creating a complex structure with Scripting Dictionary - VBScript

I am trying to understand some code so that i can make modifications to it. I am fairly new at vbscript so any help is appreciated .

I am looking at a Dictionary object that looks like it is behaving like a table with different rows controlled by a key. I am not sure what is happening. commands like list.add list.count+1 , ListElement are a little over my league right now. The code is able to output data for 1 use with simple statement

Sub DumpList ( list )
' This function dumps all the people in the office and their information 
' in the application window. The list is usually sorted by Name.

Dim e, le

For Each e In list ' output listelements...
    Set le = list(e)

    LogOutput 0, "line: " & (le.num, 3) & " : " & le.Name _
                & " " & le.PHNumber1 & " 开发者_如何转开发" & le.PHNumber2 _
                & " " & le.Email1 & " " & le.Email2 _
                & " " & le.DeskNo.1 & " " & le.OFficeCode _
                & " " & le.wirecolour & " " & le.wirecross 
Next
End Sub

I am not sure how it is working for me to make any changes to it.

Thanks again


The task: Maintain a collection of persons.

First attempt at a solution: Use a dictionary with numerical indices=keys, based on dic.Count

As sanwar pointed out, a dictionary stores key-value pairs. To put (info about) persons in a dictionary, we need a person class from which we can create person objects/instances to hold the multiple information elements.

Minimal/POC code for a Person class:

Dim g_nPersonId : g_nPersonId = -1
Class cPerson
  Private m_nId
  Private m_sName
  Private m_dtBirth
  Private m_dWage
  Public Function init( sName, dtBirth, dWage )
    Set init    = Me
    g_nPersonId = g_nPersonId + 1
    m_nId       = g_nPersonId
    Name        = sName
    Birth       = dtBirth
    Wage        = dWage
  End Function  
  Public Property Let Name(  sName   ) : m_sName   = sName     : End Property
  Public Property Let Birth( dtBirth ) : m_dtBirth = dtBirth   : End Property
  Public Property Let Wage(  dWage   ) : m_dWage   = dWage     : End Property
  Public Property Get Id()             : Id        = m_nId     : End Property
  Public Property Get Name()           : Name      = m_sName   : End Property
  Public Property Get Birth()          : m_dtBirth = m_dtBirth : End Property
  Public Property Get Wage()           : m_dWage   = m_dWage   : End Property
  Public Function Data()
    Data = Array( m_nId, m_sName, m_dtBirth, m_dWage )
  End Function  
End Class ' cPerson

[The class cPerson defines/blue prints persons, each having an id, a name, a dob, and a salary. You create persons by calling the init function passing suitable values for name, doc, and wage members; the id will augmented automagically (by using a global counter instead of proper class level data as possible in more capable OO languages).]

and a demo script to prove we can create and display persons:

  Dim oAdam : Set oAdam = New cPerson.init( "Adam", #1/5/2001#, 1234.56 )
  Dim oEve  : Set oEve  = New cPerson.init( "Eve" , #1/6/2001#, 6543.21 )
  Dim oPerson
  For Each oPerson In Array( oAdam, oEve )
      WScript.Echo Join( oPerson.Data(), " - " )
  Next    

output:

0 - Adam - 1/5/2001 - 1234.56
1 - Eve - 1/6/2001 - 6543.21

Now lets put them in a dictionary with numerical keys (a VBScript special feature, other languages have string-key-only dictionaries) based on the .Count property. The .Count property of an empty dictionary is 0, by adding the first element (a person object holding all info we need) to the dictionary its .Count increments to 1 (ready for the next addition). You easily can see that .Add .Count + 1 is a waste of time/effort:

  Dim dicPersons : Set dicPersons = CreateObject( "Scripting.Dictionary" )
  Dim aPersons   : aPersons       = Array( _
        Array( "Adam", #1/5/2001#, 1234.56 ) _
      , Array( "Eve" , #1/6/2001#, 6543.21 ) _
  )
  Dim aPerson
  For Each aPerson In aPersons
      dicPersons.Add dicPersons.Count, New cPerson.init( aPerson( 0 ), aPerson( 1 ), aPerson( 2 ) )
  Next
  Dim nPerson
  WScript.Echo "Adam & Eve"
  For Each nPerson In dicPersons
      WScript.Echo nPerson, ":", Join( dicPersons( nPerson ).Data(), " - " )
  Next    
  dicPersons.Remove 0 ' how do we know the key of Adam?
  WScript.Echo "Adam zaped"
  For Each nPerson In dicPersons
      WScript.Echo nPerson, ":", Join( dicPersons( nPerson ).Data(), " - " )
  Next    
  WScript.Echo "Trying to add Caine"
 On Error Resume Next 
  dicPersons.Add dicPersons.Count, New cPerson.init( "Caine", Date(), 0.33 )  
  WScript.Echo Err.Description
 On Error GoTo 0

The output

Adam & Eve
0 : 0 - Adam - 1/5/2001 - 1234.56
1 : 1 - Eve - 1/6/2001 - 6543.21
Adam zaped
1 : 1 - Eve - 1/6/2001 - 6543.21
Trying to add Caine
This key is already associated with an element of this collection

shows why dictionaries with numerical indices based on .Count are no solution for the task: Maintain a collection of persons.


In this case the variable list holds a Scripting.Dictionary.

When you use the VBScript For Each construct on Scripting.Dictionary each key in the dictionary is returned. So in this case the For Each will loop place each key in the variable e on each iteration.

The Line:-

 Set le = list(e)

is now using the key for this loop to lookup the value in the dictionary associated with the key. In this case the value is an object that has properties.

Hence a dictionary can be used to quickly and directly lookup a "row" in a "table" using its key. Also as the code you've posted demonstrates you can enumerate each key and lookup each value to "scan" the whole "table".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜