◎VBS腳本運行庫手冊之六 ——Dictionary 對象

 

Dictionary Object

腳本經常用來從外面的源獲得信息,例如從文本文件或者數據庫文件。在這些信息獲得之後,它將被存儲到它的內存中,然後用腳本來更改它。例如將信息存儲在一個變量中,或者存儲在一個數組中。同樣,這些信息可以存儲在Dictionary 對象中。Dictionary 就好象一個數組一樣。不同的是,它用叫做鍵對(key-item pairs)來存儲信息,而數組用數字值來存儲。例如,一個一維的數組存儲州的首府像下面這樣:

0 - Olympia

1 - Salem

2 - Sacramento

於其相反,Dictionary 存儲信息像如下的格式:

Washington – Olympia

Oregon - Salem

California - Sacramento

如果你的命令行只是要求輸入一個參數,比如計算機名字,你可以用數組來完成這樣的工作。但是,Dictionary 提供了比數組更加多的功能。特別指出的是,Dictionary 不要求一個腳本確定需要存儲的元素的數目。在數組中,你必須確定數組的大小,或者當添加數據的時候重新變更數組的大小。知道每個值對應的 index。在Dictionary 中,值可以通過 key 或者 item 自身來訪問。

這樣,當管理員用腳本從外部獲得信息,比如獲得計算機的名字,然後存儲在內存中以備使用的時候,Dictionary 就成了一個理想的工具。

Creating a Dictionary

因爲 Dictionary 是一個 COM 對象,你必須用其它的 COM 對象那樣去初始化它。如下的代碼創建一個 Dictionary 對象。

Set objDictionary = CreateObject("Scripting.Dictionary")

當創建完了一個 Dictionary 對象之後,你可以配置 Dictionary 的屬性或者向其內部添加元素。

Configuring Dictionary Properties

Dictionary 只有一個配置的屬性,CompareMode,它對於要添加哪個 KEY 或者不能添加哪個 KEY起着非常重要的作用。(檢查 key 是否存在在 Dictionary 中也是十分重要的)默認的情況下,Dictionary 是被創建成二進制模式,基於 ASCII 的值。知道這個很重要,因爲在ASCII 中,大寫和小寫字符是不同的。在二進制中,如下的兩個服務可以同時被添加進來:

alerter

ALERTER

換句話說,在二進制模式下,你可能因爲大小寫不同而添加進來很多個同樣的 item。這樣就難於搜索了。如果你想查找 Alerter 這個KEY,你可能得到它不存在,因爲沒有和它大小寫完全一樣的值。這樣你可能向一個 Dictionary 添加同樣的 item。當一個 Dictionary 被配置成text 模式的時候,大小寫被認爲是一樣的,這樣可以除去同樣的 key,你的 Dictionary 如果存在 alerter 的話,你就不能向其中添加另外一個叫做 ALERTER key。無論你搜索 alerter 還是 ALERTER,都會找到叫做 Alerter key

爲了配置 Dictionary 的模式,首先創建一個 Dictionary 對象實例,然後配置它的屬性爲如下的值:

0-設置成爲二進制模式,這個是默認選項。

1 設置成 text 模式。

例如,如下的 4.44 的腳本設置 Dictionary text 模式:

Listing 4.44 Configuring the Dictionary Object

1 Const TextMode = 1

2   Set objDictionary = CreateObject("Scripting.Dictionary")

3   objDictionary.CompareMode = TextMode

Dictionary 有任何元素的時候,你不能更改 Dictionary CompareMode 屬性。這是因爲,二進制允許大小寫的區分,例如,如下的

keys 每個代表了不同 key,因爲 Dictionary 是基於二進制格式的:

apple

Apple

APPLE

text 模式下,這些 keys 是一致的。如果你將這些元素存儲在二進制格式,那麼沒有什麼問題,但是存儲在 text 模式下的時候,Dictionary

就突然之間有三個同樣的 keys,它就會失敗了。

如果你想配置 Dictionary 的模式,那麼事先移走 Dictionary 中所有的元素。

Adding Key-Item Pairs to a Dictionary

在創建了 Dictionary 對象實例之後,你可以用 add 方法向 Dictionary 添加 key-item 對。Add方法需要兩個參數,必須按照如下順序並且用逗號分開:  Key name ,   Item value

