嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎使用 TechNet 專欄,Microsoft Scripting Guys 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

今天的問題:如何清點文字檔中的項目?


如何清點文字檔中的項目?

嗨,Scripting Guy!我要如何清點文字檔中的項目?

-- JA

JA,您好。如果我們明白您的問題無誤的話,您有個文字檔包含幾行字,每一行都代表一特定的項目。為了簡化事情,讓我們假設您的文字檔案包含城市名稱:
City
Seattle
Seattle
Los Angeles
Chicago
Seattle
Los Angeles
Pittsburgh

您要找的是一個可以讀過整個檔案並且回報每個項目發生次數的指令碼;也就是說,一個可以回報類似於這樣報告的指令碼:

Pittsburgh 1
Chicago 1
Los Angeles 2
Seattle 3

這有幾種不同的方法可以辦到,不過我們決定說明一個非常強大而且有彈性的方法來處理當作資料庫來用的文字檔案 (這也是您最初想要做的)。這不是個眾所周知的方法,但是您實際上可以使用 ADO (ActiveX Data Objects) 來執行對文字檔案的資料庫查詢。而那正是我們在此指令碼中所做的:

On Error Resume Next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
strPathtoTextFile = "C:\Scripts"
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=" & strPathtoTextFile & ";" & _
        "Extended Properties=""text;HDR=Yes;FMT=Delimited"""
strFile = "City_Names.txt"
objRecordset.Open "Select City, Count(City) AS CountOfCity FROM " & strFile & _
    " GROUP BY City", objConnection, adOpenStatic, adLockOptimistic, adCmdText
Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("City"), objRecordset.Fields.Item("CountOfCity")
    objRecordset.MoveNext
Loop

如您可能預期的,此指令碼大部分都是用來建立 ADO ConnectionRecordset 物件,然後將文字檔視為資料庫進行連結。 我們今天不會詳述這些步驟;如果您有興趣,可以參閱 Scripting Clinic 專欄中與此相關的主題。今天的重點會放在從文字檔中擷取資料所用的查詢,以及顯示回傳資料的幾行程式碼,

就先從用來擷取資料的 SQL 查詢開始吧:

objRecordset.Open "Select City, Count(City) AS CountOfCity FROM " & strFile & _
    " GROUP BY City", objConnection, adOpenStatic, adLockOptimistic, adCmdText

乍看之下,您可能會被這項查詢所困惑,因為您可能記得,我們的文字檔案只包含一個欄位:檔案中的每一行都只包含一個城市名稱,別無其他。然而,即使「資料庫」中只有一個欄位,SQL 查詢還是會指定兩個不同的項目:CityCount(City) AS CountOfCity。怎麼會這樣呢?

事實上我們並沒有選取兩個不同的欄位;而是只選取了一個欄位 (City) 與一個「導出欄位」,讓我們可以清點每個城市出現在資料庫的次數 (導出欄位是根據在其他欄位中找到的資料進行計算的欄位;欄位本身並不真的存在於資料庫中。)Count(City) AS CountOfCity 項目 (與 GROUP BY City 子句結合) 可以讀成這樣:算出每個城市出現在檔案中的次數,然後將該數字儲存在一個名為 CountOfCity 的導出欄位中。

也就是說,此查詢會產生一個看起來像這樣的資料錄集,有 PittsburghChicago 作為 City 欄位的例項, 而 11 作為 CountOfCity 導出欄位的例項:

Pittsburgh 1
Chicago 1

好處是我們得到的這個資料錄集已經計算好城市總數。或者我們可以開啟文字檔案,讀取每一行,然後使用陣列或是 Dictionary 物件來追蹤每個城市名稱出現在欄位中的次數。但是 ADO 使這個過程簡單多了。

您或許也已經注意到:我們並沒有從資料庫資料表中選取 (因為我們沒有資料庫也沒有資料表),而是在 SQL 查詢中指定文字檔案的名稱。因此,我們是從 strFile 變數中選取資料,而這也剛好代表文字檔案 (City_Names.txt) 的名稱。

一旦得到資料錄集後,只要使用這段程式碼來循迴處理所有記錄,就可以回應城市名稱與每個城市出現在檔案中的次數:

Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("City"), objRecordset.Fields.Item("CountOfCity")
    objRecordset.MoveNext
Loop

如您所見,這藉由回應兩個項目的值就可以做到:CityCountOfCity。即使 CountOfCity 是個導出欄位,它還是被當成像是真正儲存於資料庫中的真實欄位一樣。總而言之,這是從文字檔案擷取資訊 (與未經處理資料相反) 一種非常簡單的方法。


如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首