Anda di halaman 1dari 14

Dictionary Object in QTP.

A complete guide
Today we will see a less talked about and not so often used Dictionary Object in QTP. Note that, this is not something very QTP specific. Dictionary object was developed by Microsoft and is part of VB Scripting. What is Dictionary Object? In simple terms, Dictionary object is similar to a typical array. The difference between a dictionary object and an array is that there is a unique key associated with every item of dictionary object. This unique key can help you in calling that item as and whenever required. What is the syntax and how can we use dictionary object? Shown below is a typical script. Dim dict Create a variable. Set dict = CreateObject(Scripting.Dictionary) dict.Add Company, HP Adding keys and corresponding items. dict.Add Tool, QuickTest Pro dict.Add Website, LearnQTP dict.Add Country, India dict is an object of class Scripting.Dictionary. Company-HP, Tool-QuickTest Pro, Website-LearnQTP, Country-India are key-item pairs that were added using Add method on dict object. Other methods available for dictionary object are Exists Method, Items Method, Keys Method, Remove Method, RemoveAll Method Using Exists Method to check whether the key Country exists? If dict.Exists(Country) Then msg = Specified key exists. Else msg = Specified key doesnt exist. End If Using Items and Keys method to retrieve ALL items and keys respectively from inside dictionary object. i = dict.Items Get the items. k = dict.Keys Get the keys. For x = 0 To dict.Count-1 Iterate the array. msgbox i(x) & : & k(x) Next

Using Remove method to remove Website LearnQTP pair from the object. dict.Remove(Website) Using Remove all method to clear the dictionary dict.RemoveAll Clear the dictionary. What are the places where it can be used? When you want to share data between different actions in a test, dictionary object can be used. To do this you should create a reserved test object for the Dictionary object. Here is a process to set up a reserved dictionary object. [Source] 1. Open Windows registry by opening a Run window and entering regedit. 2. Navigate to HKEY_CURRENT_USER\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects. 3. Create a new key (folder) named GlobalDictionary by right-clicking on the ReservedObjects key and selecting New -> Key. 4. Under the new key, create a String value named ProgID by right-clicking on GlobalDictionary and selecting New -> String Value. 5. Assign Scripting.Dictionary to the new ProgID string value by right-clicking on ProgID and selecting Modify. 6. If QTP window is already open you need to close and restart it. 7. Now to check whether dictionary object was installed successfully in registry, simple write GlobalDictionary. (dont forget the dot) and you should see a drop-down containing all methods and properties associated with dictionary object.

Why dictionary object and why not array only? As shown in the example above, dictionary object was used with the index (key) being string. In the case of array, the index can be ONLY numeric. Then of course we have some obvious advantages like referencing a value with a meaningful keys etc.

What are the other places where it can be used? Alex Dinu has written a good article where he found the usefulness of dictionary object. Microsoft has another nice article on where Dictionary Object can be used. Over to you. Have you used dictionary object in the past? Why? I have used dictionary object to remove duplicates in an array. I ll paste the code here. I hope it helps. here, I have 2 arrays, TC() and Status() TC contains test case IDs and Status contains their respective status. Of course, a TC ID can be repeated multiple time having multiple statuses like Test Passed or Test Failed. My objective was to create a file that has the final status. If all the statuses for a test case is Test passed, it passes. Else, it is failed. The following function converts the array to a dictionary object and removes the duplicated and also consolidates the status holding only the final status. Thus, it is ready to be pasted to an excel file and sent to the manager. Public Function converToDictionary( TC, Status) Dim dict, j, k k = Ubound(TC) msgbox k Set dict = CreateObject(Scripting.Dictionary) For j = 0 to k If dict.Exists(TC(j)) then If dict(TC(j)) = Test Passed then dict.Remove(TC(j)) dict.add TC(j), Status(j) End If Else dict.add TC(j), Status(j) End If strMsg = strMsg & TC(j)& : & dict.Item(TC(j)) & vbcr Next Set converToDictionary = dict End Function

The Dictionary Objects


