VBA FileSystemObject 使用指南
文章背景
文章背景: 在 VBA 中,通过 Dir 函数可以判断指定路径的文件是否存在。此外,借助 FileSystemObject 对象,我们同样可以操作文件和文件夹。
FileSystemObject 对象模型是微软提供的专门用于访问计算机文件系统的工具,具有丰富的属性和方法。它采用面向对象的 object.method 语法来处理文件夹和文件,使用起来非常方便。需要注意的是,FileSystemObject 并非 VBA 内置组件,而是以 COM 组件形式提供,因此在使用前需创建 FileSystemObject 对象。
目录
- 创建 FSO 对象
- 1.1 直接创建法
- 1.2 引用法
- 借助 FSO 可以获取的对象
- FSO 对象的属性
- 应用示例
- 4.1 检查文件或文件夹是否存在
- 4.2 基于给定路径,创建新文件夹
- 4.3 获取文件夹内所有文件的名称
- 4.4 获取文件夹内所有子文件夹的名称
- 4.5 获取文件夹及其子文件夹内所有文件的名称
- 4.6 拷贝文件
- 4.7 拷贝文件夹
1. 创建 FSO 对象
1.1 直接创建法
Sub FSODemo()
Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
End Sub
缺点: 使用直接创建法时,在 VBA 代码中操作 FSO 对象时,无法使用 IntelliSense 自动补全功能。
1.2 引用法
通过 VBE 编译器的 工具 -> 引用,打开 引用 对话框,在 可使用的引用 中找到 Microsoft Scripting Runtime 选项,勾选后点击 确定。具体操作如下:
(此处可插入 00:37 的视频或截图说明操作步骤)
完成上述步骤后,即可在 VBA 代码中引用 FSO 对象:
Sub CreatingFSO()
Dim MyFSO As FileSystemObject
Set MyFSO = New FileSystemObject
End Sub
说明:
- 通过
New关键字创建FileSystemObject的实例。 - 通过
Set关键字将新实例赋给MyFSO对象。
也可以将上述代码合并为一行:
Sub CreatingFSO_1()
Dim MyFSO As New FileSystemObject
End Sub
优点: 使用引用法时,代码中操作 FSO 对象可通过 IntelliSense 显示其属性和方法,方便开发。
(此处可插入 00:21 的视频或截图说明 IntelliSense 效果)
2. 借助 FSO 可以获取的对象
下表展示了借助 FSO 可以获取和修改的几个重要对象:

3. FSO 对象的属性
FSO 对象的属性如下表所示:

