嗨,Scripting Guy!

嗨,Scripting Guy!

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

今天的問題:如何使用 ADO 開啟在檔名中有空格的文字檔案?


如何使用 ADO 開啟在檔名中有空格的文字檔案?

嗨,Scripting Guy!我要如何使用 ADO 開啟在檔名中有空格的文字檔案?

-- TL

TL,您好。您可能已經忘了有寄這個問題給我們;說這個問題只擱置了一陣子,那真是太含蓄了 (您都不知道我們從它上面擦掉的灰塵和蜘蛛網有多少,才貼到 Script Center (Script 中心) 的)。您是很久以前寫信問我們這個簡單的問題:要如何使用 ADO 開啟在檔名中剛好有空格的文字檔案?看似簡單,老實說,我們卻想不出來。我們試過插入雙引號跟單引號,試過使用短檔案名稱,甚至還試過在網路上搜尋答案。套句棒球的說法,我們被封殺出局。


附註:我們甚至還拜讀了愛因斯坦以及牛頓爵士的精選集,希望他們之一有答案。很不幸地,他們好像也沒我們幸運。


所以我們就放棄了嗎?事實上,我們是放棄了。儘管如此,我們心中不時還是惦記著這個問題,而且偶爾會嘗試不一樣的東西,說不定可以找出答案。我們每次嘗試新玩意,總是會失敗。

終於有一天,在查詢關於 Microsoft Excel 上的某些資料時,答案被我們瞎摸到了 (其實我們是誤碰到一個不同問題的答案,結果是用於 Excel 的方法同樣也可以用於文字檔案)。所以終於在許久之後,TL,我們可以給您 (或至少是您的曾曾曾孫子) 這個問題的解答:「如何使用 ADO 開啟在檔名中有空格的文字檔案?」

在揭曉答案之前,我們或許該向其他旁人解釋一下狀況。ADO (ActiveX Data Objects) 可讓您使用資料庫技術從文字檔讀取資料。我們今天不會詳述所有的細節;如需詳細資料,請參閱在 MSDN 上的 Scripting Clinic (Scripting 門診) 專欄。假設您有個簡單的文字檔案看起來就像這樣 (就假裝檔案中有一千多行):

Name,Department,Title
Ken Myer,Finance,Fiscal Specialist
Pilar Ackerman,Research,Manager
Jonathan Haas,Headquarters,Fiscal Specialist

若想要有所有 Fiscal Specialist (會計師) 的名單,可以使用與此相似的 ADO 指令碼來擷取該項資訊,而不用一行一行地讀過整份文字檔案。

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
strPathtoTextFile = "C:\Scripts\Text files"
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=" & strPathtoTextFile & ";" & _
        "Extended Properties=""text;HDR=YES;FMT=Delimited"""
strFile = "Employees.txt"
objRecordset.Open "SELECT * FROM " & strFile & " WHERE Title = 'Fiscal Specialist'", _
    objConnection, adOpenStatic, adLockOptimistic, adCmdText
Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("Name")
    Wscript.Echo objRecordset.Fields.Item("Department")
    Wscript.Echo objRecordset.Fields.Item("Title")   
    objRecordset.MoveNext
Loop

我們在這裡所做的,是連接到 C:\Scripts\Text files 資料夾,然後查詢 Employees.txt 檔案。這一行程式碼指出我們想要處理的檔案名稱:

strFile = "Employees.txt"

看起來完美無缺:指令碼會執行,而且會回報所有會計師的名稱、部門和職稱。

那問題在哪裡?假設我們的文字檔案叫做 Fabrikam Employees.txt。沒什麼大不了的,對吧?畢竟,您只需要將 strFile 變數的值改成這樣就可以了:

strFile = "Fabrikam Employees.txt"

我們也是這樣想,可是執行指令碼後卻得到這個訊息:

Microsoft JET Database Engine: Syntax error in FROM clause.

哎呀!顯然 Fabrikam Employees.txt 檔名中的空格造成了問題,這我們知道,我們想不透的是要怎麼解決這個問題。我們試過各種不同的單引號與雙引號排列組合,卻發現答案其實簡單多了:只要把檔名用方括弧括起來就解決了。

沒錯,方括弧。如果將 strFile 的值設成這樣,指令碼就會運作順暢:

strFile = "[Fabrikam Employees.txt]"

老實說,這實在有點令人失望。在經過一番大費周章,我們以為答案應該是很複雜;那樣我們才有理由說:「我們之所以花了這麼長的時間,是因為這是一個相當複雜的問題,需要無比的理智推論與能力,才找得出答案。」結果我們只能說:「只要用方括號將檔名括起來就行了!」哎,至少可以用就好了!反正就像我們說的,我們連在愛因斯坦跟牛頓的大作中都找不到答案,所以囉。

對了,完整的指令碼看起來像這樣:

Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
strPathtoTextFile = "C:\Scripts\Text files"
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=" & strPathtoTextFile & ";" & _
        "Extended Properties=""text;HDR=YES;FMT=Delimited"""
strFile = "[Fabrikam Employees.txt]"
objRecordset.Open "SELECT * FROM " & strFile & " WHERE Title = 'Fiscal Specialist'", _
    objConnection, adOpenStatic, adLockOptimistic, adCmdText
Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("Name")
    Wscript.Echo objRecordset.Fields.Item("Department")
    Wscript.Echo objRecordset.Fields.Item("Title")   
    objRecordset.MoveNext
Loop

外加一筆。諷刺的是,在那麼努力嘗試找出一種方式來存取檔名中有空格的文字檔案之後,我們最後卻找到了兩種辦法。您也可以用 ` 字元來括住檔案名稱,這不是單引號,而是與 ~ 符號位在同個鍵 (至少在美式英文鍵盤上是一樣的) 上的重音符號。換句話說,您也可以將 strFile 的值設為以下名稱,指令碼照樣可以正常運作:

strFile = "`Fabrikam Employees.txt`"

如需詳細資訊

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

 

回到頁首 回到頁首