這裡介紹如何在 Excel VBA 中讀取與寫入文字檔,並提供基本的參考範例。

通常 Excel VBA 程式都會從 Excel 表格中取得資料,經過處理之後再送回 Excel 表格中,但有些時候我們也會需要直接從外部的文字檔讀取資料,或是將處理完的資料儲存至外部的文字檔中,以下是 Excel VBA 中檔案讀取與寫入的教學。

讀取外部文字檔

若要在 VBA 中讀取外部的文字檔,可以使用 Open 來開啟檔案,其語法為:

Open 檔案位置 For Input As 檔案代碼

檔案位置就是檔案在硬碟中的路徑,VBA 在開啟檔案之後,會使用檔案代碼來辨識檔案,每個已開啟的檔案都會對應一個不重複的檔案代碼,例如 #1#2 等,編號可以不連續,但不可以重複。

開啟檔案之後,通常我們會使用迴圈的方式來讀取整個檔案內容,每次以 Line 讀取一行資料,然後藉由 EOF(end of file)來判斷檔案是否已經讀取到結尾,如果讀取至結尾則跳出迴圈。

在檔案開啟之後,後續所有的檔案讀取以及判斷檔案結尾等動作,都會使用檔案代碼的方式來指定檔案。

以下是一個簡單的範例:

Dim FilePath As String

' 文字檔案位置
FilePath = "C:\ExcelDemo\demo.txt"

' 開啟 FilePath 文字檔,使用編號 #1 檔案代碼
Open FilePath For Input As #1

' 執行迴圈,直到編號 #1 檔案遇到結尾為止
Do Until EOF(1)

  ' 從編號 #1 檔案讀取一行資料
  Line Input #1, LineFromFile

  ' 輸出一行資料
  MsgBox (LineFromFile)

Loop

' 關閉編號 #1 檔案
Close #1

VBA 讀取文字檔案

這個範例會開啟 C:\ExcelDemo\demo.txt 這個文字檔(執行時請自己建立這個檔案),並將其設定為編號 #1 的檔案,如果要開啟多個檔案時,則可自行變更每個檔案的代碼,例如 #2#3 等。

在迴圈的判斷式中,我們使用 EOF(1) 來判斷編號 #1 的檔案是否已經到達結尾處。

在讀檔的動作則使用 LineInput #1 之中讀取一行資料,然後將這一行資料儲存在 LineFromFile 這個變數當中。

當檔案使用完畢之後,要使用 Close 將開啟的檔案關閉。

寫入外部文字檔

若要將資料寫入外部的文字檔,一開始也是使用 Open 開啟檔案:

Open 檔案位置 For Output As 檔案代碼

這個語法跟之前讀檔的語法類似,只是把開檔的模式改為 Output,檔案位置就填入要寫入的檔案路徑,而檔案代碼也是自己取一個不重複的數字即可。開啟檔案之後,即可使用 Print 函數將指定的資料寫入檔案中。

Dim OutputFilePath As String
Dim Content As String

' 文字檔案位置
OutputFilePath = "C:\ExcelDemo\demo_output.txt"

' 開啟 OutputFilePath 文字檔,使用編號 #2 檔案代碼
Open OutputFilePath For Output As #2

' 要寫入檔案的內容
Content = "This is a test."

' 將 Content 的內容寫入編號 #2 的檔案
Print #2, Content

' 關閉編號 #2 檔案
Close #2

VBA 寫入文字檔案

這個範例會打開 C:\ExcelDemo\demo_output.txt 這個檔案,然後將 Content 變數的內容以 Print 寫入其中,最後呼叫 Close 將檔案關閉。而在寫入完成後,demo_output.txt 的檔案內容如下:

寫入檔案的內容

如果呼叫 Print 時,省略要寫入的資料,就會寫入空白行至檔案中:

' 寫入空白行
Print #2,

若要拼湊多個變數,產生想要的排版格式,可以使用分號將多個資料串起來:

' 以空白分隔
Print #2, "Hello"; " "; "World"

' 以 5 個空白分隔
Print #2, "Hello"; Spc(5); "World"

Dim MyBool As Boolean
MyBool = True
' 輸出字串與布林變數
Print #2, "The "; MyBool; " is a Boolean value."

Dim MyInt As Integer
MyInt = 123
' 輸出字串與整數變數
Print #2, "The"; MyInt; "is a Integer value."

這是寫入的檔案內容:

寫入檔案的內容

更多 Print 的範例,可以參考 Microsoft Learn 的說明文件

