前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VBA使用API_02:遍历文件

VBA使用API_02:遍历文件

作者头像
xyj
发布2020-07-28 10:52:39
1.1K0
发布2020-07-28 10:52:39
举报
文章被收录于专栏:VBA 学习VBA 学习

1、遍历文件

我们在VBA中遍历获取所有文件的方法一般是使用下面3种:

  • 调用Dir函数
  • 使用FileSystemObject
  • 使用cmd命令

Dir方法是VBA里封装好了的,但是对于判段是否是文件夹并没有很好的方法,一般是利用文件名是否包含“.”来判断,但这个是很不严谨的。

不过这个方法其实和Windows API的使用方法很相近,只是他的返回值太单一了一点:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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里面记录了较多信息,理解这个也能让我们明白底层的一些原理。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档