Welcome to Sesame Script, the column for beginning script writers. The goal of this column is to teach the very basics of Windows scripting for system administration automation. Well provide you with the information youll need to begin reading and understanding scripts and to start modifying those scripts to suit your own needs. If theres anything in particular about scripting youre finding confusing, let us know; youre probably not alone. Check the Sesame Script Archives to see past articles. On This Page Introduction The Dictionary Object A Unique Individual An Example that Doesnt Use the Dictionary Object An Example that Does Use the Dictionary Object Other Things You Should Know About the Dictionary Object More Information In Closing Introduction Was that occassionally, occasionally, or occassionaly? What in the world is a clevis? Should I be using e-mail as a verb? How do you pronounce puisne? No, these are not difficult questions. Granted, you might not know the answers to all of them off the top of your head, but its easy enough to find those answers: just check the dictionary. Dictionaries are great inventions, arent they? Everything is in order, everything is easy to find, and dictionaries are packed with information about practically every word in a given language, and even some in other languages. Where would we be without dictionaries? Lets see - wed probably spell though as tho or thoe, laugh would be a thing of the past, and many people would never know what scabies is. Maybe dictionaries werent such a great idea after all. Okay, despite the difficulties proliferated by dictionaries (at least in English), they really are incredibly useful, so useful that there are even different types of dictionaries. There are crossword puzzle dictionaries, Scrabble dictionaries, medical dictionaries, and - believe it or not - a scripting Dictionary. Top of page The Dictionary Object If youre now imagining a book with entries like CScript and For-Next, all nicely alphabetized and defined, well, thats not what were talking about. You can find something like that on MSDN, but its called an SDK and it more closely resembles

an encyclopedia (but without all the cool pictures). The dictionary were talking about is the Scripting.Dictionary object. The Dictionary object doesnt provide pronunciations or even definitions, but it does provide an easy way to store and look up information within a script. Heres how it works. Top of page A Unique Individual A Dictionary object is a little bit like an array in that it can hold a list of values. Those values can be of just about any type: strings, dates, numbers, and so on. You can use a For Each loop to loop through the objects in a Dictionary object. However, while an array is a great way to iterate through a list of values, its functionality is somewhat limited compared to the Dictionary object. Rather than being just a simple list of values, a Dictionary object consists of a collection of what are called key-item pairs. That sounds like a fancy technical term, doesnt it? Its really not so fancy - it just means that each entry in the list consists of two elements: a key and an item. See, now key-item pair just seems very unimaginative doesnt it? A key is a unique entry: no two keys within a single Dictionary object can be the same. The item is just a value that goes along with a particular key. You can have as many duplicate items as you want, its only the keys that need to be unique. For example, your Dictionary could look like this: Key Myer Accountant Pilar Ackerman Clerk Ellen Adams Accountant Michael Holm Gardener The names are the keys, and the occupations are the items. As you can see, no two names are alike, but we do have more than one Accountant. Note: You can use the same value for the key and the item, like this: Key Myer Key Myer Pilar Ackerman Pilar Ackerman Ellen Adams Ellen Adams Michael Holm Michael Holm Were not entirely sure why youd want to, but it does come up sometimes. Doing this does not change the fact that the keys all must be unique.

If youve ever worked with a database you might be thinking that this looks pretty familiar. This is amazing: so far weve compared the Dictionary object to a dictionary, an array, and now a database. Wow, what is this thing, really?

Its a little bit of everything. It gives you the power of looking up entries, as well as the unique identification provided in dictionaries and databases; it gives you, the ease of use of dictionaries and arrays;, and, heres the one we havent mentioned yet, the Dictionary object works in memory, just like an array. You create the Dictionary object within your script, use the object for whatever you need to use it for, then it disappears when the script ends. Top of page An Example that Doesnt Use the Dictionary Object All right, enough of this theory of the dictionary universe; were sure youre wondering by now how this thing works and what in the world youd actually use it for. We can help you with the former, but while we can give you a suggestion for the latter youll be much better able to determine good uses for this object in your own situation than we are. The best thing to do, of course, is to give you an example. Suppose you want to find out the state of all services on a machine. Thats simple; just use a WMI query, like this:
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service") For Each objService in colServices Wscript.Echo "Name: " & objService.Name Wscript.Echo "State: " & objService.State Next