例如,在腳本 4.45 中,創建了一個 Dictionary 對象,然後添加一些類似於表格 4.10 中的key-item 對。

Table 4.10 Sample Key-Item Pairs

Key Item

Printer 1 Printing

Printer 2Offline

Printer 3Printing

Listing 4.45 Adding Key-Item Pairs to a Dictionary

1   Set objDictionary = CreateObject("Scripting.Dictionary")

2   objDictionary.Add "Printer 1", "Printing"

3   objDictionary.Add "Printer 2", "Offline"

4   objDictionary.Add "Printer 3", "Printing"

Dictionary key 必須是唯一的。例如,如下的兩個語句會產生一個運行的錯誤出來。在第一行被編譯之後,叫做 printer 1 key 已經存在於 Dictionary 中了:

objDictionary.Add "Printer 1", "Printing"

objDictionary.Add "Printer 1", "Offline"

 

 

Inadvertently Adding a Key to a Dictionary

使用 Dictionary 對象的一個潛在的問題是,你如果去訪問一個在 Dictionary 中不存在的元素的時候,它不產生一個錯誤,而是將這個不存在的元素添加到 Dictionary 中去了。看下面的腳本示例,它創建了一個

Dictionary,添加了三對 key-item,然後嘗試去回顯不存在的item,printer 4:

Set objDictionary = CreateObject("Scripting.Dictionary")

objDictionary.Add "Printer 1", "Printing"

objDictionary.Add "Printer 2", "Offline"

objDictionary.Add "Printer 3", "Printing"

Wscript.Echo objDictionary.Item("Printer 4")

當腳本嘗試去回顯不存在的 item 的時候,沒有任何運行錯誤發生,而是創建了一個新的 keyprinter 4,並被添加到了 Dictionary 中,它的對象的 item 的值是 null

爲了避免這樣的錯誤發生,在訪問 item 的值的時候,去檢查它是否存在。

Manipulating Keys and Items in a Dictionary

作爲 Dictionary 本身而言,它的用途很少。一個 Dictionary 只有在訪問它的 item,列舉它的item,或者修改它的 item 的時候,才變得有用。在你創建了一個 Dictionary 之後,你可能作如下的一些事情:

確定在這個 dictionary 中有多少對 key-item 對列舉出在 dictionary keys 和或者 item

決定在 Dictionary 是否存在特定的 key修改在 Dictionary 中的 key 或者 item 的值 Dictionary 中移除特定 key-item 對。

所有這些任務都可以通過在 RunTime Library 中提供的屬性方法來實現。

Determining the Number of Key-Item Pairs in a Dictionary

和其它的許多集合一樣,Dictionary 有一個 count 屬性用來返回在這個集合中的 key-item 對的數量。在腳本 4.46 中創建了是個

Dictionary 對象,然後添加三個 key-item 對,回顯這個Dictionary count 屬性的值。

Listing 4.46 Determining the Number of Key-Item Pairs in a Dictionary

1  Set objDictionary = CreateObject(“Scripting.Dictionary”)

2    objDictionary.Add “Printer 1”, “Printing”

3    objDictionary.Add “Printer 2”, “Offline”

4    objDictionary.Add “Printer 3”, “Printing”

5    Wscript.Echo objDictionary.Count

當腳本運行的時候,會顯示一個值 3

Enumerating Keys and Items in a Dictionary

Dictionary 被設計成用來暫時的存儲信息。任何存在 Dictionary

中的信息都是作爲臨時用的,沒有用來長期存儲的。它一般是用來臨時放信息,然後在腳本中在重新調用他們。例如,你有個存儲了服務器名稱清單的Dictionary,然後在後面的腳本中連到這些服務器上,並且獲得相應的信息。結果是,你每次連接到一個服務器的時候,你都必須去調用 Dictionary中的信息。

Keys items 的方法可以用來返回他們的組成集合,或者的單獨的返回或者全部返回在Dictionary 中的 item-key 的信息。在你用了其中的一個方法之後,你可以用 For Each 循環列舉除在數組中所有的 key-item

例如在 4.47 中的腳本創建一個簡單的 Dictionary,添加三對 keys-item,在這個 Dictionary 創建結束之後,腳本用 keys 方法來列舉出所有的 keys,然後用 items 方法來返回所有的 items

