ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 循环遍历文件夹及子文件夹(宏)2020-8-9(定稿)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2020-8-7 23:14 | 显示全部楼层 |阅读模式
本帖最后由 413191246se 于 2020-8-9 21:25 编辑

* 各位朋友:下面 5 个主程序分别是 cuanju 老师、gbgbxgb 老师、duquancai 老师、小花鹿 老师 和一位挪威人 Havrda 所编写的宏代码。
* 还有两个小程序,分别是我编写的单个文档示例代码《adoc》宏和我编写的《SelectFolder》函数。
* 如果想批量排版 Word 文档(*.docx/*.doc),可以在《adoc》宏里修改代码,不要修改主程序,以免出错。
* 以下 5 个宏均在 Word2019 (根下10层子文件夹) 下测试通过,正确无误!(Word2007-2019 应该都可以。)
*(不可在 Word2003 下使用,因为过去我试过,无法运行。Word2003 可以使用挪威人所写的代码,似乎可以。)
  1. Sub 循环遍历文件夹及子文件夹_DIR_cuanju()
  2.     Dim strFileFilter As String
  3.     Dim strFileName As String, strType As String
  4.     Dim StartFolder As String
  5.     Dim FolderList As Object, FileList As Object
  6.     Dim FolderName, arr1
  7.     Dim oD As Document, i&, x&, m&, n&
  8.     strFileFilter = "doc*"
  9.     Set FolderList = CreateObject("Scripting.Dictionary")
  10.     Set FileList = CreateObject("Scripting.Dictionary")
  11.     StartFolder = SelectFolder
  12.     FolderList.Add StartFolder, ""
  13.     Do While FolderList.Count > 0
  14.         For Each FolderName In FolderList.keys
  15.             strFileName = Dir(FolderName, vbDirectory)
  16.             Do While strFileName <> ""
  17.                 If strFileName <> ".." And strFileName <> "." Then
  18.                     If GetAttr(FolderName & strFileName) And vbDirectory Then
  19.                         FolderList.Add FolderName & strFileName & "", ""
  20.                         m = m + 1
  21.                     Else
  22.                         i = InStrRev(strFileName, ".")
  23.                         strType = Right(strFileName, Len(strFileName) - i)
  24.                         If strType Like strFileFilter Then
  25.                             FileList.Add FolderName & strFileName, ""
  26.                         End If
  27.                         n = n + 1
  28.                     End If
  29.                 End If
  30.                 strFileName = Dir
  31.             Loop
  32.             FolderList.Remove (FolderName)
  33.         Next
  34.     Loop
  35.     For Each arr1 In FileList.keys
  36.         Set oD = Documents.Open(arr1)
  37.         adoc
  38.         oD.Close True
  39.         x = x + 1
  40.     Next
  41.     Set FolderList = Nothing
  42.     Set FileList = Nothing
  43.     MsgBox "文件夹包含 " & n & " 个文件!" & m & " 个子文件夹!" & vbCr & "共处理 Word 文档(*.docx/*.doc) " & x & " 个!", 0 + 48
  44. End Sub
  45. Sub 循环遍历文件夹及子文件夹_DIR_gbgbxgb()

  46.     Dim d As Object, thePath$, theStr$, i&, j&, k&, doc As Document

  47.     thePath = SelectFolder

  48.     Set d = CreateObject("Scripting.Dictionary")

  49.     d(thePath) = ""

  50.     Do While i < d.Count
  51.         thePath = d.keys()(i)
  52.         theStr = Dir(thePath, vbDirectory)
  53.         Do While theStr <> ""
  54.             If theStr <> "." And theStr <> ".." Then
  55.                 If (GetAttr(thePath & theStr) And vbDirectory) = vbDirectory Then
  56.                     d(thePath & theStr & "") = ""
  57.                 Else
  58.                     j = j + 1
  59.                     If thePath & theStr Like "*.doc*" Then
  60.                         Set doc = Documents.Open(FileName:=thePath & theStr)
  61.                         adoc
  62.                         doc.Close savechanges:=wdSaveChanges
  63.                         k = k + 1
  64.                     End If
  65.                 End If
  66.             End If
  67.             theStr = Dir
  68.         Loop
  69.         i = i + 1
  70.     Loop

  71.     Set d = Nothing

  72.     MsgBox "文件夹包含 " & j & " 个文件!" & i - 1 & " 个子文件夹!" & vbCr & "共处理 Word 文档(*.docx/*.doc) " & k & " 个!", 0 + 48
  73. End Sub
  74. Sub 循环遍历文件夹及子文件夹_DIR_xiaohualu()

  75.     Dim d, n&, m&, x&, mydir, dk, doc As Document, i&
  76.     Set d = CreateObject("Scripting.Dictionary")

  77.     d(SelectFolder) = ""

  78.     Do While n < d.Count
  79.         dk = d.keys
  80.         mydir = Dir(dk(n), vbDirectory)
  81.         Do While mydir <> ""
  82.             If mydir <> "." And mydir <> ".." Then
  83.                 If GetAttr(dk(n) & mydir) = vbDirectory Then
  84.                     d(dk(n) & mydir & "") = ""
  85.                     m = m + 1
  86.                 Else
  87.                     x = x + 1
  88.                     If dk(n) & mydir Like "*.doc*" Then
  89.                         Set doc = Documents.Open(FileName:=dk(n) & mydir)
  90.                         adoc
  91.                         doc.Close savechanges:=wdSaveChanges
  92.                         i = i + 1
  93.                     End If
  94.                 End If
  95.             End If
  96.             mydir = Dir
  97.         Loop
  98.         n = n + 1
  99.     Loop

  100.     Set d = Nothing
  101.     Set dk = Nothing

  102.     MsgBox "文件夹包含 " & x & " 个文件!" & m & " 个子文件夹!" & vbCr & "共处理 Word 文档(*.docx/*.doc) " & i & " 个!", 0 + 48
  103. End Sub
  104. Sub 循环遍历文件夹及子文件夹_FSO_duquancai()

  105.     Dim pPath$, f As Object, fd As Object, fso As Object, Stack$(), top&, n&, stxt$, doc As Document, x&

  106.     pPath = SelectFolder

  107.     Set fso = CreateObject("Scripting.FileSystemObject")

  108.     top = 1
  109.     ReDim Stack(0 To top)

  110.     Do While top >= 1
  111.         For Each f In fso.getfolder(pPath).Files
  112.             n = n + 1
  113.             stxt = f.Path
  114.             If stxt Like "*.doc*" Then
  115.                 Set doc = Documents.Open(FileName:=stxt)
  116.                 adoc
  117.                 doc.Close savechanges:=wdSaveChanges
  118.                 x = x + 1
  119.             End If
  120.         Next
  121.         For Each fd In fso.getfolder(pPath).SubFolders
  122.             Stack(top) = fd.Path
  123.             top = top + 1
  124.             If top > UBound(Stack) Then ReDim Preserve Stack(0 To top)
  125.         Next
  126.         If top > 0 Then pPath = Stack(top - 1): top = top - 1
  127.     Loop

  128.     Set f = Nothing
  129.     Set fd = Nothing
  130.     Set fso = Nothing

  131.     MsgBox "文件夹包含 " & n & " 个文件!" & vbCr & "共处理 Word 文档(*.docx/*.doc) " & x & " 个!", 0 + 48
  132. End Sub
  133. Sub adoc()
  134.     With ActiveDocument.Paragraphs(1).Range
  135.         .InsertBefore Text:="Loop Folders!" & vbCr
  136.         .Bold = True
  137.         .Underline = wdUnderlineSingle
  138.         .Font.ColorIndex = wdRed
  139.         .ParagraphFormat.Alignment = wdAlignParagraphJustify
  140.     End With
  141. End Sub
  142. Function SelectFolder() As String
  143.     With Application.FileDialog(msoFileDialogFolderPicker)
  144.         If .Show Then SelectFolder = .SelectedItems(1) & "" Else End
  145.     End With
  146.     If MsgBox("是否选择文件夹 " & """" & SelectFolder & """" & " ?", 4 + 16) = vbNo Then End
  147. End Function
  148. Sub 循环遍历文件夹及子文件夹_DIR_Havrda()
  149.     Dim n&, doc As Document
  150.     Dim FileNameWithPath As Variant, ListOfFilenamesWithParh As New Collection
  151.     Call FileSearchByHavrda(ListOfFilenamesWithParh, SelectFolder, "*.doc*", True)
  152.     For Each FileNameWithPath In ListOfFilenamesWithParh
  153.         Set doc = Documents.Open(FileName:=FileNameWithPath)
  154.         adoc
  155.         doc.Close savechanges:=wdSaveChanges
  156.         n = n + 1
  157.     Next FileNameWithPath
  158.     If ListOfFilenamesWithParh.Count = 0 Then MsgBox "File not found!"
  159.     MsgBox "处理完毕!共处理 Word 文档(*.docx/*.doc) " & n & " 个!", 0 + 48
  160. End Sub
  161. Sub FileSearchByHavrda(pFoundFiles As Collection, pPath As String, pMask As String, pIncludeSubdirectories As Boolean)
  162.     Dim DirFile As String, CollectionItem As Variant, SubDirCollection As New Collection
  163.     pPath = Trim(pPath)
  164.     If Right(pPath, 1) <> "" Then pPath = pPath & ""
  165.     DirFile = Dir(pPath & pMask)
  166.     Do While DirFile <> ""
  167.         pFoundFiles.Add pPath & DirFile
  168.         DirFile = Dir
  169.     Loop
  170.     If Not pIncludeSubdirectories Then Exit Sub
  171.     DirFile = Dir(pPath & "*", vbDirectory)
  172.     Do While DirFile <> ""
  173.         If DirFile <> "." And DirFile <> ".." Then
  174.             If ((GetAttr(pPath & DirFile) And vbDirectory) = 16) Then SubDirCollection.Add pPath & DirFile
  175.         End If
  176.         DirFile = Dir
  177.     Loop
  178.     For Each CollectionItem In SubDirCollection
  179.          Call FileSearchByHavrda(pFoundFiles, CStr(CollectionItem), pMask, pIncludeSubdirectories)
  180.     Next
  181. End Sub
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-8-8 07:23 | 显示全部楼层
Sub 遍历子文件夹()
Dim d, thispath, thisname, n&, m&, x&, mydir, dk
Set d = CreateObject("scripting.dictionary")
thispath = ThisWorkbook.Path & "\"
thisname = ThisWorkbook.Name
d(thispath) = ""
Do While n < d.Count
    dk = d.keys
    mydir = Dir(dk(n), vbDirectory)
    Do While mydir <> ""
        If mydir <> "." And mydir <> ".." Then
            If GetAttr(dk(n) & mydir) = vbDirectory Then
                d(dk(n) & mydir & "\") = ""
                m = m + 1
                Cells(m, 1) = dk(n) & mydir & "\"
            Else
                x = x + 1
                Cells(x, 7) = dk(n) & mydir
            End If
        End If
        mydir = Dir
    Loop
    n = n + 1
Loop
End Sub

TA的精华主题

TA的得分主题

发表于 2020-8-8 08:43 | 显示全部楼层
小花鹿 发表于 2020-8-8 07:23
Sub 遍历子文件夹()
Dim d, thispath, thisname, n&, m&, x&, mydir, dk
Set d = CreateObject("scriptin ...

此法甚是精湛啊,学习了

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-8-8 11:06 | 显示全部楼层
本帖最后由 413191246se 于 2020-8-8 19:52 编辑

* 小花鹿 老师:辛苦了!多谢!——待我改为 for Word 格式。。。刚才测试了一下,似乎很完美!我再细细完备之。。。

TA的精华主题

TA的得分主题

发表于 2020-8-8 12:23 | 显示全部楼层
dir函数对unicode字符串支持不好

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-8-8 13:30 | 显示全部楼层
谢谢 loquat 老师!——我大略地测试了一下 duquancai 杜老师 的代码,似乎还好,都修改格式并保存了。
老师,那针对 Unicode 有什么好对策没有呢?

TA的精华主题

TA的得分主题

发表于 2020-8-8 21:17 | 显示全部楼层
FSO加递归的方法:
Sub test()
Dim fso, fld, f, br(1 To 65536, 1 To 1), n&
Set fso = CreateObject("scripting.filesystemobject")
Set fld = fso.getfolder(ThisWorkbook.Path)
For Each f In fld.Files
    n = n + 1
    br(n, 1) = f
Next f
Call digui(br, n, ThisWorkbook.Path)
[a1].Resize(n) = br
End Sub
Sub digui(br, n, p)
Dim fso, fld, f, subfld, fd
Set fso = CreateObject("scripting.filesystemobject")
Set fld = fso.getfolder(p)
Set subfld = fld.subfolders
For Each fd In subfld
    For Each f In fd.Files
        n = n + 1
        br(n, 1) = f
    Next f
    Call digui(br, n, fd)
Next fd
End Sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-8-8 23:17 | 显示全部楼层
小花鹿 老师:又辛苦您了!您的 2 楼代码我已经改写完毕,完美无缺,正确无误!7 楼代码明日测试。

TA的精华主题

TA的得分主题

发表于 2020-8-9 09:04 | 显示全部楼层
本帖最后由 cuanju 于 2020-8-9 11:25 编辑

Sub dm1()
Rem 提取文件夹的所有全文件名及文件大小
Rem 可以通过修改代码实现遍历文件夹(不遍历子文件夹)或遍历子文件夹
    Dim Fso As Object, arr$(), i&, sPath$
    Set Fso = CreateObject("Scripting.FileSystemObject")
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then sPath = .SelectedItems(1) & "\" Else Exit Sub
    End With
    Call GetFiles(sPath, Fso, arr, i)
    ActiveSheet.UsedRange.Clear
    ActiveSheet.Range("A2").Resize(i, 2) = Application.Transpose(arr)
    ActiveSheet.Cells(1, 1).Value = "文件名"
    ActiveSheet.Cells(1, 2).Value = "大小(MB)"
    ActiveSheet.Range("B:B").NumberFormatLocal = "#,##0.00_ "
    ActiveSheet.Columns("A:B").AutoFit
    ActiveSheet.Range("A1").CurrentRegion.Sort key1:=Range("B1"), Order1:=xlDescending, Header:=xlYes '排序
End Sub

Private Sub GetFiles(ByVal sPath$, ByRef Fso As Object, ByRef arr$(), ByRef i&)
    Dim Folder As Object
    Dim SubFolder As Object
    Dim File As Object
    Set Folder = Fso.GetFolder(sPath)
    For Each File In Folder.Files
        i = i + 1
        If i = 1 Then
            ReDim arr(1 To 2, 1 To 1)
        Else
            ReDim Preserve arr(1 To 2, 1 To i)
        End If
        arr(1, i) = File.Path
        arr(2, i) = File.Size / 1048576
    Next
    '如果不提取子文件夹下的文件则注释掉以下三行代码
    For Each SubFolder In Folder.SubFolders
        Call GetFiles(SubFolder.Path, Fso, arr, i)
    Next
   
    Set Folder = Nothing
    Set File = Nothing
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-8-9 10:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 413191246se 于 2020-8-9 21:30 编辑

cuanju 老师 辛苦了!代码已保存,容后测试。----最终函数 SelectFolder 参考了 cuanju 老师 的代码,精简到 4 行!多谢!
但 cuanju 老师 和 小花鹿 老师 所写的 Excel 代码,有的未改成 Word 的,也有改的。
总之,我一看 Excel VBA 就吓够呛,不要来 Excel 的,我只来 Word 的。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-26 02:55 , Processed in 0.037311 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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