In this script we connect to the WMI service on the local computer and then query the Win32_Service class to get a collection of all the services on the computer. (You could run this query against a remote computer by changing the value of strComputer from a dot [.] to the name of the remote computer.) We then simply loop through the collection of services using a For Each loop and echo back the Name and State properties of each service. When we run the script we get back something like this:
Name: Alerter State: Stopped Name: ALG State: Running Name: AppMgmt State: Stopped Name: aspnet_state State: Stopped ...

Nice, huh? True, we could have formatted it a little better and made it a little more readable, or even written the output to an Excel spreadsheet. But what if what we

really wanted to do was list the services that are stopped? Well, in that case we could just change our query from
Select * from Win32_Service

to
Select * from Win32_Service Where State = 'Stopped'

This gives us a collection of all the stopped services, which enables us to echo back the name of the stopped services, like this:
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service Where State = 'Stopped'") Wscript.Echo "Stopped Services:" For Each objService in colServices Wscript.Echo objService.Name Next

This script is almost identical to the previous one; for one thing, it starts out by connecting to the WMI service on the local computer. We then query for all services, but this time specifying that we want only the services where the State is equal to Stopped. We then loop through the collection of stopped services and echo the name of each service. But now suppose you also want some information about the services that are running? You wouldnt be able to read the query results into an array because an array (at least not the kind of arrays beginning scripters are used to) can hold either the name of each service or the state but not both. Instead youd end up doing multiple queries trying to get the information youre after. Or, you could go the easy route and use the Dictionary object. Top of page An Example that Does Use the Dictionary Object First things first. We cant list services or do anything else with the Dictionary object until we have keys and items in the object. So, as we typically try to do here in Sesame Script, well start with step one, creating and populating the Dictionary object.
strComputer = "." Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service") Set objDictionary = CreateObject("Scripting.Dictionary") For Each objService in colServices objDictionary.Add objService.Name, objService.State Next

In this script we once again connect to WMI on the local computer, then run a query to retrieve all the services on the computer. Nothing new there. Then we run into this line:
Set objDictionary = CreateObject("Scripting.Dictionary")

All were doing here is creating an instance of the Dictionary object, or, more precisely, the Scripting.Dictionary object. Once we have a Dictionary object we set up a For Each loop to loop through our collection of services and add each one to the Dictionary object. We add the services to the Dictionary object by using, what else, the Add method:
objDictionary.Add objService.Name, objService.State

As you can see, the Add method takes two parameters. The first is the value we want to use as the key to our dictionary entry, in this case the Name of the service. The second is the value we want to use for the item; here were using the State of the service. We loop through the collection of services, adding the names of all the services and the corresponding states of those services to the Dictionary object. Because we dont echo anything or do anything else the script just ends at that point. How do we know those entries were actually added to the Dictionary? Well, the fact that the script didnt crash is one clue. A better clue would be to actually do something with those entries. Lets start by simply listing all the stopped services:
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service") Set objDictionary = CreateObject("Scripting.Dictionary") For Each objService in colServices objDictionary.Add objService.Name, objService.State Next colKeys = objDictionary.Keys For Each strKey in colKeys If objDictionary.Item(strKey) = "Stopped" Then

Wscript.Echo strKey End If Next

We start out with our previous script, retrieving all the services and adding their names and states to the Dictionary object. Now it starts to get interesting. (You mean it hasnt been interesting so far?) The first thing we do is get a collection of all the keys we added to our Dictionary object. We do that by calling the Keys method of the Dictionary object:
colKeys = objDictionary.Keys

