Microsoft Excel是Microsoft為使用Windows和Apple Macintosh操作系統的電腦編寫的一款電子表格軟件。直觀的界面、出色的計算功能和圖表工具,再加上成功的市場營銷,使Excel成為最流行的個人計算機數據處理軟件。 VBA包含了許多用于文件操作的語句和函數,可以滿足絕大多數情況下的文件操作要求。下面我們按照操作目的進行一 一介紹。  ?(一)文件處理
1.Name 語句 語法:Name oldpathname As newpathname 功能:重命名一個文件、目錄、或文件夾,移動一個文件。 說明:在一個已打開的文件上使用 Name,將會產生錯誤。進行文件操作時,一定要注意錯誤處理。 示例: On Error Resume Next '錯誤處理 Name "f:\TEST.xls" As "f:\TEST123.xls" '重命名 Name "f:\TEST.xls" As "f:\dll\TEST.xls" '移動文件 Name "f:\TEST.xls" As "d:\TEST123.xls" '跨驅動器移動并重命名文件 注意:Name不能移動一個目錄或文件夾。 2、FileCopy 語句 語法:FileCopy source, destination 功能:復制一個文件。 說明:如果對一個已打開的文件使用 FileCopy 語句,則會產生錯誤。 示例: FileCopy "f:\TEST.xls", "e:\TEST.xls" '從F盤復制TEST.xls到E盤 3、Kill 語句 語法:Kill pathname 功能:從磁盤中刪除文件。 說明:Kill 支持多字符 (*) 和單字符 (?) 的統配符來指定多重文件。如果使用 Kill 來刪除一個已打開的文件,則會產生錯誤。 示例: Kill "f:\TEST.xls" ’刪除F盤的TEST.xls文件 Kill "f:\*.xls" ' 刪除F盤所有xls文件 4、GetAttr 函數 語法:GetAttr(pathname) 功能:獲取一個文件、目錄、或文件夾的屬性。返回一個 Integer值。 返回值:由 GetAttr 返回的值,是下面這些屬性值的總和: 常數 值 描述 vbNormal 0 常規 vbReadOnly 1 只讀 vbHidden 2 隱藏 vbSystem 4 系統文件 vbDirectory 16 目錄或文件夾 vbArchive 32 存檔文件 vbalias 64 指定的文件名是別名。只在Macintosh中可用。 說明:若要判斷是否設置了某個屬性,在 GetAttr 函數與想要得知的屬性值之間使用 And 運算符與逐位比較。如果所得的結果不為零,則表示設置了這個屬性值。 示例: Debug.Print GetAttr("F:\test.txt") '若為存檔文件,在立即窗口可看到值為32 Debug.Print GetAttr("F:\test.txt") '將屬性—高級—可存檔文件的勾去掉后,值為0 為判斷一個文件是否只讀,可用下法: Debug.Print GetAttr("F:\test.txt") And vbReadOnly 若值非零,說明時只讀的。 5、SetAttr 語句 語法:SetAttr pathname, attributes 功能:為一個文件設置屬性。 說明:如果想要給一個已打開的文件設置屬性,則會產生運行時錯誤。 示例: SetAttr"F:\test.txt", vbHidden ' 設置隱藏屬性 SetAttr"F:\test.txt", vbHidden + vbReadOnly ' 設置隱藏并只讀 6、FileLen 函數 語法:FileLen(pathname) 功能:獲取一個文件的長度,單位是字節。 說明:當調用 FileLen 函數時,不需要打開文件,如果所指定的文件已經打開,則返回的值是這個文件在打開前的大小。 7、FileDateTime 函數 語法:FileDateTime(pathname) 功能:獲取一個文件被創建或最后修改后的日期和時間。 示例: Debug.Print FileDateTime("F:\TEST.xls") '在立即窗口可看到2007-3-29 19:28:27 (二)目錄處理 1、CurDir 函數 語法:CurDir[(drive)] 功能:返回當前的路徑。 說明:drive 參數是可選的,它指定一個存在的驅動器。如果沒有指定驅動器,或 drive 是零長度字符串 (""),則 CurDir 會返回當前驅動器的路徑。 示例: Debug.Print CurDir ' 返回“C:\Documents and Settings\yc\My Documents” Debug.Print CurDir("C") ' 返回“C:\Documents and Settings\yc\My Documents” Debug.Print CurDir("D") ' 返回“D:\”。 2、ChDir 語句 語法:ChDir path 功能:改變當前的目錄或文件夾。 說明:ChDir 語句改變缺省目錄位置,但不會改變缺省驅動器位置。缺省驅動器一般是C。 示例: ChDir "D:\temp" Debug.Print CurDir ' 返回“C:\Documents and Settings\yc\My Documents” Debug.Print CurDir("D") ' 返回“D:\temp” 與上例比較,此時D盤的當前目錄已經變為“D:\temp”,但是缺省驅動器還是C。 3、ChDrive 語句 語法:ChDrive drive 功能:改變當前的驅動器。 說明:如果使用零長度的字符串 (""),則當前的驅動器將不會改變。如果 drive 參數中有多個字符,則 ChDrive 只會使用首字母。 示例: ChDrive "D" ChDir "D:\temp"Debug.Print CurDir ' 返回“D:\temp” Debug.Print CurDir("D") ' 返回“D:\temp” 與上例比較,用CurDir返回的是“D:\temp”,當前驅動器已經變為D了。 4、Dir 函數 語法:Dir[(pathname[, attributes])] 兩個參數都是可選的,attributes表示文件屬性。 功能:返回一個文件名、目錄名或文件夾名稱,它必須與指定的模式或文件屬性、或磁盤卷標相匹配。 說明:在第一次調用 Dir 函數時,必須指定 pathname,否則會產生錯誤。如果也指定了文件屬性,那么就必須包括 pathname。 Dir 會返回匹配 pathname 的第一個文件名。若想得到其它匹配 pathname 的文件名,再一次調用 Dir,且不要使用參數。如果已沒有合乎條件的文件,則 Dir 會返回一個零長度字符串 ("")。一旦返回值為零長度字符串,并要再次調用 Dir 時,就必須指定 pathname,否則會產生錯誤。不必訪問到所有匹配當前 pathname 的文件名,就可以改變到一個新的 pathname 上。但是,不能以遞歸方式來調用 Dir 函數。以 vbDirectory 屬性來調用 Dir 不能連續地返回子目錄。 示例: Debug.Print Dir("F:\TEST.xls") ’返回"TEST.xls" Debug.Print Dir("F:\*.xls") ’返回按條件第一個找到的文件名 Debug.Print Dir("F:\*.txt",vbReadOnly) ’返回第一個只讀的txt文件 以下過程可顯示C盤根目錄下的所有目錄. Sub DirC() MyPath = "c:\" MyName = dir(MyPath, vbDirectory) ' 找尋第一項。 Do While MyName <> "" ' 開始循環。 ' 跳過當前的目錄及上層目錄。 If MyName <> "." And MyName <> ".." Then ' 使用位比較來確定 MyName 代表一目錄。 If (GetAttr(MyPath & MyName) And vbDirectory) = vbDirectory Then Debug.Print MyName ' 如果它是一個目錄,將其名稱顯示出來。 End If End If MyName = dir ' 查找下一個目錄。 Loop End Sub 以下過程利用遞歸可以查找目錄和子目錄下的所有文件。 Public Sub FindFile(mPath As String, Optional sFile As String = "") On Error Resume Next Dim s As String, sDir() As StringDim, i As Long, d As Long If Right(mPath, 1) <> "\" Then mPath = mPath & "\" End If '查找目錄下的文件 s = dir(mPath & sFile, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem) Do While s <> "" Debug.Print mPath & s s = dir Loop '查找目錄下的子目錄 s = dir(mPath, vbArchive + vbDirectory + vbHidden + vbNormal + vbReadOnly + vbSystem) Do While s <> "" If s <> "." And s <> ".." Then If (GetAttr(mPath & s) And vbDirectory) = vbDirectory Then d = d + 1 ReDim Preserve sDir(d) sDir(d) = mPath & s End If End If s = dir Loop '開始遞歸 For i = 1 To d FindFile sDir(d) & "\" Next End Sub 5、MkDir 語句 語法:MkDir path 功能:創建一個新的目錄或文件夾。 說明:path 可以包含驅動器。如果沒有指定驅動器,則 MkDir 會在當前驅動器上創建新的目錄或文件夾。 示例: MkDir "MYDIR" '在當前目錄建立新的目錄或文件夾。 6、RmDir 語句 語法:RmDir path 功能:刪除一個存在的目錄或文件夾。 說明:如果想要使用 RmDir 來刪除一個含有文件的目錄或文件夾,則會發生錯誤。在試圖刪除目錄或文件夾之前,先使用 Kill 語句來刪除所有文件。 示例: RmDir "MYDIR" ' 將 MYDIR 刪除。 (三)處理文本文件 1、Open 語句 語法:Open pathname For mode [Access access] [lock] As [#]filenumber [Len=reclength] 其中access、lock、reclength為可選參數,一般不用。 mode 指定打開文件的方式。有5種: Input:以輸入方式打開,即讀取方式。 Output:以輸出方式打開,即寫入方式。 Append:以追加方式打開,即添加內容到文件末尾。 Binary:以二進制方式打開。 Random:以隨機方式打開,如果未指定方式,則以 Random 方式打開文件。 filenumber 是一個有效的文件號,范圍在 1 到 511 之間。可以指定,也可使用 FreeFile 函數可得到下一個可用的文件號。 說明:如果 pathname 指定的文件不存在,那么,在用 Append、Binary、Output、或 Random 方式打開文件時,可以建立這一文件。 示例: Open "F:\TEST.txt" For Input As #1 '以輸入方式打開 Open "F:\TEST.xls" For Binary As #1 '以二進制方式打開 2、Close 語句 語法:Close [filenumberlist] filenumberlist 參數為一個或多個文件號,若省略 filenumberlist,則將關閉 Open 語句打開的所有活動文件。 說明:打開文件后,必須在使用完后關閉文件。 示例: Dim I, FileName For I = 1 To 3 FileName = "TEST" & I ' 創建文件名。 Open FileName For Output As #I ' 打開文件。 Print #I, "This is a test." ' 將字符串寫入文件。 Next I Close ' 將三個已打開的文件全部關閉。 3、Reset 語句 語法:Reset 功能:關閉所有用 Open 語句打開的磁盤文件。 說明:Reset 語句關閉 Open 語句打開的所有活動文件,并將文件緩沖區的所有內容寫入磁盤。 示例: Dim FileNumber For FileNumber = 1 To 5 Open "TEST" & FileNumber For Output As #FileNumber Write #FileNumber, "Hello World" ' 將數據寫入文件。 Next FileNumber Reset ' 關閉文件并將緩沖區內的數據寫到磁盤中。 4、FreeFile 函數 語法:FreeFile[(rangenumber)] 參數 rangenumber指定一個范圍,以便返回該范圍之內的下一個可用文件號。指定 0(缺省值)則返回一個介于 1 – 255 之間的文件號。指定 1 則返回一個介于 256 – 511 之間的文件號。 功能:提供一個尚未使用的文件號。 示例: Dim fnum As Integer fnum = FreeFile Open "F:\TEST.txt" For Input As #fnum Close #fnum 5、EOF 函數 語法:EOF(filenumber) 功能:返回一個 Integer,它包含 Boolean 值 True,表明已經到達為 Random 或順序 Input 打開的文件的結尾。 6、LOF 函數 語法:LOF(filenumber) 功能:返回一個 Long,表示用 Open 語句打開的文件的大小,該大小以字節為單位。 7、Loc 函數 語法:LOc(filenumber) 功能:返回一個 Long,在已打開的文件中指定當前讀/寫位置。 8、Input # 語句 語法:Input #filenumber, varlist 功能:從已打開的順序文件中讀出數據并將數據指定給變量。 說明:通常用 Write # 將 Input # 語句讀出的數據寫入文件。為了能夠用 Input # 語句將文件的數據正確讀入到變量中,在將數據寫入文件時,要使用 Write # 語句而不使用 Print # 語句。使用 Write # 語句可以確保將各個單獨的數據域正確分隔開。 示例: 本示例使用 Input # 語句將文件內的數據讀入兩個變量中。本示例假設 TESTFILE文件內含數行以 Write # 語句寫入的數據;也就是說,每一行數據中的字符串部分都是用雙引號括起來,而與數字用逗號隔開,例如,("Hello", 234)。 Dim MyString, MyNumber Open "TESTFILE" For Input As #1 ' 打開輸入文件。 Do While Not EOF(1) ' 循環至文件尾。 Input #1, MyString, MyNumber ' 將數據讀入兩個變量。 Debug.Print MyString, MyNumber ' 在立即窗口中顯示數據。 LoopClose #1 ' 關閉文件。
9、Write # 語句 語法:Write #filenumber, [outputlist] 功能:將數據寫入順序文件。 說明:通常用 Input # 從文件讀出 Write # 寫入的數據。 如果省略 outputlist,并在 filenumber 之后加上一個逗號,則會將一個空白行打印到文件中。多個表達式之間可用空白、分號或逗號隔開。空白和分號等效。 用 Write # 將數據寫入文件時將遵循幾個通用的約定,使得無論什么區域都可用 Input # 讀出并正確解釋數據: ·在寫入數值數據時總使用句號作為十進制分隔符。 ·對于 Boolean 類型的數據,或者打印 #TRUE# 或者打印 #FALSE#。無論在什么地區,都不將 True 和 False 這兩個關鍵字翻譯出來。 ·使用通用的日期格式將 Date 類型的數據寫入文件中。當日期或時間的部件丟失或為零時,只將現有部分寫入文件中。 ·如果 outputlist 的數據為 Empty,則不將任何數據寫入文件。但對 Null 數據,則要寫入 #NULL#。 ·如果 outputlist 數據為 Null 數據,則將 #NULL# 寫入文件中。 ·對于 Error 類型的數據,輸出看起來與 #ERROR errorcode# 一樣。無論在什么地區,都不將關鍵字 Error 翻譯出來。 與 Print # 語句不同,當要將數據寫入文件時,Write # 語句會在項目和用來標記字符串的引號之間插入逗號。沒有必要在列表中鍵入明確的分界符。Write # 語句在將 outputlist 中的最后一個字符寫入文件后會插入一個新行字符,即回車換行符,(Chr(13) + Chr(10))。 示例: Open "F:\test.txt" For Output As #1 ' 打開輸出文件。 Write #1, "Hello World", 1234 ' 寫入以逗號隔開的數據。 Write #1, ' 寫入空白行。 Dim MyBool, MyDate, MyNull, MyError ' 賦值 Boolean、Date、Null 及 Error 等。 MyBool = False : MyDate = #February 12, 1969# : MyNull = Null MyError = CVErr(32767) ' Boolean 數據以 #TRUE# 或 #FALSE# 的格式寫入。 ' 日期以通用日期格式寫入,例如:#1994-07-13# 代表 ' 1994 年 1 月 13 日。Null 數據以 #NULL# 格式寫入。 ' Error 數據以 #ERROR 錯誤代號# 的格式寫入。 Write #1, MyBool; " is a Boolean value" Write #1, MyDate; " is a date" Write #1, MyNull; " is a null value" Write #1, MyError; " is an error value" Close #1 ' 關閉文件。 ?
我們可以看到寫入的內容為: "Hello World",1234 #FALSE#," is a Boolean value" #1969-02-12#," is a date" #NULL#," is a null value" #ERROR 32767#," is an error value" 10、Line Input # 語句 語法:Line Input #filenumber, varname 功能:從已打開的順序文件中讀出一行并將它分配給 String 變量。 說明:通常用 Print # 與 Line Input # 語句配合使用。 Line Input # 語句一次只從文件中讀出一個字符,直到遇到回車符 (Chr(13)) 或回車–換行符 (Chr(13) + Chr(10)) 為止。回車–換行符將被跳過,而不會被附加到字符串上。 示例: Dim TextLineOpen "TESTFILE" For Input As #1 ' 打開文件。 Do While Not EOF(1) ' 循環至文件尾。 Line Input #1, TextLine ' 讀入一行數據并將其賦予某變量。 Debug.Print TextLine ' 在立即窗口中顯示數據。 LoopClose #1 ' 關閉文件。 ?
11、Input 函數 語法:Input(number, [#]filenumber) 其中number 指定要返回的字符個數。 功能:返回 String,它包含以 Input 或 Binary 方式打開的文件中的字符。 說明:通常用 Print # 或 Put 將 Input 函數讀出的數據寫入文件。Input 函數只用于以 Input 或 Binary 方式打開的文件。 與 Input # 語句不同,Input 函數返回它所讀出的所有字符,包括逗號、回車符、空白列、換行符、引號和前導空格等。 示例: Dim MyCharOpen "f:\test.txt" For Input As #1 Do While Not EOF(1) ' 循環至文件尾。 MyChar = Input(1, #1) ' 讀入一個字符。 Debug.Print MyChar ' 顯示到立即窗口。 LoopClose #1 ?
下面這個函數可以將文本文件的數據一次讀入到一個字符串(但是若包含中文時會出錯,因為一個中文字占2個字節)。 Public Function ReadText(FileName As String) Dim fnum%, isopen As Boolean On Error GoTo erro fnum = FreeFile() Open FileName For Input As #fnum isopen = True ReadText = Input(LOF(fnum), fnum) erro: If isopen Then Close #fnum If err Then Debug.Print err.Number, err.Description End Function
12、Print # 語句 語法:Print #filenumber, [outputlist] outputlist 參數的設置如下: [{Spc(n) | Tab[(n)]}] [expression] [charpos] Spc(n) 用來在輸出數據中插入空白字符,而 n 指的是要插入的空白字符數。 Tab(n) 用來將插入點定位在某一絕對列號上,這里,n 是列號。使用無參數的 Tab 將插入點定位在下一個打印區的起始位置。 expression 要打印的數值表達式或字符串表達式。 charpos 指定下一個字符的插入點。使用分號將插入點定位在上一個顯示字符之后。用 Tab(n) 將插入點定位在某一絕對的列號上,用無參數的 Tab 將插入點定位在下一個打印區的起始處。如果省略 charpos,則在下一行打印下一個字符。 功能:將格式化顯示的數據寫入順序文件中。 說明:通常用 Line Input # 或 Input 讀出 Print # 在文件中寫入的數據。 示例: Open "F:\test.txt" For Output As #1 ' 打開輸出文件。 Print #1, "This is a test" ' 將文本數據寫入文件。 Print #1, ' 將空白行寫入文件。 Print #1, "Zone 1"; Tab; "Zone 2" ' 數據寫入兩個區(print zones)。 Print #1, "Hello"; " "; "World" ' 以空格隔開兩個字符串。 Print #1, Spc(5); "5 leading spaces " ' 在字符串之前寫入五個空格。 Print #1, Tab(10); "Hello" ' 將數據寫在第十列。 ' 賦值 Boolean、Date、Null 及 Error 等。 Dim MyBool, MyDate, MyNull, MyError MyBool = False: MyDate = #2/12/1969#: MyNull = Null MyError = CVErr(32767) ' True、False、Null 及 Error 會根據系統的地區設置自動轉換格式。 ' 日期將以標準的短式日期的格式顯示。 Print #1, MyBool; " is a Boolean value" Print #1, MyDate; " is a date" Print #1, MyNull; " is a null value" Print #1, MyError; " is an error value" Close #1 ?
以上代碼寫入的內容如下: This is a test Zone 1 Zone 2 Hello World 5 leading spaces Hello False is a Boolean value 1969-2-12 is a date Null is a null value Error 32767 is an error value 13、Width # 語句 語法:Width #filenumber, width width 必要。范圍在 0–255 之間的數值表達式,在新的一行開始之前,指出在該行上可出現多少字符。如果 width 等于 0,則行的長度不受限制。width 的缺省值為 0。 功能:將一個輸出行的寬度指定給用 Open 語句打開的文件。 示例: Dim IOpen "f:\TESTFILE.txt" For Output As #1 Width #1, 5 ' 設置輸出行寬為 5。 For I = 0 To 9 ' 循環 10 次。 Print #1, Chr(48 + I); ' 每行輸出五個字符。 Next I Close #1 ?
以上代碼寫入的內容如下: 01234 56789 (四)處理二進制文件 打開二進制文件可以使用Open語句的Random和Binary方式打開。二進制文件讀寫使用Get和Put語句。 1、Put 語句 語法:Put [#]filenumber, [recnumber], varname recnumber 可選。Variant (Long)。記錄號(Random 方式的文件)或字節數(Binary 方式的文件),指明在此處開始寫入。 說明:通常用 Get 將 Put 寫入的文件數據讀出來。 示例: Dim num As Long, text As Strin gnum = 12345text = "a string" Open "f:\data.bin" For Binary As #1 '打開或創建一個二進制文件 Put #1, , num '寫入4個字節 Put #1, , text '寫入8個字節(字符串長為8) Close #1 ?
2、Get 語句 語法:Get [#]filenumber, [recnumber], varname recnumber 可選。Variant (Long)。記錄號(Random 方式的文件)或字節數(Binary 方式的文件),以表示在此處開始讀出數據。 功能:將一個已打開的磁盤文件讀入一個變量之中。 說明:通常用 Put 將 Get 讀出的數據寫入一個文件。 示例:讀取以上代碼寫入的內容 Dim num As Long, text As String Open "f:\data.bin" For Binary As #1 Get #1, , numtext = Space$(8) '準備8個字節的字符串 Get #1, , text '讀入 Debug.Print num, text Close #1 ?
在立即窗口可以看到如下內容: 12345 a string 3、Seek 語句 語法:Seek [#]filenumber, position 其中position 為介于 1~ 2,147,483,647(相當于 2^31 – 1)之間的數字,指出下一個讀寫操作將要發生的位置。 功能:在 Open 語句打開的文件中,設置下一個讀/寫操作的位置。 說明:可以用Seek語句指定Get語句的讀取位置,但在 Get 及 Put 語句中指定的記錄號將覆蓋由 Seek 語句指定的文件位置。 示例: Dim MaxSize, NextChar, MyChar Open "TESTFILE" For Input As #1 MaxSize = LOF(1) ' 取得文件的總字符數。' 用循環讀入所有記錄,但是從最后的記錄開始往前讀。 For NextChar = MaxSize To 1 Step -1 Seek #1, NextChar ' 設置讀寫位置。 MyChar = Input(1, #1) ' 讀入一字符。 Next NextChar Close #1 ?
4、Seek 函數 語法:Seek(filenumber) 功能:返回一個 Long,在 Open 語句打開的文件中指定當前的讀/寫位置。 說明:在使用Get語句讀取文件時,必須用LOF函數來判斷是否到達文件末尾,而不是用EOF函數。可以使用Seek函數判斷當前位置,然后與LOF的值比較。 示例: Do While Seek(1) < lof(1)="" '繼續讀取=""> '...... Loop ?
(五)小結 VBA語句的文件操作涵蓋了文件操作的絕大部分內容,很多函數的使用也很簡單,一般的文件讀寫也非常方便,特別是對文本文件。但對于復雜的文件讀寫,代碼的結構和維護性都不好。因此在VB6之后,微軟引入了FileSystemObject對象模型,提供了面向對象的類庫,來操作驅動器、文件夾和文件。但對于二進制文件的操作,目前還只能用VBA語句。
Excel整體界面趨于平面化,顯得清新簡潔。流暢的動畫和平滑的過渡,帶來不同以往的使用體驗。 |