Listing 4.47 Enumerating Keys and Items in a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5

6    colKeys = objDictionary.Keys

7    For Each strKey in colKeys

8    Wscript.Echo strKey

9    Next

10

11   colItems = objDictionary.Items

12   For Each strItem in colItems

13   Wscript.Echo strItem

14   Next

當腳本在 CScript 下運行的時候,命令行的信息如下:

Printer 1

Printer 2

Printer 3

Printing

Offline

Printing

爲了顯示特定的 item 的值,用 item 方法,例如,如下的代碼語句顯示了 key printer 3 item 的值:

Wscript.Echo objDictionary.Item("Printer 3")

 

Verifying the Existence of a Specific Key

Dictionary 的一個比數組更加優秀和標準的優點是你可以快速的找到特定的 key 是否存在。例如,假如你有一定的文件 list 安裝在一個計算機上,並且你向搜索這個 list,來保證特定的dll文件已經安裝了。你用集合或者數組,除非你係統的搜索整個數組否則你沒有方法來確定特定的一個文件是否存在了。但是用 Dictionary 你可以 Exists 方法來檢查給定的 key 是否存在。用Exists 方法只是需要一個參數,(需要查詢的 key 的名字),然後返回一個 Boolean 的值,如果是真的值,表明這個 key 存在,如果是否,則不存在。

例如,在腳本 4.48 中創建一個 Dictionary 對象,添加三對元素,然後腳本檢查叫做 key 的關鍵詞是否存在,並且回顯其結果。

Listing 4.48 Verifying the Existence of a Dictionary Key

1 Set objDictionary = CreateObject("Scripting.Dictionary")

2   objDictionary.Add "Printer 1", "Printing"

3   objDictionary.Add "Printer 2", "Offline"

4   objDictionary.Add "Printer 3", "Printing"

5   If objDictionary.Exists("Printer 4") Then

6   Wscript.Echo "Printer 4 is in the Dictionary."

7   Else

8   Wscript.Echo "Printer 4 is not in the Dictionary."

9   End If

當腳本運行的時候,會有 printer 4 is not in the Dictionary 的消息出現在屏幕上.

Modifying an Item in a Dictionary

添加到 Dictionary 中的 item 不是一成不變的,事實上,你可以在任何的時間去更改它。這個功能可以讓你紀錄腳本的運行情況。例如,你的Dictionary 是個關於服務器名稱的列表區,每次你的腳本對應的服務器運行結束之後,你可以更改它對應的 item 值來標識它的狀態。在腳本中止之前,你可以將狀態列出來看腳本運行成功與否的。在 4.49 中的腳本創建了一個具有三個 keys Dictionary,這三個key 分貝爲 atl-dc-01,atl-dc-02,atl-dc-03,每個的 item 都是設置成 no status,這個表明針對這個服務器的狀態信息還沒有獲得。然後回顯他們的 item的信息。

在這個 Dictionary 被創建之後,用 item 方法以 key 作爲參數更改這些 item 的值。例如,如下的腳本代碼語句更改 key  atl-dc-01 item available::

objDictionary.Item("atl-dc-01") = "Available"

在這三個 items 的值被更改了之後,新的 item 被回顯出在屏幕上:

Listing 4.49 Modifying the Value of a Dictionary Item

1Set objDictionary = CreateObject("Scripting.Dictionary")

2objDictionary.Add "atl-dc-01", "No status"

3objDictionary.Add "atl-dc-02", "No status"

4objDictionary.Add "atl-dc-03", "No status"

5

6colKeys = objDictionary.Keys

7For Each strKey in colKeys

8Wscript.Echo strKey, objDictionary.Item(strKey)

9Next

10

11    objDictionary.Item("atl-dc-01") = "Available"

12    objDictionary.Item("atl-dc-02") = "Available"

13    objDictionary.Item("atl-dc-03") = "Unavailable"

14

15    colKeys = objDictionary.Keys

16    For Each strKey in colKeys

17    Wscript.Echo strKey, objDictionary.Item(strKey)

18    Next

當在 Cscript 下運行這個的時候,命令行中的信息如下:

atl-dc-01 No status

atl-dc-02 No status

atl-dc-03 No status

atl-dc-01 Available

atl-dc-02 Available

atl-dc-03 Unavailable

