2

first-time poster but long-time fan for finding VBA and SQL solutions on this site. I have a VBA subroutine that is designed to find all PDF files within a directory that the user designates. The program does recursions through all subfolders and generates a spreadsheet as follows:

Column A: complete file path ("C:\Users\Records\NumberOne.pdf")

Column B: folder path containing the file ("C:\Users\Records\")

Column C: the file name itself ("NumberOne.pdf")

Up to this point, the program (code below) works flawlessly. I've used it to search a directory with over 50,000 PDF files, and it successfully generates the spreadsheet every time (total elapsed time for the program is usually 5-10 minutes in large directories).

The problem is that I want to add Column D to capture the date that the PDF file was created. I have Googled this and labored over it for hours, trying techniques like FSO.DateCreated and so forth, and nothing has worked. If FSO.DateCreated is what I need, I'm not sure where to insert it in my subroutine to make it work. Usually I get an error that the object does not support that property or method. Does anybody happen to know where I can insert the proper code for my program to find the date each PDF was created and drop it into Column D on my output spreadsheet?

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
yms
  • 10,361
  • 3
  • 38
  • 68
Angler
  • 78
  • 1
  • 6
  • Maybe you can have a second array for the dates? You could pass the array to recurseSubFolders and get the dates there, then assign the array to another column as you did with the full path. – yms Sep 06 '13 at 15:37
  • Excellent suggestion, I'll tinker with that and see if I can get it to work. – Angler Sep 06 '13 at 15:50

3 Answers3

3

You need to get the file with GetFile before you can access the DateCreated.

Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(myFileName)
str = f.DateCreated
MsgBox (str)
Stewbob
  • 16,759
  • 9
  • 63
  • 107
2

Your code is fine (beside some issues with indentation). I just added the instruction to get the creation date from the file system, as you can see below:

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

I don't know why you weren't able to use the FSO object, but I believe it can be because few lines below you set it to nothing, so I instantiated it again before the first For cycle:

Set FSO = CreateObject("Scripting.FileSystemObject")

Hope this helps, The Macro Guru

TheMacroGuru
  • 134
  • 2
  • Outstanding! I tested it on a small batch (4 files) and it worked perfectly. Currently running it against one of our medical record directories to pick up the file attributes on 1,000+ PDFs. UPDATE: Works like a charm. I picked up every Date Created for 3,760 PDF files within a directory. Elapsed time for the program: about one minute. – Angler Sep 06 '13 at 16:09
  • And yeah, sometimes I play fast and loose with my indentation... :) – Angler Sep 06 '13 at 16:09
  • 1
    @TheMacroGuru good answer. Also, @Angler you could try setting `Application.ScreenUpdating = False` for increased speed. – Aaron Thomas Sep 06 '13 at 16:12
1

FileSystem.FileDateTime(inputfilepath) returns a variant or date of when the file was last created or modified.

Aaron Thomas
  • 5,054
  • 8
  • 43
  • 89