The colKeys variable now contains a collection of all the keys in our Dictionary object, which, as we know, happens to be the names of all the services running on the computer. (We know that because we just added them with the Add method, remember?) The next thing we do is loop through that collection of keys (services) using a For Each loop. For each key in our collection, we want to check the Item property, which contains the state of the service, and see if the state is Stopped. How do we check the Item property? Like this:
If objDictionary.Item(strKey) = "Stopped" Then

As we already mentioned, keys must be unique, but not items. That means theres really no way to directly access a particular Dictionary entry based on item, you have to access an entry based on the unique key. (You can look for all the items - well show you how to do that in a minute.) To do that we use the Item property and pass it the key of the entry were interested in. Since were looping through all the keys, we use the value of each key, strKey, and pass that to the Item property to get the value of the item associated with that key. Does that make sense? Okay, lets say our key contains the service Alerter. We pass Alerter to the Item property to find out the state of the Alerter service, which is contained in the item part of the key-item pair for that entry. Does it make sense now? We hope so. In our If Then statement we retrieve the item associated with the key and compare that to Stopped, the state were looking for. If the item is equal to Stopped we echo back the name of the key (service):
If objDictionary.Item(strKey) = "Stopped" Then Wscript.Echo strKey End If

If the value of the item is not Stopped we ignore it and loop around to the next key in the collection. When were done well have a list of all the services that were stopped at the time the query was run. (And yes, it is possible that a service could have been started in the fraction of a second it took us to get the values into and out of the Dictionary object, That means that theres a small possibility youre results arent 100% accurate. But, hey, give us a break: this is just an example!)

What have we accomplished so far? Well, basically the same thing we had accomplished in our non-Dictionary example. Pretty compelling, isnt it? All right then, maybe we should take this a step farther. How about we get a list of all the Stopped processes, and a list of all the Running processes? This requires just a small addition to our previous script:
strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service") Set objDictionary = CreateObject("Scripting.Dictionary") For Each objService in colServices objDictionary.Add objService.Name, objService.State Next colKeys = objDictionary.Keys Wscript.Echo "Stopped:" For Each strKey in colKeys If objDictionary.Item(strkey) = "Stopped" Then Wscript.Echo strKey End If Next Wscript.Echo Wscript.Echo "Running:" For Each strKey in colKeys If objDictionary.Item(strkey) = "Running" Then Wscript.Echo strKey End If Next

All weve done is add a few Wscript.Echo statements, copied our existing For Each loop ,and made one small change. Really simple. (Yes, really.) After we retrieve our collection of keys we echo Stopped: because we want to separate our Stopped list from our Running list. After weve echoed all the stopped services we put in a Wscript.Echo statement to insert a blank line - we want an obvious separation between our two lists - and then we echo Running: to introduce our list of running services. After that we have a For Each loop thats identical to the loop that checks for stopped services, but we replace Stopped with Running in the If Then statement. See, it really is that simple. Heres what the results look like:
Stopped: Alerter AppMgmt aspnet_state Ati HotKey Poller ... Running: AdobeActiveFileMonitor

AudioSrv BITS CcmExec CryptSvc DcomLaunch Dhcp ...

Top of page Other Things You Should Know About the Dictionary Object There are plenty of other things you can do with the Dictionary object. Retrieving all the Items For starters, we said wed show you how to get a list of all the items in a Dictionary. Remember how we got a list of all the keys?
colKeys = objDictionary.Keys For Each strKey in colKeys If objDictionary.Item(strkey) = "Stopped" Then Wscript.Echo strKey End If Next

We used the Keys method to get a collection of all the keys. We then used a For Each loop to loop through that collection. We used an If Then statement to check the item associated with each key, then echoed back the keys we were interested in. If we take out the If Then statement were simply echoing back all the keys:
colKeys = objDictionary.Keys For Each strKey in colKeys Wscript.Echo strKey Next

We do the exact same thing to list all the items:


colItems = objDictionary.Items For Each strItem in colItems Wscript.Echo strItem Next

As you can see, all we did was replace the Keys method with the Items method. (Yes, we also changed the variable names, since its kind of nice for the variable names to have something to do with the data the variable contains.) Retrieving a list of items isnt always quite as useful as a list of keys because, depending on the values in your key-item pair, you could end up with a list something like this:
Running Stopped Running

