views:

530

answers:

0

Hi guys,

I've got a problem with my VBA (you guessed it).

I took code from this post: vbaexpress.com/kb/getarticle.php?kb_id=405 and added in: wilmott.com/messageview.cfm?catid=10&threadid=40372

Basically, first code would output to a worksheet, but as I theoretically could breach the 65k rows limit, I'd like to output to a csv instead (i.e. write every line found out to an external text file). I don't really need the time limit functionality, i didn't get around to deleting that yet.

I'm running Excel 2003 SP2 on Windows XP Pro SP3. So the code that i have modified (combined version of the two above):

Code:

Public X() Public i As Long Public objShell, objFolder, objFolderItem Public FSO, oFolder, Fil

Sub MainExtractData() 

    Dim NewSht As Worksheet 
    Dim MainFolderName As String 
    Dim TimeLimit As Long, StartTime As Double 

    Const ForReading = 1, ForWriting = 2, ForAppending = 8 
    Dim FSO, f, g 

    ReDim X(1 To 65536, 1 To 11) 

    Set objShell = CreateObject("Shell.Application") 
    TimeLimit = 0 
    StartTime = Timer 

    Application.ScreenUpdating = False 
    MainFolderName = "c:\temp" 'list files in this folder
     ' Set NewSht = ThisWorkbook.Sheets.Add

     ' File attribs are as follows:
     ' X(1, 1) = "Path"
     ' X(1, 2) = "File Name"
     ' X(1, 3) = "Last Accessed"
     ' X(1, 4) = "Last Modified"
     ' X(1, 5) = "Created"
     ' X(1, 6) = "Type"
     ' X(1, 7) = "Size"
     ' X(1, 8) = "Owner"
     'X(1, 9) = "Author"
     'X(1, 10) = "Title"
     'X(1, 11) = "Comments"

    i = 1 

    Set FSO = CreateObject("scripting.FileSystemObject") 
    Set oFolder = FSO.GetFolder(MainFolderName) 
     'error handling to stop the obscure error that occurs at time when retrieving DateLastAccessed
    On Error Resume Next 

    Set f = FSO.OpenTextFile("c:\temp\ls_output.csv", ForWriting, True) 

    For Each Fil In oFolder.Files 
        Set objFolder = objShell.Namespace(oFolder.path) 
        Set objFolderItem = objFolder.ParseName(Fil.Name) 
        i = i + 1 
        If i Mod 20 = 0 And TimeLimit <> 0 And Timer > (TimeLimit * 60 + StartTime) Then 
            Goto FastExit 
        End If 
        If i Mod 50 = 0 Then 
            Application.StatusBar = "Processing File " & i 
            DoEvents 
        End If 


        d_path = oFolder.path 
        d_filename = Fil.Name 
        d_dateaccess = Fil.DateLastAccessed 
        d_lastmod = Fil.DateLastModified 
        d_datecreate = Fil.DateCreated 
        d_type = Fil.Type 
        d_size = Fil.Size 
        d_owner = objFolder.GetDetailsOf(objFolderItem, 8) 
        d_all = d_path & "," & d_filename & "," & d_dateaccess & "," & d_lastmod & "," & d_datecreate & "," & d_type & "," & d_size & "," & d_owner 
        f.Writeline d_all 'write ob

    Next 

     'Get subdirectories
    If TimeLimit = 0 Then 
        Call RecursiveFolder(oFolder, 0) 
    Else 
        If Timer < (TimeLimit * 60 + StartTime) Then Call RecursiveFolder(oFolder, TimeLimit * 60 + StartTime) 
        f.Write d_all 'write ob
    End If 
FastExit: 
     ' Range("A:K") = X
     ' If i < 65535 Then Range(Cells(i + 1, "A"), Cells(65536, "A")).EntireRow.Delete
     ' Range("A:K").WrapText = False
     ' Range("A:K").EntireColumn.AutoFit
     ' Range("1:1").Font.Bold = True
     ' Rows("2:2").Select
     ' ActiveWindow.FreezePanes = True
     ' Range("a1").Activate

    Set FSO = Nothing 
    Set objShell = Nothing 
    Set oFolder = Nothing 
    Set objFolder = Nothing 
    Set objFolderItem = Nothing 
    Set Fil = Nothing 
    Application.StatusBar = "" 
    Application.ScreenUpdating = True 
    f.Close 
End Sub 

Sub RecursiveFolder(xFolder, TimeTest As Long) 
    Dim SubFld 

    For Each SubFld In xFolder.SubFolders 
        Set oFolder = FSO.GetFolder(SubFld) 
        Set objFolder = objShell.Namespace(SubFld.path) 
        For Each Fil In SubFld.Files 
            Set objFolder = objShell.Namespace(oFolder.path) 
             'Problem with objFolder at times
            If Not objFolder Is Nothing Then 
                Set objFolderItem = objFolder.ParseName(Fil.Name) 
                i = i + 1 
                If i Mod 20 = 0 And TimeTest <> 0 And Timer > TimeTest Then 
                    Exit Sub 
                End If 
                If i Mod 50 = 0 Then 
                    Application.StatusBar = "Processing File " & i 
                    DoEvents 
                End If 
                d_path = oFolder.path 
                d_filename = Fil.Name 
                d_dateaccess = Fil.DateLastAccessed 
                d_lastmod = Fil.DateLastModified 
                d_datecreate = Fil.DateCreated 
                d_type = Fil.Type 
                d_size = Fil.Size 
                d_owner = objFolder.GetDetailsOf(objFolderItem, 8) 

                d_all = d_path & "," & d_filename & "," & d_dateaccess & "," & d_lastmod & "," & d_datecreate & "," & d_type & "," & d_size & "," & d_owner & "," 
                f.Writeline d_all 'write ob
            Else 
                Debug.Print Fil.path & " " & Fil.Name 
            End If 

        Next 
        Call RecursiveFolder(SubFld, TimeTest) 
    Next 
End Sub

What i'm actually after is - files in the current directory (c:\temp) to be listed recursively (i.e. i also want files from subfolders), with their attributes (date modified, file owner etc) - output into a comma separated file (to be used elsewhere).

What this code actually does is list the files (and attribs) in the current folder, and closes the file. After inserting some breaks it seems that it jumps from this line

Code: Set oFolder = FSO.GetFolder(SubFld)(RecursiveFolder sub) back to a previous sub where the call to recursivefolder came from. This is weird as it does not happen in the original piece of code. Feel there's a schoolboy error in there somewhere!

Any help is greatly appreciated.

Cheers Dan