Removing Key-Item Pairs from a Dictionary

Key-item 對也可以從 Dictionary 中移走,Script Runtime Library 提供了移走 key-item 對的兩種方法:

   RemoveAll, 移走所有的 key-item

   Remove, Dictionary 移走特定的 key-item 的值。

 

 

Removing All Key-Item Pairs from a Dictionary

你或許有一些腳本,比如監視的腳本,作着同樣的動作,將信息存在一個 Dictionary 中,然後要麼在屏幕上顯示這些信息,要麼將這些信息存儲在文本文件中或者數據庫中。然後,腳本停止幾分鐘,收集更新了之後的信息,就這樣不確定的進行下去了。

如果你用 Dictionary 來作爲臨時的數據存儲收集信息數據,你可能希望在收取新的信息之前清空 Dictionary 的內容。爲了做到這點,你可以用方法RemoveAll 來移走所有的 Dictionary中的 key-item 對。例如,在 4.50 中的腳本創建了一個含有三個元素的 Dictionary,然後顯示 Dictionary keys,腳本用 RemoveAll 方法移走所有的 key-item對,Dictionary.RemoveAll 爲了檢查元素是否被移走,在此回顯 Dictionary key 的信息Listing 4.50 Removing All the Key-Item Pairs in a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5    colKeys = objDictionary.Keys

6    Wscript.Echo "First run: "

7    For Each strKey in colKeys

8Wscript.Echo strKey

9    Next

10   objDictionary.RemoveAll

11   colKeys = objDictionary.Keys

12   Wscript.Echo VbCrLf & "Second run: "

13   For Each strKey in colKeys

14    Wscript.Echo strKey

15   Next

當腳本在 CScript 運行的時候,如下的信息顯示在命令行中。和你看見的一樣,第二次輸出的時候是空的,因爲 Dictionary 已經沒有任何的 keys 了。

First run:

Printer 1

Printer 2

Printer 3

Second run:

Removing a Specific Key-Item Pair from a Dictionary

和移走所有的 key-item 對不同,你有的時候可能向移走一個單獨的 key item。例如,假如你的腳本來從一系列的計算機上獲得時間日誌。腳本被設計成嘗試聯繫每個計算機跟蹤每個成功和失敗。如果不能連接到計算機上,腳本嘗試重新連接,知道連接到計算機並獲得所有的日誌信息。在這個假想的情況下,可能你的

Dictionary 中有如下的 keys

atl-dc-01

atl-dc-02

atl-dc-03

atl-dc-04

atl-dc-05

當腳本運行的時候,它可能不能連接到計算機

atl-dc-03,atl-dc-04,在這種情況下,腳本去嘗試重新連接這些計算機。但是腳本怎麼知道哪個計算機需要連接,哪個不需要那?

一個解決的辦法就是簡單的移走已經成功連接的計算機。在第一段腳本被編譯結束之後,那這個Dictionary 中只是包含如下的元素:

atl-dc-03

atl-dc-04

一旦一個計算機連接成功,就從 Dictionary 中移走這個元素,這樣,如果 Dictionary 中不再含有任何元素的時候,那麼所有的計算機就都連接成功了,腳本運行結束了。

爲了移走單個的元素,用 Remove 方法,輸入 key 的名字作爲唯一的參數。例如如下的腳本語句移走了 key atl-dc-02 key 和它對應的item

objDictionary.Remove("atl-dc-02")

4.51 中的腳本創建一個有三個元素的 Dictionary 對象,回顯所有的 keys。然後移走 key printer 2 key 和它的item,然後再次回顯 Dictionary keys

Listing 4.51 Removing a Specified Key-Item Pair from a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5    colKeys = objDictionary.Keys

6    Wscript.Echo "First run: "

7    For Each strKey in colKeys

8Wscript.Echo strKey

9    Next

10   objDictionary.Remove("Printer 2")

11   colKeys = objDictionary.Keys

12   Wscript.Echo VbCrLf & "Second run: "

13   For Each strKey in colKeys

14    Wscript.Echo strKey

15   Next

當腳本在 CScript 運行的時候,在命令行中顯示如下:

First run:

Printer 1

Printer 2

Printer 3

Second run:

Printer 1

Printer 3

在第二段腳本編譯的末尾,printer 2 已經不再存在於 Dictionary 中了。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章