除了使用 Print 之外,還有一個 Write 也可以寫入檔案,它會自動將文字的內容加上雙引號,並以逗號分隔多個輸入變數,以下是一個範例(將上面 Print 的位置直接替換成 Write 即可):

' 以逗號分隔,寫入檔案
Write #2, "Hello, World", 123

Write 在寫入檔案時,會將幾種 VBA 變數轉換為特殊的格式,例如 True 就會轉為 #TRUE#,詳細的說明請參考 Microsoft Learn 的說明文件

附加方式寫入檔案

當我們用 Output 模式寫入一個已經存在的檔案時,如果檔案中存在有舊的內容的話,在寫入之後就會將舊的內容覆蓋掉,若想要保留舊資料,並增加一些內容接在原本資料的後方,就可以用附加的方式(append)寫入檔案,最典型的使用情境就是將程式輸出訊息寫入記錄檔。

若要以附加方式寫入檔案,只要將開檔的模式改為 Append 即可,以下是一個簡單的範例:

Dim OutputFilePath As String
Dim Content As String

OutputFilePath = "C:\ExcelDemo\demo_output.txt"

' 建立文字檔
Open OutputFilePath For Output As #2
Content = "This is a test."
Print #2, Content
Close #2

' 附加方式寫入檔案
Open OutputFilePath For Append As #3
Content = "This is another test."
Print #3, Content
Close #3

執行之後,demo_output.txt 的內容如下:

寫入檔案的內容

VBA 的開檔模式除了 InputOutputAppend 之外,還有用於二進位檔案的 Binary 模式,以及用於隨機存取的 Random 模式,不過另外這兩種一般人比較少用,就不介紹了,有興趣的人請參考 Microsoft Learn 的說明

自動選擇檔案代碼

如果要使用程式自動開啟多個檔案,不想使用手動指定檔案代碼的話,可以使用 FreeFile 這個函數自動取得可用的檔案代碼,以下是一個簡單的使用範例:

Dim FileCount As Integer
Dim FileNumber As Integer
Dim FileName As String

 ' 使用迴圈自動寫入 5 個檔案
For FileCount = 1 To 5

  ' 自動取得檔案代碼
  FileNumber = FreeFile()

  ' 檔案名稱
  FileName = "C:\ExcelDemo\demo_output_" & FileCount & ".txt"

  ' 開啟檔案
  Open FileName For Output As #FileNumber

  ' 寫入檔案
  Print #FileNumber, "Hello, World"

  ' 關閉檔案
  Close #FileNumber

Next FileCount

這個範例會自動寫入五個檔案,程式設計者不需要檢查可用的檔案代碼,在較複雜的程式中,建議使用這種方式,可以避免不小心造成檔案代碼衝突的問題。

應用範例

寫入 CSV 檔案

CSV 檔案就是每個欄位以逗點分隔的檔案,以下是將 Excel 表格的資料寫入 CSV 檔的範例,假設我們的 Excel 檔案中有一張向這樣的表格:

Excel 表格

若要在 VBA 中將這個表格的資料直接寫成一個 CSV 檔,可以這樣寫:

Dim ColNum As Integer
Dim Line As String
Dim LineValues() As Variant
Dim OutputFileNum As Integer
Dim PathName As String
Dim RowNum As Integer
Dim SheetValues() As Variant

' 取得目前 Excel 檔的儲存路徑
PathName = Application.ActiveWorkbook.Path

' 自動取得檔案代碼
OutputFileNum = FreeFile

' 在同樣路徑下,開啟一個 demo_output.csv 檔
Open PathName & "demo_output.csv" For Output As #OutputFileNum

' 取得 Excel 表格內的資料
SheetValues = Sheets("工作表1").Range("A1:C6").Value

' 動態調整陣列大小
ReDim LineValues(1 To 3)

For RowNum = 1 To 5
  For ColNum = 1 To 3
    ' 把 Excel 資料表的一列資料放進陣列中
    LineValues(ColNum) = SheetValues(RowNum, ColNum)
  Next

  ' 將陣列中的資料以逗號連接起來
  Line = Join(LineValues, ",")

  ' 將 CSV 資料寫入檔案
  Print #OutputFileNum, Line
Next

' 關閉檔案
Close #OutputFileNum

產生的 CSV 檔若用記事本開啟,即可看到其原始的資料:

記事本開啟 CSV 檔

而若使用 Excel 來開啟 CSV 檔,就會直接以表格的方式呈現:

Excel 開啟 CSV 檔

參考資料