VBA使用API_02:遍历文件
时间:2022-07-22
本文章向大家介绍VBA使用API_02:遍历文件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1、遍历文件
我们在VBA中遍历获取所有文件的方法一般是使用下面3种:
- 调用Dir函数
- 使用FileSystemObject
- 使用cmd命令
Dir方法是VBA里封装好了的,但是对于判段是否是文件夹并没有很好的方法,一般是利用文件名是否包含“.”来判断,但这个是很不严谨的。
不过这个方法其实和Windows API的使用方法很相近,只是他的返回值太单一了一点:
Sub TestVBADir()
VBADirR "path"
End Sub
Function VBADirR(strdir As String) As Long
Dim fn As String
fn = VBA.Dir(strdir & "*", vbDirectory)
Do Until fn = ""
If fn <> "." And fn <> ".." Then
Debug.Print fn
End If
fn = VBA.Dir()
Loop
End Function
FileSystemObject方法是对象形式的,好理解。
cmd命令最简单,用dir命令就可以。
这2种方法我在VBA汇总多个Excel文件数据里使用过。
这些方法的底层应该都是调用了Windows API来实现,让我们看看如何直接使用Windows API来实现遍历文件。
2、代码实现
主要使用的是FindFirstFile和FindNextFile2个API:
Const MAX_PATH As Long = 260
Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20
Private Const FILE_ATTRIBUTE_COMPRESSED As Long = &H800
Private Const FILE_ATTRIBUTE_DEVICE As Long = &H40
Private Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10
Private Const FILE_ATTRIBUTE_ENCRYPTED As Long = &H4000
Private Const FILE_ATTRIBUTE_HIDDEN As Long = &H2
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Private Const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED As Long = &H2000
Private Const FILE_ATTRIBUTE_OFFLINE As Long = &H1000
Private Const FILE_ATTRIBUTE_READONLY As Long = &H1
Private Const FILE_ATTRIBUTE_REPARSE_POINT As Long = &H400
Private Const FILE_ATTRIBUTE_SPARSE_FILE As Long = &H200
Private Const FILE_ATTRIBUTE_SYSTEM As Long = &H4
Private Const FILE_ATTRIBUTE_TEMPORARY As Long = &H100
Sub ScanDir()
ScanDirR "path*"
End Sub
Function ScanDirR(lpFileName As String) As Long
Dim hFindFile As Long
Dim fd As WIN32_FIND_DATA
hFindFile = FindFirstFile(lpFileName, fd)
If hFindFile = INVALID_HANDLE_VALUE Then
Debug.Print lpFileName, "FindFirstFile出错"
Exit Function
End If
Dim path As String
path = VBA.Left$(lpFileName, VBA.InStrRev(lpFileName, ""))
Dim ret As Long
ret = 1
'返回的文件名中会包含"."和".."
'“.'代表本目录,".."代表上一层目录
'一般情况下需要把这两个名称过滤掉
Dim tmp As String
Do While ret
tmp = GetFileName(fd.cFileName)
If tmp <> "." And tmp <> ".." Then
If fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY Then
ScanDirR path & tmp & "*"
Else
'输出文件名中包含“xls”的文件
If tmp Like "*xls*" Then Debug.Print path & tmp, VBA.Hex(fd.dwFileAttributes)
End If
End If
ret = FindNextFile(hFindFile, fd)
Loop
FindClose hFindFile
End Function
'去除多余的空字符
Function GetFileName(str As String) As String
Dim index As Long
index = VBA.InStr(str, VBA.Chr(0))
If index Then
GetFileName = VBA.Left$(str, index - 1)
Else
GetFileName = str
End If
End Function
3、小结
使用API来实现遍历文件功能可以增强我们的灵活性,因为返回值WIN32_FIND_DATA里面记录了较多信息,理解这个也能让我们明白底层的一些原理。
- Selenium2+python自动化54-unittest生成测试报告(HTMLTestRunner)
- Selenium2+python自动化55-unittest之装饰器(@classmethod)
- 每天一个Linux命令(4)——mkdir
- 每天一个Linux命令(3)——pwd
- 11-移动端开发教程-zepto.js入门教程
- 【OpenCV学习笔记之一】图像加载,修改及保存
- 【干货】一种直观的方法认识梯度下降
- 漫谈Java IO之普通IO流与BIO服务器
- 浅谈强化学习的方法及学习路线
- 【亲测有效】Win10家庭版Microsoft Edge页面出现乱码的两种解决方案及gpedit.msc命令无法使用的解决策略
- Fiddler抓包7-post请求(json)
- Selenium2+python自动化56-unittest之断言(assert)
- 长文 | 手把手教你如何使用python进行数据分析(最好将文章代码自己码一遍)
- 回归与梯度下降法及实现原理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP中$_SERVER的详细参数
- R语言使用贝叶斯层次模型进行空间数据分析
- PHP中的小数取整
- PHP中文获取拼音函数
- PHP5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
- PHP获取中文拼音首字符方法
- PHP_MySQL笔试题目一
- nginx+nginx-upsync-module实现动态负载及自定义验证
- np.diff函数
- PHP对Json字符串解码返回NULL的一般解决方案
- 记一次 Istio 云数据库连接失败的错误排查过程
- PHP对抗web扫描器的脚本技巧
- MTO Jmetal IGD计算BUG
- 《算法》读书笔记:1.1 基础编程模型
- 《剑指 offer》刷题记录之:查找和排序