【问题标题】:Excel VBA - PDF file propertiesExcel VBA - PDF 文件属性
【发布时间】:2013-09-06 15:01:03
【问题描述】:

第一次发帖,但长期以来一直是在此站点上查找 VBA 和 SQL 解决方案的粉丝。我有一个 VBA 子例程,旨在查找用户指定的目录中的所有 PDF 文件。该程序对所有子文件夹进行递归并生成如下电子表格:

A列:完整的文件路径(“C:\Users\Records\NumberOne.pdf”)

B 列:包含文件的文件夹路径(“C:\Users\Records\”)

C 列:文件名本身(“NumberOne.pdf”)

到目前为止,程序(下面的代码)运行良好。我用它搜索了一个包含超过 50,000 个 PDF 文件的目录,并且每次都能成功生成电子表格(在大目录中,程序的总运行时间通常为 5-10 分钟)。

问题是我想添加 D 列来捕获 PDF 文件的创建日期。我已经用谷歌搜索了这个并为它工作了几个小时,尝试了 FSO.DateCreated 等技术,但没有任何效果。如果 FSO.DateCreated 是我需要的,我不确定将它插入我的子例程中的哪个位置以使其工作。通常我会收到一个错误,即对象不支持该属性或方法。是否有人碰巧知道我可以在哪里为我的程序插入正确的代码以查找每个 PDF 的创建日期并将其放入输出电子表格的 D 列?

Sub GetFiles()
'-- RUNS AN UNLIMITED RECURSION SEARCH THROUGH A TARGETED FOLDER AND FINDS ALL PDF FILES WITHIN

        Application.ScreenUpdating = False
        Application.DisplayAlerts = False

        Dim j As Long
        Dim ThisEntry As String
        Dim strDir As String
        Dim FSO As Object
        Dim strFolder As String
        Dim strName As String
        Dim DateCreated As Date '--(Possibly String?)
        Dim strArr(1 To 1048576, 1 To 1) As String, i As Long
        Dim fldr As FileDialog

        '-- OPEN DIALOG BOX TO SELECT DIRECTORY THE USER WISHES TO SEARCH
        Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
        With fldr
            .Title = "Select the directory you wish to search"
            .AllowMultiSelect = False
            If .Show <> -1 Then
                Exit Sub
                Set fldr = Nothing
            Else
                strDir = .SelectedItems(1) & "\"
            End If
        End With

        '-- LOOK FOR RECORDS WORKSHEET; IF IT DOES NOT EXIST, CREATE IT; IF IT DOES EXIST, CLEAR CONTENTS
        If Not (wsExists("records")) Then
                Worksheets.Add
            With ActiveSheet
                .Name = "records"
            End With
            Set ws = ActiveSheet
        Else
            Sheets("records").Activate
            Range("A1:IV1").EntireColumn.Delete
            Set ws = ActiveSheet
        End If

        '-- SET SEARCH PARAMETERS
        Let strName = Dir$(strDir & "\" & "*.pdf")
        Do While strName <> vbNullString
            Let i = i + 1
            Let strArr(i, 1) = strDir & strName
            Let strName = Dir$()
        Loop

        '-- UNLIMITED RECURSIONS THROUGH SUBFOLDERS
        Set FSO = CreateObject("Scripting.FileSystemObject")
        Call recurseSubFolders(FSO.GetFolder(strDir), strArr(), i)
        Set FSO = Nothing

        '-- CREATE COLUMN HEADERS ON OUTPUT WORKSHEET
        With ws
            Range("A1").Value = "AbsolutePath"
            Range("B1").Value = "FolderPath"
            Range("C1").Value = "FileName"
            Range("D1").Value = "DateCreated"
        End With

        If i > 0 Then
            ws.Range("A2").Resize(i).Value = strArr
        End If

        lr = Cells(Rows.Count, 1).End(xlUp).Row

        For i = 1 To lr
        ThisEntry = Cells(i, 1)

        '-- EXTRACT FOLDER PATH AND FILE NAME FROM STRING
        For j = Len(ThisEntry) To 1 Step -1
            If Mid(ThisEntry, j, 1) = Application.PathSeparator Then
            Cells(i, 2) = Left(ThisEntry, j)
            Cells(i, 3) = Mid(ThisEntry, j + 1)
        Exit For

        End If
        Next j
        Next i

        Application.ScreenUpdating = True
        Application.DisplayAlerts = True

End Sub

----------

Private Sub recurseSubFolders(ByRef Folder As Object, _
ByRef strArr() As String, _
ByRef i As Long)
Dim SubFolder As Object
Dim strName As String

        For Each SubFolder In Folder.SubFolders
        Let strName = Dir$(SubFolder.Path & "\" & "*.pdf")
        Do While strName <> vbNullString
        Let i = i + 1
        Let strArr(i, 1) = SubFolder.Path & "\" & strName
        Let strName = Dir$()
        Loop
        Call recurseSubFolders(SubFolder, strArr(), i)
        Next

End Sub

【问题讨论】:

  • 也许你可以有第二个日期数组?您可以将数组传递给 recurseSubFolders 并在那里获取日期,然后像使用完整路径一样将数组分配给另一列。
  • 很好的建议,我会修改一下,看看能不能让它发挥作用。

标签: vba excel fso


【解决方案1】:

您需要先获取带有GetFile 的文件,然后才能访问DateCreated

Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(myFileName)
str = f.DateCreated
MsgBox (str)

【讨论】:

    【解决方案2】:

    您的代码很好(除了一些缩进问题)。我刚刚添加了从文件系统获取创建日期的指令,如下所示:

    Set FSO = CreateObject("Scripting.FileSystemObject")
    For i = 1 To lr
        ThisEntry = Cells(i, 1)
    
    '-- EXTRACT FOLDER PATH AND FILE NAME FROM STRING
        For j = Len(ThisEntry) To 1 Step -1
            If Mid(ThisEntry, j, 1) = Application.PathSeparator Then
                Cells(i, 2) = Left(ThisEntry, j)
                Cells(i, 3) = Mid(ThisEntry, j + 1)
                Cells(i, 4) = FSO.GetFile(ThisEntry).DateCreated
                Exit For
    
            End If
        Next j
    Next i
    

    我不知道你为什么不能使用 FSO 对象,但我相信这可能是因为下面几行你将它设置为空,所以我在第一个 For 循环之前再次实例化它:

    设置 FSO = CreateObject("Scripting.FileSystemObject")

    希望这会有所帮助, 宏观大师

    【讨论】:

    • 优秀!我在小批量(4 个文件)上对其进行了测试,并且效果很好。目前针对我们的一个病历目录运行它,以获取 1,000 多个 PDF 上的文件属性。更新:像魅力一样工作。我为一个目录中的 3,760 个 PDF 文件提取了每个创建日期。节目经过的时间:大约一分钟。
    • 是的,有时我的缩进玩得又快又松... :)
    • @TheMacroGuru 很好的答案。另外,@Angler 你可以尝试设置Application.ScreenUpdating = False 以提高速度。
    【解决方案3】:

    FileSystem.FileDateTime(inputfilepath) 返回最后一次创建或修改文件的变体或日期。

    【讨论】:

      猜你喜欢
      • 2016-06-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多