ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 香川群子

[分享] 跟我学 【喜迎2015立春】遍历文件夹(含子文件夹)方法 ABC

    [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-2-5 09:36 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:文件操作和FSO
感谢分享。

TA的精华主题

TA的得分主题

发表于 2015-2-5 09:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
学习,谢谢分享!

TA的精华主题

TA的得分主题

发表于 2015-2-5 09:57 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-2-5 10:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
补一下课:【Dir 使用方法】

myPath = "c:\"    '首先设定目标文件夹,注意末尾必须是【\】文件夹符号。

myFile = Dir(myPath, vbDirectory)    '第一次使用Dir函数时,必须完整输入路径和检索要求。
                                                  ' 如果直接使用Dir不带参数则会报错。

Do While myFile <> ""    '开始Do不定循环、直至在本文件夹内没有找到文档/文件夹而返回空白时停止。

    If myFile <> "." And myFile <> ".." Then
        '此If判断为忽略 当前文件夹"."以及忽略上级文件夹".."
   
        If (GetAttr(MyPath & MyName) And vbDirectory) = vbDirectory Then
             '接下来的If判断是:通过二进制的位比较计算结果= vbDirectory 来判断这是一个文件夹。
            Debug.Print myFile         '判断为文件夹时的处理
        Else '否则为文档
            Debug.Print myFile        '判断为文档时的处理。
        End If
    End If
    myFile = Dir     '继续调用【不带路径参数的Dir函数】 这样就能得到下一个搜寻结果。
Loop

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-2-5 10:32 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-2-5 14:33 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-2-5 14:35 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
支持楼主!谢谢分享!

TA的精华主题

TA的得分主题

发表于 2015-2-5 15:15 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
好资料谢谢分享,跟你学VBA

TA的精华主题

TA的得分主题

发表于 2015-2-5 19:32 | 显示全部楼层
补一个方法

如何列出文件夹及其所有子文件夹中的文件?
问:
您好,脚本专家!如何列出某个文件夹中的所有文件以及该文件夹的所有子文件夹中的所有文件?
-- MA
答:
您好,MA。有很多用户提出过这个问题,我们还没来得及作出解答。这是因为,这个问题还没有一个既有效又简便的解决办法:能够完成这一任务的脚本注定会有些不易理解,也无法通过本专栏惯用的简洁明了的方式进行解决。从另一方面来说,客户永远是正确的:如果您们需要一个能够列出某个文件夹中的所有文件以及该文件夹的所有子文件夹中的所有文件的脚本,我们还有什么可说的呢?
着手编写脚本前,必须先解决两个问题。第一,需要选择一种脚本技术。WMI、FileSystemObject 及 Shell 对象都能列出文件夹中的文件以及文件夹中的子文件夹。不过,这些技术都没有能够自动列出这些子文件夹中文件的机制(更不必说可能存在的再下一级文件夹了)。使用上述任何一种技术都可以达到目的,但都不是非常容易。
我们倾向于使用 WMI。使用它编写的脚本可能比使用 FileSystemObject 或 Shell 对象编写的类似脚本复杂一些,但 WMI 脚本的优点是,在本地计算机上检索此类信息与从远程计算机中检索同样方便。而 FileSystemObject 或 Shell 对象都做不到这一点。我们看重的是 WMI 的灵活性。
第二,我们注意到,所有这些脚本技术都没有完成以下操作的内置方法:循环访问文件夹,列出文件名,然后自动循环访问所有子文件夹并列出其中的文件。因此,需要使用"递归函数"来执行这项任务。对递归进行说明超出了本专栏的讨论范围;有关简要说明,请参阅 Microsoft Windows 2000 脚本编写指南。只需说我们要创建一个可以根据需要多次调用自身的函数就够了。换句话说,如果我们有可以访问某个文件夹并列出其中所有文件的函数,则该函数可以调用自身来访问子文件夹并列出其中的所有文件,然后再次调用自身来访问再下一级文件夹。很难以直观的方式来说明这一点,但这种方法的确奏效。
它还会产生一个新问题,我们稍后再进行讨论。我们先来看一个脚本,它的作用是列出某个文件夹及其所有子文件夹(但这第一个示例脚本并未列出这些文件夹中的任何文件):
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
strFolderName = "c:\scripts"
Set colSubfolders = objWMIService.ExecQuery _
("Associators of {Win32_Directory.Name='" & strFolderName & "'} " _
& "Where AssocClass = Win32_Subdirectory " _
& "ResultRole = PartComponent")
For Each objFolder in colSubfolders
    GetSubFolders strFolderName
Next
Sub GetSubFolders(strFolderName)
    Set colSubfolders2 = objWMIService.ExecQuery _
("Associators of {Win32_Directory.Name='" & strFolderName & "'} " _
& "Where AssocClass = Win32_Subdirectory " _
& "ResultRole = PartComponent")
    For Each objFolder2 in colSubfolders2
        strFolderName = objFolder2.Name
        Wscript.Echo objFolder2.Name
        GetSubFolders strFolderName
    Next
End Sub
'---------------------------------------------------------------------------
以上脚本的作用是使用"AssociatorsOf"查询来获取文件夹 C:\Scripts 的所有子文件夹的列表。我们的查询所要表达的基本意思是:给我提供与目录 C:\Scripts 相关的所有项目的列表,但前提是这些项目是子目录("Where AssocClass = Win32_Subdirectory")。
此脚本获取的是所有顶级子文件夹的列表:例如,C:\Scripts\Folder1 和 C:\Scripts\Folder2。它不能获取任何下一级文件夹;此查询无法返回像 C:\Scripts\Folder1\SubfolderA 之类的文件夹。要获取这些下一级子文件夹(子文件夹的子文件夹),我们需要使用递归查询。子例程"GetSubFolders"可以实现这个目的。我们将找到的每个子文件夹的名称(如 C:\Scripts\Folder1 和 C:\Scripts\Folder2)逐一传递给该子例程,使之查询这些子文件夹中是否有下一级子文件夹。如果有任何下一级子文件夹,该函数将自动调用自身并查找是否有再下一级子文件夹。
感到困惑不解吗?不必沮丧;很多人都会有这种感觉。但不要担心,只需让代码保持原样并运行即可。要搜索其他文件夹(即 C:\Scripts 以外的文件夹),只需更改包含要搜索的文件夹的变量值即可。例如,如果要搜索 C:\Windows,请使用以下这行代码:
strFolderName = "c:\windows"
那么,如何列出所有这些文件夹中的文件?从现在开始,情况确实变得更复杂了。这是因为,我们需要再执行一个查询:我们使用一个查询来获取所有子文件夹的名称,然后使用另一个查询获取每个文件夹中的文件集合。这第二个查询恰好与以下内容非常相似:
Set colFiles = objWMIService.ExecQuery _
("Select * from CIM_DataFile where Path = '" & strPath & "'")
这还不算太复杂,但以下情况就不同了:在此类查询中,必须"转义"在文件路径中出现的 \(使用两个 \\)。不能在查询中使用"C:\Scripts\Folder1\";而必须使用"C:\\Scripts\\Folder1\\"。您会发现,脚本中的代码将每个 \ 都替换为 \\;在此类查询中引用文件路径时,这正是我们需要做的。脚本中相当大一部分内容专用于转换文件夹路径名,以使它们可以在查询中使用。
注意事项就讲这么多。以下便是每位用户都想一睹为快的脚本:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
strFolderName = "c:\scripts"
Set colSubfolders = objWMIService.ExecQuery _
("Associators of {Win32_Directory.Name='" & strFolderName & "'} " _
& "Where AssocClass = Win32_Subdirectory " _
& "ResultRole = PartComponent")
Wscript.Echo strFolderName
arrFolderPath = Split(strFolderName, "\")
strNewPath = ""
For i = 1 to Ubound(arrFolderPath)
    strNewPath = strNewPath & "\\" & arrFolderPath(i)
Next
strPath = strNewPath & "\\"
Set colFiles = objWMIService.ExecQuery _
("Select * from CIM_DataFile where Path = '" & strPath & "'")
For Each objFile in colFiles
    Wscript.Echo objFile.Name
Next
For Each objFolder in colSubfolders
    GetSubFolders strFolderName
Next
Sub GetSubFolders(strFolderName)
    Set colSubfolders2 = objWMIService.ExecQuery _
("Associators of {Win32_Directory.Name='" & strFolderName & "'} " _
& "Where AssocClass = Win32_Subdirectory " _
& "ResultRole = PartComponent")
    For Each objFolder2 in colSubfolders2
        strFolderName = objFolder2.Name
        Wscript.Echo
        Wscript.Echo objFolder2.Name
        arrFolderPath = Split(strFolderName, "\")
        strNewPath = ""
        For i = 1 to Ubound(arrFolderPath)
            strNewPath = strNewPath & "\\" & arrFolderPath(i)
        Next
        strPath = strNewPath & "\\"
        Set colFiles = objWMIService.ExecQuery _
("Select * from CIM_DataFile where Path = '" & strPath & "'")
        For Each objFile in colFiles
            Wscript.Echo objFile.Name
        Next
        GetSubFolders strFolderName
    Next
End Sub
'---------------------------------------------------------------------------
我们曾说过脚本比较复杂。不过还真管用!此脚本所执行的操作如下:绑定到 C:\Scripts 文件夹并回显其中的所有文件的名称,然后获取 C:\Scripts 中所有子文件夹的列表。接着循环访问子文件夹集合,并为每个子文件夹调用递归函数 GetSubFolders。该函数将列出子文件夹中的所有文件,然后检查该子文件夹是否有下一级子文件夹。如果有,将再次调用递归函数;继续重复执行这一过程,直至无法再继续为止,即列出了 C:\Scripts 及其所有子文件夹中的所有文件。
明天,可真该回头探讨一个容易解决的问题了。有哪位想知道如何使用脚本来获取本地计算机的名称吗?
--------------------------------------------------------------------------------

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-2-5 20:55 | 显示全部楼层
不愧是精华帖,博大精深啊,深入研究中!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-15 02:04 , Processed in 0.039422 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表