如果希望处理文件或文件系统,有几种选择可用。最好的选择取决于您希望完成什么任务。可用的选择包括使用VBA函数、Microsoft Scripting Runtime对象库、FileSearch对象,以及与文件系统相关的Windows API函数。
使用VBA函数
可以使用许多VBA函数处理文件系统,下表对这些函数进行了总结。
VBA函数或语句
说明
Dir |
返回与指定的格式或文件属性相匹配的文件、目录或文件夹的名称。 |
GetAttr |
返回文件、目录或文件夹的属性。 |
SetAttr |
指定文件、目录或文件夹的属性。 |
CurDir |
返回当前目录。 |
ChDir |
修改当前目录。 |
ChDrive |
修改当前驱动器。 |
MkDir |
创建一个新目录。 |
RmDir |
移除一个现有的目录。 |
Kill |
删除一个或多个文件。 |
FileLen |
以字节返回磁盘中文件的长度。 |
LOF |
以字节返回一个打开文件的长度。 |
FileCopy |
复制磁盘中的文件。 |
FileDateTime |
返回文件创建或最后修改的日期和时间。 |
Name |
重命名文件并将其移动到磁盘中另一个位置。 |
Open |
打开磁盘中的文件来读取或写入。 |
Input |
从打开的文件中读取字符。 |
Print |
写文本到顺序文件中。 |
Write |
写文本到顺序文件中。 |
Close |
关闭使用Open语句打开的文件。 |
如何使用Dir函数判断某文件是否存在?
Dir函数返回在pathname参数中指定的文件的名称。通常使用Dir函数来判断是否指定的文件存在,例如下面的DoesFileExist函数:
Function DoesFileExist(strFileSpec As String) As Boolean
' 如果参数strFileSpec指定的文件存在则返回True.
' 如果strFileSpec不是有效的文件或者是一个目录则返回False.
Const INVALID_ARGUMENT As Long = 53
On Error GoTo DoesfileExist_Err
If (GetAttr(strFileSpec) And vbDirectory) <> vbDirectory Then
DoesFileExist = CBool(Len(Dir(strFileSpec)) > 0)
Else DoesFileExist = False
End If
DoesfileExist_End:
Exit Function DoesfileExist_Err:
DoesFileExist = False
Resume DoesfileExist_End
End Function
本例中,GetAttr函数用于确保strFileSpec参数中的值不是一个目录。这是因为,如果向Dir函数中传递一个有效的目录名称,那么将返回在该目录中找到的第一个文件。
如何使用Dir函数获取文件夹中所有文件的名称?
如果pathname参数包含文件夹的路径而不是文件夹中某文件的名称,那么Dir函数返回在该文件夹中找到的第一个文件的名称。接着,再调用Dir函数而无需任何参数,获取文件夹中后面每一个文件的名称。例如,下面的过程返回一个数组,包含在strDirPath参数中指定的目录内所有文件的名称:
Function GetAllFilesInDir(
ByVal strDirPath
As String)
As Variant ' 遍历strDirPath中指定的目录并在数组中保存每个文件名 ' 然后返回该数组到调用过程. ' 如果strDirPath不是一个有效的目录则返回False. Dim strTempName
As String Dim varFiles()
As Variant Dim lngFileCount
As Long On Error GoTo GetAllFiles_Err
' 确保strDirPath以"\"字符结尾. If Right$(strDirPath, 1) <>
"\" Then strDirPath = strDirPath &
"\" End If ' 确保strDirPath是一个目录. If GetAttr(strDirPath) = vbDirectory
Then strTempName = Dir(strDirPath, vbDirectory)
Do Until Len(strTempName) = 0
' 排除 ".", "..". If (strTempName <>
".")
And (strTempName <>
"..")
Then ' 确保没有子目录名称. If (GetAttr(strDirPath & strTempName) _
And vbDirectory) <> vbDirectory
Then ' 增加数组的大小以适应发现的文件名并将其添加到数组. ReDim Preserve varFiles(lngFileCount) varFiles(lngFileCount) = strTempName lngFileCount = lngFileCount + 1
End If End If ' 使用Dir函数查找下一个文件名. strTempName = Dir()
Loop ' 返回包含已找到的文件名称的数组. GetAllFilesInDir = varFiles
End If GetAllFiles_End:
Exit Function GetAllFiles_Err: GetAllFilesInDir =
False Resume GetAllFiles_End
End Function
GetAllFilesInDir函数通过遍历目录中的每一项,并且对于发现的文件,将其名称添加到数组。第一次调用Dir时,使用目录名作为其参数。每增加一次调用都使用不带参数的Dir函数。该过程使用GetAttr函数来确保strDirPath参数包含一个有效的目录,也避免任何子目录的名称被添加到数组中。注意,该过程筛选出“.”和“..”,代表当前目录和父目录。
可以使用下面的过程测试GetAllFilesInDir过程。可以对strDirName参数试不同的值,然后使用F8逐行运行代码,看该过程是如何工作的。
Sub TestGetAllFiles() Dim varFileArray As Variant
Dim lngI As Long Dim strDirName As String
Const NO_FILES_IN_DIR As Long = 9
Const INVALID_DIR As Long = 13
On Error GoTo Test_Err
strDirName = "c:\my documents"
varFileArray = GetAllFilesInDir(strDirName)
For lngI = 0 To UBound(varFileArray)
Debug.Print varFileArray(lngI)
Next lngI
Test_Err:
Select Case Err.Number
Case NO_FILES_IN_DIR MsgBox "The directory named '" & strDirName _ & "' contains no files."
Case INVALID_DIR MsgBox "'" & strDirName & "' is not a valid directory."
Case 0 Case Else MsgBox "Error #" & Err.Number & " - " & Err.Description
End Select
End Sub
使用Microsoft Scripting Runtime Object Library
Microsoft Scripting Runtime对象库包含可以用于操作文件和目录的对象,并且比前面讲述的VBA函数更容易使用。
在使用该对象库之前,必须设置对该对象库的引用。如果在“引用”对话框中没有找到该对象库,那么应该可以在C:\Windows\System子文件夹中找到它(Scrrun.dll)。
下表描述了Scripting Runtime对象库是的对象。
对象
集合
描述
Dictionary |
|
顶层对象,与VBA Collection集合对象相似。 |
Drive |
Drives |
引用系统中的驱动器或驱动器的集合。 |
File |
Files |
引用文件系统中的文件或文件集合。 |
FileSystemObject |
|
顶层对象,用于访问驱动器、文件夹、文件。 |
Folder |
Folders |
引用文件系统中的文件夹或文件夹集合。 |
TextStream |
|
引用读取、写入或追加到文本文件中的一系列文本。 |
在Scripting Runtime对象库中的顶层对象是Dictionary对象和FileSystemObject对象。要使用Dictionary对象,则需创建一个Dictionary类型的对象变量,然后设置其为Dictionary对象的新实例。
Dim dctDict
As Scripting.Dictionary
Set dctDict =
New Scripting.Dictionary
要在代码中使用Scripting Runtime库中的其它对象,必须首先创建FileSystemObject类型的变量,然后使用New关键词创建该FileSystemObject对象的新实例,如下面的代码所示:
Dim fsoSysObj
As Scripting.FileSystemObject
Set fsoSysObj =
New Scripting.FileSystemObject
接着使用这个引用FileSystemObject对象的变量来处理Drive、Folder、File和TextStream对象。
如何使用FileSystemObject对象来处理文件和文件夹?
一旦创建了FileSystemObject对象的新实例,就能够使用它来处理驱动器、文件夹和文件了。
下面的过程返回特定文件夹中的文件到Dictionary对象里。GetFiles过程接受三个参数:目录路径、Dictionary对象、一个可选的布尔参数,指定是否应该递归调用该过程。该过程返回一个布尔值,指明是否过程运行成功。
该过程首先使用GetFolder方法返回对Folder对象的引用,然后遍历该文件夹的Files集合,添加每个文件的文件名称和路径到Dictionary对象中。如果blnRecursive参数设置为True,那么GetFiles过程被递归调用以返回每个子文件夹中的文件。
Function GetFiles(strPath
As String, _ dctDict
As Scripting.Dictionary, _
Optional blnRecursive
As Boolean)
As Boolean ' 本过程返回目录中的所有文件到Dictionary对象中. ' 如果递归调用则同时返回子文件夹中的所有文件. Dim fsoSysObj
As Scripting.FileSystemObject
Dim fdrFolder
As Scripting.Folder
Dim fdrSubFolder
As Scripting.Folder
Dim filFile
As Scripting.File
' 返回新的FileSystemObject. Set fsoSysObj =
New Scripting.FileSystemObject
On Error Resume Next ' 获取文件夹. Set fdrFolder = fsoSysObj.GetFolder(strPath)
If Err <> 0
Then ' 不正确的路径. GetFiles =
False GoTo GetFiles_End
End If On Error GoTo 0
' 遍历Files集合,添加到字典. For Each filFile
In fdrFolder.Files dctDict.Add filFile.Path, filFile.Path
Next filFile
' 如果Recursive标志为真,则递归调用. If blnRecursive
Then For Each fdrSubFolder
In fdrFolder.SubFolders GetFiles fdrSubFolder.Path, dctDict,
True Next fdrSubFolder
End If ' 如果没有错误发生则返回True. GetFiles =
True GetFiles_End:
Exit Function End Function ' 如果没有错误发生则返回True. GetFiles =
True GetFiles_End:
Exit Function End Function
可以使用下面的过程来测试GetFiles过程。该过程创建一个新Dictionary对象,将其传递到GetFiles过程,然后在立即窗口中打印在strDirPath目录及其子目录中的每个文件。
Sub TestGetFiles()
' 测试GetFiles函数. Dim dctDict
As Scripting.Dictionary
Dim varItem
As Variant Dim strDirPath
As String strDirPath =
"c:\my documents\" ' 创建新的字典. Set dctDict =
New Scripting.Dictionary
' 递归调用, 返回文件到Dictionary对象. If GetFiles(strDirPath, dctDict,
True)
Then ' 打印字典中的项目. For Each varItem
In dctDict Debug.
Print varItem
Next End If End Sub
可以对strDirPath参数试验不同的值,看看该过程是如何工作的。
如何使用FileSystemObject来处理文件属性?
File对象和Folder对象提供了Attributes属性,可用来读取或设置文件或文件夹的属性,如下面的示例。
ChangeFileAttributes过程接受四个参数:文件夹的路径、指定要设置的属性的可选的常量、指定要移除的属性的可选常量、指定是否递归调用过程的可选的参数。
如果传递的文件夹路径是有效的,那么该过程返回Folder对象。接着检查是否提供了lngSetAttr参数,如果是,那么该过程遍历文件夹中的所有文件,追加新的属性到每个文件现有的属性中。对于lngRemoveAttr参数做同样的事情,在本例中,如果指定的属性存在于集合中的文件内则移除。
最后,该过程检查blnRecursive参数是否被设置为True,如果是则为strPath参数指定的每个子文件夹中的每个文件调用该过程。
Function ChangeFileAttributes(strPath As String, _ Optional lngSetAttr As FileAttribute, _ Optional lngRemoveAttr As FileAttribute, _ Optional blnRecursive As Boolean) As Boolean
' 本函数接受一个目录路径, 一个指定文件属性设置的值
' 一个指定文件属性移除的值
' 一个指明是否递归调用的标志
' 如果没有发生错误则返回True.
Dim fsoSysObj As Scripting.FileSystemObject
Dim fdrFolder As Scripting.Folder
Dim fdrSubFolder As Scripting.Folder
Dim filFile As Scripting.File
' 返回新的FileSystemObject.
Set fsoSysObj = New Scripting.FileSystemObject
On Error Resume Next
' 获取文件夹.
Set fdrFolder = fsoSysObj.GetFolder(strPath)
If Err <> 0 Then ' 不正确的路径.
ChangeFileAttributes = False
GoTo ChangeFileAttributes_End
End If On Error GoTo 0 ' 如果调用者传递属性去设置则设置所有的.
If lngSetAttr Then
For Each filFile In fdrFolder.Files
If Not (filFile.Attributes And lngSetAttr) Then
filFile.Attributes = filFile.Attributes Or lngSetAttr
End If
Next
End If ' 如果调用者传递属性去移除则移除所有的.
If lngRemoveAttr Then
For Each filFile In fdrFolder.Files
If (filFile.Attributes And lngRemoveAttr) Then
filFile.Attributes = filFile.Attributes - lngRemoveAttr End If Next End If
' 如果调用者设置blnRecursive参数为True,则递归调用函数.
If blnRecursive Then
' 遍历子文件夹.
For Each fdrSubFolder In fdrFolder.SubFolders
' 调用带有子文件夹路径的函数.
ChangeFileAttributes fdrSubFolder.Path, lngSetAttr, _ lngRemoveAttr, True
Next
End If
ChangeFileAttributes = True
ChangeFileAttributes_End: Exit Function
End Function
可以使用下面的过程测试ChangeFileAttributes过程。在本例中,具有隐藏属性设置的“我的文档”文件夹中的所有文件被设置可见:
Sub TestChangeAttributes()
If ChangeFileAttributes(
"c:\my documents", , _ Hidden,
False) =
True Then MsgBox
"File attributes succesfully changed!" End If End Sub
可以对ChangefileAttributes过程中的参数试验不同的值,看看该过程是如何工作的。
使用FileSearch对象
FileSearch对象是Microsoft Office 9.0 Object Library中的一个成员,公开了Office文件打开对话框的所有功能的编程接口,包括在高级查找对话框中的功能。可以使用FileSearch对象的对象、方法和属性基于提供的条件来搜索文件或文件集合。
下面的示例展示了如何使用FileSearch驿象查找在strFilespec参数中指定类型的一个和多个文件。注意,通过分号分隔符指定扩展名列表可以搜索多个文件扩展名:
Function CustomFindFile(strFileSpec As String)
' 本过程演示一个简单的文件搜索程序
' 显示一个消息框,包含在"C:\"目录中与参数strFileSpec提供的文件规范相匹配的所有文件的名称
' 参数strFileSpec可以包含一个或多个在分号分隔列表中的文件规格.
' 例如,下面的strFileSpec参数返回"c:\"中包含扩展名"*.log;*.bat;*.ini"的包有文件
Dim fsoFileSearch As Office.FileSearch
Dim varFile As Variant Dim strFileList As String
' 如果输入有效,那么处理文件搜索.
If Len(strFileSpec) >= 3 And InStr(strFileSpec, "*.") > 0 Then
Set fsoFileSearch = Application.FileSearch
With fsoFileSearch .NewSearch .LookIn = "c:\" .Filename = strFileSpec .SearchSubFolders = False If .Execute() > 0 Then
For Each varFile In .FoundFiles
strFileList = strFileList & varFile & vbCrLf
Next varFile
End If
End With
MsgBox strFileList
Else MsgBox strFileSpec & " is not a valid file specification."
Exit Function
End If
End Function
FileSearch对象有两个方法和一些属性,可用于在自定义的Office解决方案中创建自定义文件搜索功能。上述示例使用NewSearch方法清除任何以前的搜索条件,Execute方法执行搜索特定的文件。Execute方法返回找到的文件数,同时支持可选的参数来指定排序顺序、排序类型、以及是否用来仅保存快速搜索索引来执行搜索。使用FoundFiles属性返回对FoundFiles对象的引用(FoundFiles对象包含搜索中找到的所有匹配文件的名称)。
使用LookIn属性指定搜索的目录,使用SearchSubFolders属性指定是否搜索在LookIn属性指定的目录中的子文件夹。FileName属性支持通配符和文件名或文件类型规范的分号分隔列表。
注:本文初译自MSDN:Working with Files, Folders, and Drives: More VBA Tips and Tricks,辑录于此,作为文件操作应用大全的一部分。
相关推荐
01037设置最近使用的文件清单中的最多文件数 01038设置新工作簿中的工作表个数 01039设置文件的默认位置 01040设置保存自动恢复文件的时间间隔和保存位置 01041停止屏幕刷新 01042使事件无效 01043使取消键无效 ...
第十三章 调试VBA过程和处理错误 264 1.测试VBA过程 265 2.终止过程 265 3.使用断点 266 4.在中断模式下使用立即窗口 269 5.使用STOP语句 271 6.添加监视表达式 271 7.清除监视表达式 274 8.使用快速监视 274 9.使用...
第十三章 调试VBA过程和处理错误 264 1.测试VBA过程 265 2.终止过程 265 3.使用断点 266 4.在中断模式下使用立即窗口 269 5.使用STOP语句 271 6.添加监视表达式 271 7.清除监视表达式 274 8.使用快速监视 274 9.使用...
注意:使用 bootcfg /rebuild 之前,应先通过 bootcfg /copy 命令备份 boot.ini 文件。 bootcfg /scan 扫描用于 Windows 安装的所有磁盘并显示结果。 注意:这些结果被静态存储,并用于本次会话。如果在...
函数作用:判断一个文件是否在使用中.................92 '85.函数作用:列出档案详细摘要信息.....................93 '86.函数作用:获取菜单ID编号及名称列表................93 '87.函数作用:状态列动态显示文字......
124.自动断开网络驱动器 125.连接选定单元格中的内容 126.获取一个单元格中有指定字体颜色部份数据 127.对指定文件加XLS加密 128.选择指定范围内使用了填充颜色的单元格 129.在特定的区域内查找文本,返回值是包含...
但是,不会在驱动器上创建虚拟文件夹结构。 虽然我主要从RDVBA增强的IDE中编辑VBA代码,但是我经常需要检查其他VBA项目中的内容以复制一段代码或一组模块。 我不在IDE中打开此类项目,而是使用文件管理器转到项目...
8.2 运用选择查询:使用查询设计网格 187 8.2.1 表的联接 188 8.2.2 同一个表使用两次(自联接) 189 8.2.3 使用Access的自动查阅功能 191 8.3 运用操作查询:力量的源泉 193 8.3.1 生成表查询(SELECT ...
8.2 运用选择查询:使用查询设计网格 187 8.2.1 表的联接 188 8.2.2 同一个表使用两次(自联接) 189 8.2.3 使用Access的自动查阅功能 191 8.3 运用操作查询:力量的源泉 193 8.3.1 生成表查询(SELECT INTO) ...
调用java源码JSON到CSV 它包含两个文件,第一个是解析JSON的java ...从vba设置目录(我建议使用c驱动器以避免管理员问题) 使用vba中的Shell()函数调用.bat文件 引用米卡·富尔顿(Micah Fulton)挽救生命。
1457.2.4 处理外部文件中的图像 1487.2.5 将字段数据类型转换为Access数据 类型 1497.2.6 使用链接表管理器加载项重新 链接表 1507.2.7 导入表和将数据库文件链接为表 1507.3 导入和链接电子数据表文件 1517.3.1 ...
1457.2.4 处理外部文件中的图像 1487.2.5 将字段数据类型转换为Access数据 类型 1497.2.6 使用链接表管理器加载项重新 链接表 1507.2.7 导入表和将数据库文件链接为表 1507.3 导入和链接电子数据表文件 1517.3.1 ...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...
1457.2.4 处理外部文件中的图像 1487.2.5 将字段数据类型转换为Access数据 类型 1497.2.6 使用链接表管理器加载项重新 链接表 1507.2.7 导入表和将数据库文件链接为表 1507.3 导入和链接电子数据表文件 1517.3.1 ...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...
1457.2.4 处理外部文件中的图像 1487.2.5 将字段数据类型转换为Access数据 类型 1497.2.6 使用链接表管理器加载项重新 链接表 1507.2.7 导入表和将数据库文件链接为表 1507.3 导入和链接电子数据表文件 1517.3.1 ...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...
1567.4 使用Microsoft Outlook和Exchange文件夹 1567.4.1 用Outlook导出和导入Jet 4.0表 1577.4.2 使用Exchange/Outlook向导的链接 1597.5 导入文本文件 1607.5.1 使用导入文本向导 1617.5.2 导入文本向导的高级选项...