【问题标题】:Use Dir to return files from a folder in file system order使用 Dir 按文件系统顺序从文件夹返回文件
【发布时间】:2011-12-31 22:03:06
【问题描述】:

PixPath 是 jpg 文件夹的完整路径,我使用如下代码来处理每个 jpg。

fileName = Dir(PixPath)
Do Until fileName = ""
   If Right$(fileName, 4) = ".jpg" Then   
      fileName = Dir()

      <process this jpg>

   End If
Loop

这工作正常,除了文件按字母数字顺序返回,而不是文件在文件夹中列出的显示顺序。有没有办法解决这个问题?

【问题讨论】:

  • 您的文件如何在文件夹中列出(按修改日期等)?
  • 文件名全部由数字组成,例如“1”,“2”等,因此文件将是“1.jpg”等,并且每个文件夹中的数字可以无限制地上升。这些文件在 Windows 资源管理器中排序为“1.jpg”、“2.jpg”、“3.jpg”等,这是所需的顺序,但 Dir 返回“1.jpg”、“10.jpg”等。跨度>
  • 我过去曾通过使用前导零命名文件来解决此问题。

标签: vba


【解决方案1】:

Dir 不能这样做。

另一种方法是:

  • 使用FileSystemObject 访问您目录中的所有文件
  • 将所有.jpg文件读入数组X
  • 使用Val按值比较.jpgs,以按数字升序排序
  • 最后的数组X包含排序后的文件

    Sub Test()
    Dim objFSO As Object
    Dim objFolder As Object
    Dim objFiles As Object
    Dim objFile As Object
    Dim X
    Dim lngFileCnt As Long
    Dim lngCnt As Long
    Dim i As Long
    Dim j As Long
    Dim strBuffer1 As String
    Dim strFolder As String
    
    Set objFSO = CreateObject("Scripting.fileSystemObject")
    strFolder = "C:\temp"
    Set objFolder = objFSO.getFolder(strFolder)
    Set objFiles = objFolder.Files
    lngFileCnt = objFiles.Count
    ReDim X(1 To lngFileCnt)
    
    'grab all jpg files        
    For Each objFile In objFiles
        If Right$(objFile.Name, 3) = "jpg" Then
            lngCnt = lngCnt + 1
            X(lngCnt) = objFile.Name
        End If
    Next
    
    'resize array to number of jpg files
    ReDim Preserve X(1 To lngCnt)
    
    'sort array by numeric value
    For i = 1 To lngCnt
        For j = (i + 1) To lngCnt
            If Val(X(i)) > Val(X(j)) Then
                strBuffer1 = X(j)
                X(j) = X(i)
                X(i) = strBuffer1
            End If
        Next
    Next
    MsgBox Join(X, ";")
    End Sub
    

    有关使用FileSystemObject 的更多信息,请参阅here

【讨论】:

    【解决方案2】:

    brettdj (thank-you brettdj) 的答案效果很好,可能是我将使用的方法,但我发现了其他方法也有效,并且可能在其他情况下提供优势。一方面,它保留了使用 Dir 遍历文件夹的极端简单性。

    在 Excel 11 中,我使用 Dir(如问题中所述)从每个文件夹(一次一个文件夹)创建 jpg 文件列表,在 Col A 中按字母数字排序。然后我使用自定义列表使用(假)数字排序对 Col A 进行排序,以便我可以按顺序处理我的 jpg。然后清除 Col A,并重复下一个文件夹。

    生成自定义列表:

    在工作列的第 1 行输入

     =ROW() & ".jpg"
    

    然后填充到任何适合的位置。就我而言,我在自定义列表中使用了 1000 个项目,因为这是我期望在任何文件夹中的最大 jpg 数量。

    自定义列表仅采用文本(或根据 MS 帮助的“简单文本”),因此在导入为自定义列表之前,必须使用粘贴>特殊>值将新生成的公式列表转换为文本。列表中的每一项都是预期的文件名之一。最终的自定义列表如下所示:

     1.jpg
     2.jpg
     3.jpg
     …
     …
     1000.jpg
    

    在我导入新的自定义列表(工具>选项>自定义列表>导入)后,它成为数据>排序>选项>第一个键排序顺序下拉菜单中的可用选择。

    如果您使用 VBA 进行这种排序,那么 Recorder 提供的内容如下:

    Range("A:A").Select
    Selection.Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=6, MatchCase:=False, Orientation:=xlTopToBottom, _
        DataOption1:=xlSortNormal
    

    前 5 个自定义列表内置在 Excel 中,因此 OrderCustom:=6 是新的自定义列表。请记住在进行正常排序时将其更改回 OrderCustom:=False。自定义列表会一直附加到创建它们的 Wkb,直到被删除。

    【讨论】:

    • 感谢您不厌其烦地发布如此全面的后续路径。虽然我曾短暂考虑过使用 Excel 在 VBA 中进行排序,但 Excel 排序也可以使用 needs tweaking。看起来您的自定义列表提供了一个不错的解决方案(+1 顺便说一句)。
    • 小修正。按照我上面的回答中的建议设置 OrderCustom:=False 会产生错误。应该是 OrderCustom:=1
    猜你喜欢
    • 2019-11-10
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多