|
Dictionary object allows storing key value pairs. A dictionary object can be used for easy lookup of values. Dictionary is a not a QTP specific functionality and is available in normal VBScript as well.
Creating the Dictionary
A dictionary object can be created using CreateObject for COM class "Scripting.Dictionary". The code below shows how to create the dictionary object in QTP
'Create the Dictionary Object
Set oDict = CreateObject("Scripting.Dictionary")
Methods
Below table shows list of methods that dictionary objects supports
Method
Description
Add (key, item)
Adds a key and item pair to a Dictionary object.
Exists(key)
Returns true if a specified key exists in the Dictionary object, false if it does not
Items()
Returns an array containing all the items in a Dictionary object
Keys()
Returns an array containing all existing keys in a Dictionary object.
Remove(key)
Removes a key, item pair from a Dictionary object
RemoveAll()
The RemoveAll method removes all key, item pairs from a Dictionary object.
Properties
Property
Description
Count
Returns the number of items in a Dictionary object. Read-only.
Item
Sets or returns an item for a specified key in a Dictionary object. Read/write
Key(Key)
Sets a key in a Dictionary object
Adding Items to Dictionary
There are two ways to Add items to dictionary. One is to use the Add method and another is to use the Item property. Both the methods are shown in code below
'Method 1 for Adding items to dictionary
'Add items to dictionary
oDict.Add "CA", "California"
oDict.Add "LA", "Los Angeles"
'The below line will throw an error as LA key already exist
oDict.Add "LA", "Los Angeles 2"
'Method 2 for adding items to dictionary
oDict.Item("CA") = "California"
'Item is the default property so ".Item" is not required
oDict("LA") = "Los Angeles"
'No Error this time as we are actually using the
'Item property and not the Add method
oDict("LA") = "Los Angeles 2"
Removing Items from Dictionary
Remove and RemoveAll methods allow to remove specified or all key(s) respectively. There usage is illustrated in the below code
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
oDict("TX") = "Texas"
oDict("IND") = "India"
'Displays "Texas"
MsgBox oDict("TX")
oDict.Remove "TX"
'Displays "Empty". The keys has been deleted and
'does not exists and when we try to access a non
'existent key, a new Empty item is created
MsgBox oDict("TX")
'Displays "India"
MsgBox oDict("IND")
'Remove all the keys
oDict.RemoveAll
'Displays Empty
MsgBox oDict("IND")
Changing Keys
The key property can use to change key of any item
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
oDict("IN") = "India"
'Change the IN key to IND
oDict.Key("IN") = "IND"
'Displays "India"
MsgBox oDict("IND")
'Displays "Empty"
MsgBox oDict("IN")
'Displays an error as the key IND is already
'associated with the value "India"
oDict.Key("IN") = "IND"
Checking Existence of an Item
We can check if an item exists or not using the exists methods as shown in code below
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
oDict("IN") = "India"
'Change the IN key to IND
oDict.Key("IN") = "IND"
'Displays "India"
MsgBox oDict("IND")
'Displays "Empty"
MsgBox oDict("IN")
'Displays an error as the key IND is already
'associated with the value "India"
oDict.Key("IN") = "IND"
Enumerating contents of a Dictionary
Items and Keys method returns the array of Items and keys respectively. These methods cannot be directly used to access the values, there return array has to be first assigned to a variable and then accessed. The code below illustrates the enumerations
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
oDict.Add "CA" , "California"
oDict.Add "LA" , "Los Angeles"
oDict.Add "TX" , "Texas"
aItems = oDict.Items
'Print all the items in the dictionary
For i = LBound(aItems) To UBound(aItems)
Print aItems(i)
Next
'Print all keys in the dictionary
'We can use For each loop also to access the array
aKeys = oDict.Keys
For Each Key in aKeys
Print "Key - " & Key
Print "Value - " & oDict(Key)
Next
Compare Mode
CompareMode property of the dictionary can be used to set the text comparison mode for key. By default it is set to 0 (vbBinaryCompare) which means keys "TX" and "Tx" are different. Changing the value for CompareMode to 1 (vbTextCompare) will make "TX", "tx", "tX" and "Tx" to be treated as the same key. CompareMode can only be changed when there are no items in the dictionary
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
oDict.Add "TX", "Texas"
'Will display Empty
MsgBox oDict("Tx")
'Remove all items
oDict.RemoveAll
'Changing the key comparison mode to text
oDict.CompareMode = vbTextCompare
oDict.Add "TX", "Texas"
'Displays Texas
MsgBox oDict("tx")
'The below line will throw an "Access is Denied" error
'As the property can only be changes when there are no
'items present in the dictionary
oDict.CompareMode = vbBinaryCompare
Using Dictionary to Hash Values
Dictionary objects support a HashVal method which can be used to get hashvalue for a text. This can be used when huge text arrays need to be compared. HashVal will always generate same values for same text.
'Create the dictionary object
Set oDict = CreateObject("Scripting.Dictionary")
'Displays 0
MsgBox oDict.HashVal("")
'Displays 570
MsgBox oDict.HashVal("Tarun Lalwani")
Extending the Dictionary Functionality
Dictionary object does not allow saving and loading dictionary to and from files. We can extend the dictionary object by using VBScript classes. The extended will provide the following new functionalities
LoadFromFile to load the dictionary from a CSV file. This will remove all previous items
AddFromFile to add the item to current dictionary from a CSV file.
ExportToFile to export the dictionarty to a CSV file.
LoadFromDictionary to load the dictionary from a dictionary object. This will remove all previous items
AddFromDictionary to add items from another dictionary object
AccessUsingIndex property with True/False value to allow item access using index also. The actual dictionary object only allows to access items based on keys. But some times it is required to access items or keys based on index.
The code below shows the extended dictionary class
Class DictionaryEx
'The actual dictionary that we will
Private oDict
'Private variable for storing value of AccessUsingIndex property
Private mAccessUsingIndex
'Now we need add all functions that the Dictionary already supports
Public Property Get HashVal(Text)
HashVal = oDict.HashVal(Text)
End Property
'Method to add a Key Value Pair
Public Sub Add(ByVal Key, ByVal Item)
oDict.Add Key, Item
End Sub
'Return the array of keys
Public Function Keys()
Keys = oDict.Keys
End Function
'Property to change key
Public Property Let Key(oldKey, newKey)
oDict.Key(oldKey) = newKey
End Property
'Returns array of items
Public Function Items()
Items = oDict.Items
End Function
'Check if certain key exists or not
Public Function Exists(Key)
Exists = oDict.Exists(Key)
End Function
'Remove All keys
Public Sub RemoveAll()
oDict.RemoveAll
End Sub
'Remove a specified key
Public Sub Remove (Key)
oDict.Remove GetKey(Key)
End Sub
'Get count of items in dictionary
Public Property Get Count()
Count = oDict.Count
End Property
'Get Property for CompareMode
Public Property Get CompareMode()
CompareMode = oDict.CompareMode
End Property
'Let Property for CompareMode
Public Property Let CompareMode(newMode)
oDict.CompareMode = newMode
End Property
'AccessUsingIndex is a flag which can be set to True/False
'If Set to True then Numeric Keys will be translated to index
'values and there corresponding keys will be used.
'In case the numeric value is an existing key in the dictionary
'then it would not be translated
Public Property Get AccessUsingIndex()
AccessUsingIndex = mAccessUsingIndex
End Property
'Let property for AccessUsingIndex
Public Property Let AccessUsingIndex(newValue)
If newValue = True Or newValue = False Then
mAccessUsingIndex = newValue
Else
'If anything other then True/False raise an error
Err.Raise vbObjectError + 1, "DictionaryEx", _
"AccessUsingIndex can only be set true/false."
End If
End Property
'Returns the actual dictionary object. This allows to do pass dictionary
'to function which might support the actual dictionarty object
Public Function Object()
Set Object = oDict
End Function
'Function to translate keys from Index to actual key
Private Function GetKey(Key)
'Return actual key in case we are not
'able to translate index to key
GetKey = Key
If Me.AccessUsingIndex Then
'If the key already exist we do not want to change
'anything even if it is a numeric value
If Not oDict.Exists(Key) And IsNumeric(Key) Then
keyIndex = CInt(Key)
'Check if index is within range
If keyIndex < Me.Count Then
Dim aKeys
aKeys = Me.Keys
'Translate from Index to Key
Key = aKeys(keyIndex)
Exit Function
End If
End If
End If
End Function
'Item is the Default property for dictionary. So we
'need to use default keyword with Property Get
'Default keyword can be used with a only one Function
'or Get Property
Public Default Property Get Item(Key)
'If a object is stored for the Key
'then we need to use Set to return the object
If IsObject(oDict.Item(GetKey(Key))) Then
Set Item = oDict.Item(GetKey(Key))
Else
Item = oDict.Item(GetKey(Key))
End If
End Property
'Let property Item
Public Property Let Item(Key, Value)
'Check of the value is an object
If IsObject(Value) Then
'The value is an object, use the Set method
Set oDict(GetKey(Key)) = Value
Else
'The value is not an object assign it
oDict(GetKey(Key)) = Value
End If
End Property
'Property Set Item
Public Property Set Item(Key, Value)
Set oDict(GetKey(Key)) = Value
End Property
'AddFromDictionary takes an actual dictionary object and
'add all keys from it
Public Sub AddFromDictionary(oldDict)
aKeys = oldDict.Keys
Me.AccessUsingIndex = False
For Each sKey In aKeys
oDict(sKey) = oldDict(sKey)
Next
End Sub
'LoadFromDictionary function removes all keys
'and then add the keys from dictionary. It is
'equivalent of creating a clone from a existing
'dictionarty object
Public Sub LoadFromDictionary(oldDict)
oDict.RemoveAll
Me.AddFromDictionary oldDict
End Sub
'Function to read dictionary key/value from file
Public Sub AddFromFile(FileName, Delimiter)
Set FSO = CreateObject("Scripting.FileSystemObject")
Set oFile = Fso.OpenTextFile (FileName)
'Read the file line by line
While Not oFile.AtEndOfStream
sLine = oFile.ReadLine
KeyValue = Split(sLine, Delimiter)
oDict(KeyValue(0)) = KeyValue(1)
Wend
Set oFile = Nothing
Set FSO = Nothing
End Sub
'Function to remove all keys and then load it from
'file
Public Sub LoadFromFile(FileName, Delimiter)
oDict.RemoveAll
Me.AddFromFile FileName, Delimiter
End Sub
'Export the dictionarty to a file and use Delimiter
'to seperate Key and Value pairs
Public Sub ExportToFile(FileName, Delimeter)
Set FSO = CreateObject("Scripting.FileSystemObject")
Set oFile = FSO.CreateTextFile(FileName, True)
Dim aKeys
aKeys = oDict.Keys
'Write the key value pairs line by line
For Each sKey In aKeys
oFile.WriteLine sKey & Delimeter & oDict(sKey)
Next
'Close the file
oFile.Close
Set oFile = Nothing
Set FSO = Nothing
End Sub
'Intialize event gets executed whenever a object is created
Sub Class_Initialize()
Set oDict = CreateObject("Scripting.Dictionary")
Me.AccessUsingIndex = False
End Sub
'Executed when the object is destroyed
Sub Class_Terminate()
'Remove all the keys
oDict.RemoveAll
'Destroy the dictionary
Set oDict = Nothing
End Sub
End Class
Below code illustrates the usage of the extended dictionary.
Set xDict1 = New DictionaryEx
Set xDict2 = New DictionaryEx
xDict1("CA") = "California"
xDict1("IND") = "India"
xDict1("FL") = "Florida"
'Export the dictionary
xDict1.ExportToFile "C:\Dict.txt", "###"
'Load dictionarty from file
xDict2.LoadFromFile "C:\Dict.txt", "###"
'Displays India
MsgBox xDict2("IND")
Set oDict = xDict2.Object
'Display Florida
MsgBox oDict("FL")
xDict2.AccessUsingIndex = True
'Displays "California"
MsgBox xDict2(0)
'Displays "India"
MsgBox xDict2("IND")
'Displays "India"
MsgBox xDict2(1)
In case you add the DictionaryEx class to a VBS file and associate it to the Test; Trying to create a object of DictionaryEx class will cause an error. This happens because global libraries in QTP are loaded outside the action scope and the classes are not visible to the action scope. The workaround is to create a function in the VBS that creates the object and returns it reference
Public Function NewDictionaryEx()
Set NewDictionaryEx = New DictionaryEx
End Function
Dictionaries as Reserved Object in QTP
QTP allows adding any COM object as reserved object by adding its information to the Registry. To add Dictionary as one of the objects, follow the below mentioned steps
Open Regedit.exe through windows run window
Browse to HKEY_CURRENT_USER\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects
Create a new key under this key with Name as "Dictionary" and as String value "ProgID" with data as "Scripting.Dictionary" as shown in below screenshot
Start QTP, type "Dictionary." and we will not get the intellisense for the same as shown in the image below
Summary
In this article we learned
How to use dictionary objects
Extending the dictionary objects
Using dictionary object as Reserved QTP objects |
|