用VBA操纵目录及文件
对Windows系统,目录(文件夹) 和文件本质上没有区别。
我们常见的操作无非是:
- 查询:找指定的目录下有哪些子目录或文件。或者查指定的目录或文件是否存在。
- 创建:如果目录不存在,新建一个目录
- 改名:将原目录名或文件名改成一个新名字
- 删除:删除指定的目录或文件
- 复制:将指定的目录或文件复制到另一个地方
- 移动:将指定的目录或文件复制到另一个地方。可以认为移动是复制和删除的组合。
显然查询是最基础的,因为其它操作之前,都需要先确认同名目录或文件是否已经存在。
VBA操纵目录及文件有两个基本技术路线:
- 用VBA自带的命令
- 用FSO对象(File System Object)
用VBA自带的命令
VBA自带了一些文件操作命令,使用非常方便。这些命令有些是Function微软官方文档, 有些是Statements 微软官方文档, 这里不细分。
1. 查询目录或文件是否存在
使用命令 Dir可以检查指定的目录或文件是否存在, 它返回一个字符串。如果存在,则返回文件名,否则返回空。
方法格式为: Dir [ (pathname, [ attributes ] ) ]
详细请参见 Dir微软官方文档
第二个参数为vbDirectory,则查询目录
strSourceDir = "C:\Temp"
If Dir(strSourceDir, vbDirectory) = "" Then MsgBox "此目录不存在!"
可以用Dir来查询某个目录中有哪些文件及文件名。注意首次查询返回第一个文件名,第二次查询时, 直接用Dir()
Dim strFN As String '文件名
Dim i As Integer '计数变量
i = 0
strFN = Dir("C:\Temp\*.txt", vbNormal)
Do While strFN <> ""
i = i + 1
strFN = Dir()
Loop
MsgBox "有" & i & "个文件!"
当然如果用FSO对象,会简单很多。
2. 创建目录
MKDir
If Dir(strPath, vbDirectory) = "" Then MkDir strPath
3.删除目录或文件
删除文件用Kill
Kill "c:\temp\test.txt"
Kill "C:\Temp\*.txt"
删除目录用RmDir (Remove Directory)
RmDir "c:\temp\test"
4. 目录和文件改名
FSO对象并没有提供改名功能,所以用VBA自带的功能就非常重要
If Dir("C:\Temp.txt" )<>"" Then
Name "C:\Temp.txt" As "C:\Temp_NewName.txt"
End If
5.复制文件
FileCopy SourceFile, DestinationFile
6.取得当前目录, 更改当前目录
CurDir
strMyPath = CurDir
ChDrive "D"
ChDir "D:\TMP" '
用FSO对象
顾名思义, File System Object 文件系统对象,自然就是用来处理文件相关事宜,这是一个强大而复杂的组件。详细可参见FSO官方文档
但是我们并不需要了解或掌握全部功能,掌握够用就好了。
要想使用FSO对象,有两种方法,一种是前引用,一种是后引用。
-
前引用
前引用就是在VBA编程界面的Tool–>Reference 里增加对“Microsoft Scripting Runtime”的引用,如下图:
增加这个引用后,在代码中定义一个对象变量就可以使用如下方法:Dim objFSO As New FileSystemObject
对于初学者,推荐这种方法,因为使用这种方法定义的对象变量,在后续输入代码时,系统会给出对象的方法和属性的提示。
-
后引用适合有经验的用户。使用前无需增加引用。
Set objFSO = CreateObject("Scripting.FileSystemObject")
1.用FSO 判断文件或目录是否存在
不像VBA自带的命令,FSO分得比较细。查盘符是否存在、目录是否存在、查文件是否存在是分开的:
blYesNo = objFSO.DriveExists("D:\")
blYesNo = objFSO.FolderExists("C:\Temp")
blYesNo = objFSO.FileExists("C:\Temp\test.txt")
分别对应3个方法,返回值一个逻辑值True 或是 False
2.用FSO 创建目录
objFSO.CreateFolder("C:\Temp\Test")
该方法没有返回值。注意如果目录已经存在,会触发错误,所以比较好的策略是在创建前,先判断是否已经存在,如果不存在再创建。
3.用FSO 对目录或文件改名
非常遗憾的是,FSO并没有提供此功能。
4.用FSO删除目录或文件
objFSO.DeleteFile "C:\Temp\Test\Test.txt", True
objFSO.DeleteFolder "C:\Temp\Test", True
第2个参数可选,如果为True, 强制删除read only的文件或目录
5.用FSO复制目录或文件
objFSO.CopyFile "C:\Temp\Test.txt", "C:\Temp\Test\Test.txt", True
objFSO.CopyFile "C:\Temp\*.txt", "C:\Temp\Test\"
objFSO.CopyFolder "C:\Temp\*", "D:\Temp\Test\"
第3个参数为 True 则如果目标文件夹里已经有同名文件,则覆盖。
6. 用FSO移动目录或文件
objFSO.MoveFile "C:\Temp\Test.txt", "C:\Temp\Test\Test.txt"
objFSO.MoveFolder "C:\Temp\", "D:\Temp\Test\"
7. 用FSO取得某目录中的文件数量及文件名
前面介绍了用Dir命令如何取得某目录中的全部文件名,有些曲折。用FSO对象处理则简单地多。
FSO中有Folder对象, File对象, Files对象(File对象的集合)
用GetFolder() 方法可以取得指定的Folder对象。可以再从Folder对象中取得对应的Files对象。从 Files对象可以访问到每一个具体的File对象.
'FSO相关对象
Dim objFSO As New FileSystemObject
Dim objFolder As Folder
Dim objFile As File
Dim objFiles As Files
Set objFolder = objFSO.GetFolder(strCurrentDir)
Set objFiles = objFolder.Files
intFiles = objFiles.Count '统计有多少个文件很简单!
If intFiles = 0 Then
MsgBox "此目录下没有文件!"
Else
For Each objFile In objFiles
Debug.Pring objFile.Name '输出文件名
Next
End If