Stopped Stopped Stopped Stopped ...

Checking for Existing Keys Weve mentioned - more than once, which you know if youve been paying attention - that each key within a Dictionary object must be unique. What happens if you try to add a key that already exists? For example, what happens if you run this script:
Set objDictionary = CreateObject("Scripting.Dictionary") objDictionary.Add "Key1", "Item" objDictionary.Add "Key2", "Item" objDictionary.Add "Key1", "Item"

Give it a try. Well wait. Did you try it? No, dont just wait for us to give you the answer, try it first. Okay, as youve discovered, heres what happens:
C:\Scripts\test.vbs(5, 1) Microsoft VBScript runtime error: This key is already associated with an element of this collection

Yes, you get an error. On line 5, the line where we tried to add Key1 for the second time, were told that the key were trying to add is already associated with an element in this Dictionary object. While its nice that we get a comprehensible error message, it would be even nicer if our script didnt crash. We can stop the script from crashing by checking for the existence of keys before we try to assign them. We do this with the Exists method. (Wow, this is so intuitive its almost scary.)
Set objDictionary = CreateObject("Scripting.Dictionary") objDictionary.Add "Key1", "Item" objDictionary.Add "Key2", "Item" If objDictionary.Exists("Key1") Then Wscript.Echo "Key1 exists" Else Wscript.Echo "Adding Key1" objDictionary.Add "Key1", "Item" End If

We start this script by creating the Scripting.Dictionary object and adding two keyitem pairs. We then use the Exists method in an If Then statement to check whether an entry exists in the Dictionary with the key Key1. If it does we echo back that fact; if it doesnt we echo a message that were adding the key, and we add the key to the Dictionary. Heres what we get back:

Key1 exists

The Exists method comes in really handy when youre doing something like reading in a list of servers from a text file and you want to ensure a server isnt listed twice. Case Sensitivity One really important thing to know about Dictionary keys is that, by default, theyre case-sensitive. That means that you can have these two keys and theyll still be considered unique:
Server1 SERVER1

This could cause problems if youre reading from a text file, a spreadsheet, or a database, any place where the data entry might not have been consistent when it comes to letter casing. Lets try our Exists script (from the previous section) again, but this time well try to add what we might assume to be a duplicate key:
Set objDictionary = CreateObject("Scripting.Dictionary") objDictionary.Add "KEY1", "Item" If objDictionary.Exists("Key1") Then Wscript.Echo "Key1 exists" Else Wscript.Echo "Adding Key1" objDictionary.Add "Key1", "Item" End If

As you can see, were adding an entry to the Dictionary with a key of KEY1. When we check for the existence of Key1, we get this message:
Adding Key1

In other words, the Dictionary object didnt recognize Key1 as being the same as KEY1; therefore, it added a new entry to the Dictionary. We can change this default behavior by changing the value of the CompareMode property. To make the keys case-insensitive we need to change this value to 1:
Const TextMode = 1 Set objDictionary = CreateObject("Scripting.Dictionary") objDictionary.CompareMode = TextMode objDictionary.Add "KEY1", "Item" If objDictionary.Exists("Key1") Then Wscript.Echo "Key1 exists" Else

Wscript.Echo "Adding Key1" objDictionary.Add "Key1", "Item" End If

We start by setting a constant, TextMode, to 1. Why did we call this constant TextMode? Because thats the technical term for making this case-insensitive, and we like to throw technical terms in every once in a while so we can sound smart (we need all the help we can get). But really, that helps the CompareMode make more sense; were setting the mode that the Dictionary object will use when keys are compared for uniqueness. There are two possible modes: text mode, which means not case sensitive; and binary mode, the default, which means case-sensitive. The CompareMode value for text mode is 1, the CompareMode value for binary mode is 0. Now that weve set CompareMode to 1, our script returns this:
Key1 exists

Anda mungkin juga menyukai