4. 应用示例
假设 C 盘中存在以下文件结构:
C:\
├── a
│ ├── b
│ │ ├── 1dog.txt
│ │ └── 2cat.txt
│ ├── c
│ │ └── 3panda.txt
│ ├── d
│ │ └── e
│ ├── 4duck.txt
│ └── 5horse.txt
4.1 检查文件或文件夹是否存在
4.1.1 检查文件夹是否存在
Sub CheckFolderExist()
Dim MyFSO As FileSystemObject
Set MyFSO = New FileSystemObject
If MyFSO.FolderExists("C:\a\b") Then
Debug.Print "The Folder Exists."
Else
Debug.Print "The Folder Does Not Exist."
End If
End Sub
输出结果:
The Folder Exists.
备注: VBA 的 Dir 函数可实现类似功能,核心代码为:CheckDir = Dir(PathName, vbDirectory)。
4.1.2 检查文件是否存在
Sub CheckFileExist()
Dim MyFSO As FileSystemObject
Set MyFSO = New FileSystemObject
If MyFSO.FileExists("C:\a\c\3panda.txt") Then
Debug.Print "The File Exists."
Else
Debug.Print "The File Does Not Exist."
End If
End Sub
输出结果:
The File Exists.
备注: VBA 的 Dir 函数可实现类似功能,核心代码为:FileName = Dir(Path)。
4.2 基于给定路径创建新文件夹
Sub CreateFolder()
Dim MyFSO As FileSystemObject
Set MyFSO = New FileSystemObject
If MyFSO.FolderExists("C:\a\f") Then
Debug.Print "The Folder Already Exists."
Else
MyFSO.CreateFolder "C:\a\f"
Debug.Print "Folder Created."
End If
End Sub
说明:
- 通过
MyFSO.FolderExists判断文件夹是否存在。 - 若不存在,则通过
MyFSO.CreateFolder创建新文件夹。
备注: VBA 的 Dir 函数结合 MkDir 可实现类似功能。
4.3 获取文件夹内所有文件的名称
Sub GetFileNames()
Dim MyFSO As FileSystemObject
Dim MyFile As File
Dim MyFolder As Folder
Set MyFSO = New FileSystemObject
Set MyFolder = MyFSO.GetFolder("C:\a")
For Each MyFile In MyFolder.Files
Debug.Print MyFile.Name
Next MyFile
End Sub
输出结果:
4duck.txt
5horse.txt
备注: 使用 VBA 的 Dir 函数结合 Do...Loop 循环可实现类似功能。
4.4 获取文件夹内所有子文件夹的名称
Sub GetSubFolderNames()
Dim MyFSO As FileSystemObject
Dim MyFolder As Folder
Dim MySubFolder As Folder
Set MyFSO = New FileSystemObject
Set MyFolder = MyFSO.GetFolder("C:\a")
For Each MySubFolder In MyFolder.SubFolders
Debug.Print MySubFolder.Name
Next MySubFolder
End Sub
输出结果:
b
c
d
f
备注: 使用 VBA 的 Dir 函数结合 Do...Loop 循环可实现类似功能。
4.5 获取文件夹及其子文件夹内所有文件的名称
通过递归法获取文件夹及其子文件夹内所有文件的名称:
Sub getAllFileNames()
Dim MyFSO As FileSystemObject
Dim MyFolder As Folder
Set MyFSO = New FileSystemObject
If MyFSO.FolderExists("C:\a") Then
Set MyFolder = MyFSO.GetFolder("C:\a")
LookupAllFiles MyFolder
Else
Debug.Print "The Folder Does Not Exist."
End If
End Sub
Sub LookupAllFiles(fld As Folder)
Dim fil As File
Dim outFld As Folder
For Each fil In fld.Files
Debug.Print fil.Name
Next
For Each outFld In fld.SubFolders
LookupAllFiles outFld ' 递归调用
Next
End Sub
输出结果:
4duck.txt
5horse.txt
1dog.txt
2cat.txt
3panda.txt
4.6 拷贝文件
将一个或多个文件从一个位置复制到另一个位置。
语法: object.CopyFile source, destination, [overwrite]
- source:必需。表示要复制的一个或多个文件的字符串,支持通配符。
- destination:必需。表示文件复制的目标路径,不支持通配符。
- overwrite:可选。布尔值,指示是否覆盖已有文件。默认为
True(覆盖)。若目标文件具有只读属性,复制会失败。
通配符说明: 通配符只能用于 source 参数的最后路径组件。例如:
FileSystemObject.CopyFile "C:\a\b\*.txt", "C:\a\"
但不能使用:
FileSystemObject.CopyFile "C:\a\*\*.txt", "C:\a\"
参考资料: 更多 CopyFile 用法见参考资料 [6]。
4.6.1 拷贝单个文件
Sub CopyFile()
Dim MyFSO As FileSystemObject
Dim Source As String
Dim Destination As String
Set MyFSO = New FileSystemObject
Source = "C:\a\b\1dog.txt"
Destination = "C:\a\1dog.txt"
MyFSO.CopyFile Source, Destination
End Sub
注意: 实际操作中,需检查 Source 文件是否存在,以及 Destination 是否已有同名文件。
4.6.2 拷贝多个指定类型的文件
Sub CopyMoreFile()
Dim MyFSO As FileSystemObject
Dim Source As String
Dim Destination As String
Dim FileName As String
Set MyFSO = New FileSystemObject
Source = "C:\a\b\*.txt"
Destination = "C:\a\"
FileName = Dir(Source)
If FileName <> "" Then
If MyFSO.FolderExists(Destination) Then
On Error Resume Next
MyFSO.CopyFile Source, Destination, False
If Err.Number <> 0 Then
Debug.Print "目标文件夹中存在同名文件,请确认!"
End If
On Error GoTo 0
Else
Debug.Print "目标文件夹不存在。"
End If
Else
Debug.Print "未找到指定文件。"
End If
Debug.Print "Done."
End Sub
说明:
- 通过通配符可一次性复制多个指定类型的文件到目标文件夹。
- 若
source包含通配符或destination以路径分隔符(\)结尾,则认为destination为已存在文件夹。
4.7 拷贝文件夹
递归地将文件夹从一个位置复制到另一个位置。
语法: object.CopyFolder source, destination, [overwrite]
- source:必需。表示要复制的一个或多个文件夹的字符串,支持通配符。
- destination:必需。表示文件夹及子文件夹复制的目标路径,不支持通配符。
- overwrite:可选。布尔值,指示是否覆盖已有文件夹。默认为
True(覆盖)。
参考资料: 更多 CopyFolder 用法见参考资料 [8]。
4.7.1 拷贝单个文件夹
Sub CopyFolder()
Dim MyFSO As FileSystemObject
Dim Source As String
Dim Destination As String
Set MyFSO = New FileSystemObject
Source = "C:\a\b"
Destination = "C:\a\d\"
MyFSO.CopyFolder Source, Destination, False
Debug.Print "Done."
End Sub
说明:
- 上述代码将文件夹
b复制到文件夹d内。 - 若
source包含通配符或destination以路径分隔符(\)结尾,则认为destination为已存在文件夹。
4.7.2 拷贝多个文件夹
Sub CopyMoreFolder()
Dim MyFSO As FileSystemObject
Dim Source As String
Dim Destination As String
Set MyFSO = New FileSystemObject
Source = "C:\a\d\*"
Destination = "C:\a\"
If Not MyFSO.FolderExists(Destination) Then
Debug.Print "目标文件夹不存在。"
Exit Sub
End If
On Error Resume Next
MyFSO.CopyFolder Source, Destination, False
If Err.Number <> 0 Then
Debug.Print "匹配不到文件夹,或者目标文件夹内已存在同名文件夹。"
End If
On Error GoTo 0
Debug.Print "Done."
End Sub
说明:
- 将文件夹
d内的所有子文件夹(本例中为e)复制到文件夹a内。 - 若
source包含通配符,则认为destination为已存在文件夹。若destination不存在,会抛出Run-time error '76': Path not found错误。
