文章背景:在VBA中,通过Dir函数,可以判断指定路径的文件是否存在等。此外,借助FileSystemObject对象,我们同样可以操作文件和文件夹。
FileSystemObject对象模型,是微软提供的专门用来访问计算机文件系统的,具有大量的属性和方法。其使用面向对象的“object.method”语法来处理文件夹和文件,使用起来十分方便。FileSystemObject并不是VBA的一部分,它是以一个COM组件的形式提供的。因此,使用前要创建FileSystemObject对象。
1 创建FSO对象1.1 直接创建法 1.2 引用法2 借助FSO可以获取的对象3 FSO对象的属性4 应用示例4.1 检查文件或文件夹是否存在4.2 基于给定路径,创建新文件夹4.3 获取文件夹内所有文件的名称4.4 获取文件夹内所有子文件夹的名称4.5 获取文件夹及其子文件夹内所有文件的名称4.6 拷贝文件4.7 拷贝文件夹
A big downside of using this method is that it would not show an IntelliSense when you work with objects in FSO.
使用直接创建法的缺点是,在VBA代码中,在使用FSO对象时,无法使用自动补全代码的功能。
通过VBE编译器里的工具
->引用
,打开引用
对话框,在可使用的引用
中,找到Microsoft Scripting Runtime
选项 ,点击确定
。具体操作如下:
完成上述步骤之后,接下来就可以在VBA代码中引用FSO对象。
Sub CreatingFSO() Dim MyFSO As FileSystemObject Set MyFSO = New FileSystemObject End Sub
(1) 通过New
关键字,创建FileSystemObject的实例(Instance)。
(2) 通过Set
关键字,将这个FileSystemObject的新实例赋给MyFSO对象。
如果需要的话,可以将上述的两条代码整合为一条。
采用引用法
的好处是,在代码中使用FSO对象时,可以通过代码自动补全的功能,显示FSO对象的属性和方法。
下表展示了借助FSO可以获取和修改的几个重要的对象。
假如C盘中有如下的文件结构:
# a -> b -> 1dog.txt, 2cat.txt # c -> 3panda.txt # d -> e # 4duck.txt # 5horse.txt
(1)检查指定路径的文件夹是否存在
运行后,立即窗口中显示的是:
The Folder Exists.
VBA中的Dir
函数,可以实现类似的功能,用到的主要代码为:CheckDir = Dir(PathName, vbDirectory)
。
(2)检查指定路径的文件是否存在
运行后,立即窗口中显示的是:
The File Exists.
VBA中的Dir
函数,可以实现类似的功能,用到的主要代码为:FileName = Dir(Path)
。
由于文件夹f
一开始不存在,因此,运行代码后,创建新的文件夹f
。
(1) 通过MyFSO.FolderExists
判断文件夹是否存在;若不存在,则通过MyFSO.CreateFolder
创建新的文件夹。
(2)也可以通过VBA的Dir
函数判断文件夹是否存在;若不存在,则通过MkDir
函数创建新的文件夹。
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
运行后,立即窗口中显示的是:
此外,借助VBA中的Dir
函数,以及Do...Loop
循环,也可以实现类似的功能。
Sub GetSubFolderNames() Dim MyFSO As FileSystemObject Dim MyFile As File 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
运行后,立即窗口中显示的是:
此外,借助VBA中的Dir
函数,以及Do...Loop
循环,也可以实现类似的功能。
通过递归法,使用FSO对象获取文件夹及其子文件夹内所有文件的名称。
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, 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
运行getAllFileNames
的代码,立即窗口中显示的是:
把一个或多个文件从一个地方复制到另一个地方。
object.CopyFilesource, destination, [ overwrite]
source-- Required. Character string file specification, which can include wildcard
characters, for one or more files to be copied.
destination-- Required. Character string destination where the file or files from sourceare to be copied. Wildcard
characters are not
allowed.
overwrite-- Optional. Booleanvalue that indicates if existing files are to be overwritten. If True, files are overwritten; if False, they are not. The default is True. Note that CopyFilewill fail if destinationhas the read-only attribute set, regardless of the value of overwrite.
关于通配符的使用,说明如下:
Wildcard characters can only be used in the last path component of the sourceargument. For example, you can use:
FileSystemObject.CopyFile 'c:\a\b\*.txt', 'c:\a\'
But you can't use:
更多关于object.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
上述代码仅仅作为示例使用。实际工作中,拷贝前,需要提前判断:1) Source
文件是否存在;2) Destination
路径中是否已存在同名文件。
4.6.2 拷贝多个指定类型的文件
(1)借助通配符,可以实现一次性拷贝多个指定文件到指定文件夹内。
(2)如果 source中包含通配符或 destination中以路径分隔符(\
)为结尾,则认为 destination是一个已存在文件夹,在其中复制相匹配的文件。
Recursively copies a folder from one location to another.
object.CopyFoldersource, destination, [ overwrite]
source-- Required. Character string folder specification, which can include wildcard
characters, for one or more folders to be copied.
destination-- Required. Character string destination where the folder and subfolders from sourceare to be copied. Wildcard
characters are not
allowed.
overwrite-- Optional. Booleanvalue that indicates if existing folders are to be overwritten. If True, files are overwritten; if False, they are not. The default is True.
更多关于object.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
(1)上述代码将文件夹b
拷贝到文件夹d
内。
(2) If sourcecontains wildcard characters, or destinationends with a path separator (\
), it is assumed that destinationis an existing folder in which to copy matching folders and subfolders.
4.7.2 拷贝多个文件夹
(1)将文件夹d
内所有的子文件夹拷贝到文件夹a
内,本例中文件夹d
内只有一个子文件夹,也就是e
。
(2)如果 source中包含通配符,则认为 destination是一个已存在的文件夹。如果destination文件夹不存在,则运行时会报错:Run-time error '76': Path not found
。
参考资料:
[1] excel VBA 操作文件的主要方法 利用FileSystemObject对象来处理文件(https://www.office26.com/excelhanshu/vba-read-write-files-03.html)
[2] Excel VBA 操作文件(夹)神器--FSO对象(https://zhuanlan.zhihu.com/p/104704524)
[3] FileSystemObject object(https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/filesystemobject-object)
[4] Using VBA FileSystemObject (FSO) in Excel – Easy Overview & Examples(https://trumpexcel.com/vba-filesystemobject/)
[5] How to use the MKDIR Statement (VBA)(https://www.techonthenet.com/excel/formulas/mkdir.php)
[6] CopyFile method(https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/copyfile-method)
[7] VBA中CopyFile 方法的功能及应用(https://blog.csdn.net/kongwei521/article/details/7176558)
[8] CopyFolder method(https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/copyfolder-method)
联系客服