Consulting

Page 1 of 2 1 2 LastLast
Results 1 to 20 of 33

Thread: Selective listing of files in a folder

  1. #1

    Selective listing of files in a folder

    The following macro selects a folder and lists all files in that folder. It works as intended.
    For each document there are several revisions, and I want to only list the last revision (see below). Some files have alpha revisions, some have numeric revisions.
    This has been posted in another forum but no response so far.

    WHAT IS HAPPENING
    FileOne [A]
    FileOne [B]
    FileOne [C]
    FileTwo [0]
    FileTwo [1]
    FileTwo [2]

    WHAT I WANT
    FileOne [C]
    FileTwo [2]

    Sub File_Attributes()
        Dim sFolder As FileDialog
    
        Set sFolder = Application.FileDialog(msoFileDialogFolderPicker)
    
        If sFolder.Show = -1 Then
        File_Attributes_List_Files sFolder.SelectedItems(1), True
        End If
    End Sub
    
    Sub File_Attributes_List_Files(ByVal SourceFolderName As String, ByVal IncludeSubfolders As Boolean)
        Dim FSO As Object
        Dim SourceFolder As Object
        Dim SubFolder As Object
        Dim FileItem As Object
        Dim r As Long
    
        Set FSO = CreateObject("Scripting.FileSystemObject")
        Set SourceFolder = FSO.GetFolder(SourceFolderName)
    
        r = ActiveCell.Row
        For Each FileItem In SourceFolder.Files
        Rows(r).Insert
        Cells(r, 3).Formula = Chr(61) & "HYPERLINK(" & Chr(34) & FileItem.Path & Chr(34) & "," & Chr(34) & FileItem.Name & Chr(34) & ")"
        r = r + 1
        x = SourceFolder.Path
        Next FileItem
    
        If IncludeSubfolders Then
        For Each SubFolder In SourceFolder.SubFolders
        File_Attributes_List_Files SubFolder.Path, True
        Next SubFolder
        End If
    
        Set FileItem = Nothing
        Set SourceFolder = Nothing
        Set FSO = Nothing
        ActiveWorkbook.Saved = True
    End Sub
    Last edited by SamT; 05-11-2016 at 05:54 AM. Reason: Added white space to code

  2. #2
    Moderator VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    My main computer is down and all I have is this old laptop, but. . .

    Only a suggestion for your consideration.Soory I can do no better ATT.

    After
        Set SourceFolder = FSO.GetFolder(SourceFolderName)
    add
    Dim AllFiles(1 to SourceFolder.Count)
    For i = 1 to SourceFolder.Count
    AllFiles(i) = SourceFolder.Items(i)
    Next
    then sort the array allFiles.

    Then loop thru the sorted array looking for the last of each similar file name
    Dim BPos as Long
    For i = 1 to UBound(AllFiles)
    Fname = AllFiles(i)
    BPos = InStr(Fname, "[") - 1
    Fname = Left(Fname, BPos)
    
    Do While InStr(AllFiles(i + 1), FName)
    i = i + 1
    Loop
    
           Rows(r).Insert 
            Cells(r, 3).Formula = Chr(61) & "HYPERLINK(" & Chr(34) & SourceFolder.Items(i).Path & Chr(34) & "," & Chr(34) & SourceFolder.Items(i).Name & Chr(34) & ")" 
    
    'Etc etc Etc
    Loop
    Incorporating subfolders is a different subject.
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

  3. #3
    I get an error message: "Compile error: Constant expression required".
    .Count is highlighted in the line: "Dim AllFiles(1 To SourceFolder.Count)".

  4. #4
    Moderator VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    Sorry, all my reference files on the broken computer.

    Not to worry, somebody else will be along shortly.
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

  5. #5
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    I guess you are wanting the last version based on filename and not last revision to the file? Windows has a file attribute with created and modified dates.

    If you want the former, then I would probably reverse (descending) sort the filenames and use Split(), Join() and Ubound(). For the sorting routine, if all files would have the same file extension, coding would be a bit less. e.g. No XLSX, XLSM, and XLS files with the same basename.

    This is why most use a common file naming convention to avoid those issues. I wrote a kb article with code to show how to save files using Windows unique filenaming convention. http://www.vbaexpress.com/kb/getarticle.php?kb_id=1041

    As a start, rather than using FSO, I would just get the file list and reverse sort as I explained in #17 of http://www.vbaexpress.com/forum/showthread.php?54971
    From there, you can check if the first one is the last version named one. My test in that thread shows how to quick view the array.

  6. #6
    Kenneth, the code in thread above (#17) lists all the files. How can I make it list only one version as per original question. Am I missing something?<br>

  7. #7
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    I solve problems one step at a time. The first step that I would do is to get all the filenames into an array in descending order. Try doing that and see if that works first.

    One then needs to consider the next steps. In your example, you show two words in the base filename with the 2nd having []'s around them. Knowing that, we can then create a loop to create another array with the filenames needed. Of course if one word base filename exists, then that is another consideration.

  8. #8
    Knowledge Base Approver VBAX Wizard
    Joined
    Apr 2012
    Posts
    5,646
    to retrieve the last version of file 'example.xlsx' in directory 'G:\OF'

    Sub M_snb()
      msgbox split(createobject("wscript.shell").exec("cmd /c dir ""G:\OF\example*.xlsx"" /b/s/o-d").stdout.readall,vbcrlf)(0)
    End Sub

  9. #9
    Yes the code sorts in descending order. But I can't progress with the next part as my VB skills are only just past beginner. Meaning I need an explicit code example. With respect to file names, they could be all variations, single word, multiple words, dashes, dots, etc. Revisions could be alpha or numeric.

  10. #10
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,729
    Location
    1. Do you only want to search within a single folder, i.e. not looking in sub folders?

    2. If you do want to search the entire tree, how do you want to handle something like

    ...\Folder1\Filename[1]
    ...\Folder1\Filename[2]
    ...\Folder2\Filename[1]
    ...\Folder3\Filename[3]

    Just return ...\Folder3\Filename[3]?


    3. If you do want to search the entire tree, how do you want to handle something like

    ...\Folder1\Filename[1]
    ...\Folder1\Filename[2]
    ...\Folder2\Filename[1]
    ...\Folder2\Filename[2]


    Return both ...\Folder1\Filename[2] and ...\Folder2\Filename[2]???
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  11. #11
    1. Prefer folder tree. Single folder acceptable.
    2. Cannot understand ... assuming searching one folder only. In Folder 1, return Filename[2].
    3. Yes.

  12. #12
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    Paul asked a good question. Basically, it looks like you base last versions on each subfolder's last version.

    I guess you got this far. I don't have time to finish this right now but it shows how I would set it up. You have to look at the last and current, folder, base filename, and file extension.
    Rem Needs Tools > References > MicroSoft Script Runtime, scrrun.dll
    Rem Instructions: http://support.microsoft.com/default.aspx?scid=kb;en-us;186118
    Sub Main()
      Dim sParent As String, x() As Variant, xx As Variant
      Dim sLFolder As String, sLBase As String, sLExt As String 'Last
      Dim sCFolder As String, sCBase As String, sCExt As String 'Current
      Dim fso As FileSystemObject
      Dim s() As String
      
      Set fso = New FileSystemObject
      
      sParent = "x:\t\tt\ttt"
      sParent = fGetFolder("Delete Selection to Pick Entry Folder", sParent)
      If sParent = "" Then Exit Sub
        
      'Descending Order by drive\path\filename.ext. Do not list folders.
      x() = aFFs("x:\t\tt", "/O-N /A-D", True) 'True, check all subfolders.
      'MsgBox Join(x(), vbLf) 'Truncates end of long strings.
      'Debug.Print Join(x, vbLf) 'May truncate from beginning of long string.
    
    
      sLFolder = ""
      sLBase = ""
      sLExt = ""
      sCFolder = ""
      sCBase = ""
      sCExt = ""
    
    
      With fso
        For Each xx In x()
          sCFolder = .GetParentFolderName(xx)
          sCBase = .GetBaseName(xx)
          sCExt = .GetExtensionName(xx)
          
          'Do checks here, show debug results for testing purposes.
    'MAIN VERSION CHECKS USING LAST and CURRENT DATA, GO BELOW....
          Debug.Print sLFolder, sLBase, sLExt 'Last results
          Debug.Print sCFolder, sCBase, sCExt 'Current results
          
          'Reset Last data to Current data based on IF checks added above
          sLFolder = sCFolder
          sLBase = sCBase
          sLExt = sCExt
        Next xx
      End With
    End Sub
    
    
    Private Function fGetFolder(Optional HeaderMsg As String, Optional sInitialFilename As String = "") As String
        With Application.FileDialog(msoFileDialogFolderPicker)
            If sInitialFilename = "" Then sInitialFilename = Application.DefaultFilePath
            .InitialFileName = sInitialFilename
            .Title = HeaderMsg
            If .Show = -1 Then
                fGetFolder = .SelectedItems(1)
            Else
                fGetFolder = ""
            End If
        End With
    End Function
    
    
    'Set extraSwitches, e.g. "/ad", to search folders only.
    'MyDir should end in a "\" character unless searching by wildcards, e.g. "x:\test\t*
    'Command line switches for the shell's Dir, http://ss64.com/nt/dir.html
    Function aFFs(myDir As String, Optional extraSwitches = "", _
      Optional tfSubFolders As Boolean = False) As Variant
      
      Dim s As String, a() As String, v As Variant
      Dim b() As Variant, i As Long
      
      If tfSubFolders Then
        s = CreateObject("Wscript.Shell").Exec("cmd /c dir " & _
          """" & myDir & """" & " /b /s " & extraSwitches).StdOut.ReadAll
        Else
        s = CreateObject("Wscript.Shell").Exec("cmd /c dir " & _
          """" & myDir & """" & " /b " & extraSwitches).StdOut.ReadAll
      End If
      
      a() = Split(s, vbCrLf)
      If UBound(a) = -1 Then
        MsgBox myDir & " not found.", vbCritical, "Macro Ending"
        Exit Function
      End If
      ReDim Preserve a(0 To UBound(a) - 1) As String 'Trim trailing vblfcr
      
      For i = 0 To UBound(a)
        If Not tfSubFolders Then
          s = Left$(myDir, InStrRev(myDir, "\"))
          'add the folder name
          a(i) = s & a(i)
        End If
      Next i
      aFFs = sA1dtovA1d(a)
    End Function
    
    
    Function sA1dtovA1d(strArray() As String) As Variant
      Dim varArray() As Variant, i As Long
      ReDim varArray(LBound(strArray) To UBound(strArray))
      For i = LBound(strArray) To UBound(strArray)
        varArray(i) = CVar(strArray(i))
      Next i
      sA1dtovA1d = varArray()
    End Function

  13. #13
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,729
    Location
    Quote Originally Posted by Trying View Post
    1. Prefer folder tree. Single folder acceptable.
    2. Cannot understand ... assuming searching one folder only. In Folder 1, return Filename[2].
    3. Yes.
    Your answer to 1 (Search entire folder tree) seems to conflict with your answer to 2 (one folder only). In the example/question the [3] file was in a different folder, but still within the over all tree.

    a. So if you wanted to search within only each sub folder of each (sub) folder, then you'd have 3 returned


    ...\Folder1\Filename[1] - No
    ...\Folder1\Filename[2] - Yes
    ...\Folder2\Filename[1] - Yes
    ...\Folder3\Filename[3] - Yes



    b. So if you wanted to search the entire folder tree, then you'd have 1 returned


    ...\Folder1\Filename[1] - No
    ...\Folder1\Filename[2] - No
    ...\Folder2\Filename[1] - No
    ...\Folder3\Filename[3] - Yes

    All depends on what your requirements are
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  14. #14
    Moderator VBAX Sage SamT's Avatar
    Joined
    Oct 2006
    Location
    Near Columbia
    Posts
    7,814
    Location
    @ Trying

    Since you apparently have no organization to your files and folders, how do we know which of these files you want returned?

    Folder Tree
    MainFolder
    Folder1
    Folder3
    Folder2
    MainFolder Files
    Folder1 Files Folder2
    Files
    Folder3
    Files
    FstFile.xls FstFile.xls FstFile.xls FstFile.xls
    FstFile[1].xls FstFile[2].xls ThrdFile.xls SecFile.xls
    SecFile.xls SecFile[1].xls FrthFile.xls FrthFile[1].xls


    Please tell us that there is a rule about where files are stored.

    And please tell us that rule.
    I expect the student to do their homework and find all the errrors I leeve in.


    Please take the time to read the Forum FAQ

  15. #15
    Paul, this is what I was after.

    ...\Folder1\Filename[1] - No
    ...\Folder1\Filename[2] - Yes
    ...\Folder2\Filename[1] - Yes
    ...\Folder3\Filename[3] - Yes

    Continuing brief: In a folder tree, for each folder (the key), where there are multiple files with the same name but different revision, return only the data for the latest revision file. File revisions are bound by square brackets. Revision tags may be numeric single digit such as [1], numeric multiple digit such as [12], or alpha such as [A].

  16. #16
    Kenneth, I get an error message when I run the code.
    Compile error: User-defined type not defined.
    Highlights "Dim FSO As FileSystemObject"

  17. #17
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    Rem and ' designate comments. In the REM, I explain that it uses a library reference and how to add it. I also provided a link to the help file for fso.

    This should be close.
    Option Explicit
    
    Rem Needs Tools > References > MicroSoft Script Runtime, scrrun.dll
    Rem Instructions: http://support.microsoft.com/default.aspx?scid=kb;en-us;186118
    Sub Main()
      Dim sParent As String, x() As Variant, y() As Variant, xx As Variant, i As Long
      Dim sLFolder As String, sLBase As String, sLExt As String 'Last
      Dim sCFolder As String, sCBase As String, sCExt As String 'Current
      Dim sLFBE As String, sCFBE As String
      Dim fso As FileSystemObject, r As Range
      
      Set fso = New FileSystemObject
      
      sParent = "d:\myfiles\Excel\t\t\" 'Add trailing backslash, "\".
      sParent = fGetFolder("Pick Parent Folder", sParent)
      If sParent = "" Then Exit Sub
        
      'Descending Order by drive\path\filename.ext. Do not list folders.
      x() = aFFs(sParent, "/O-N /A-D", True) 'True, check all subfolders.
      'MsgBox Join(x(), vbLf) 'Truncates end of long strings.
      'Debug.Print Join(x, vbLf) 'May truncate from beginning of long string.
    
    
      y() = x() 'Make sure that y() can hold all of x() if needed.
    
    
      'First cell to add hyperlink.
      Set r = Range("C" & Rows.Count).End(xlUp).Offset(1)
    
    
      sLFolder = ""
      sLBase = ""
      sLExt = ""
      sLFBE = ""
      sCFolder = ""
      sCBase = ""
      sCExt = ""
      sCFBE = ""
      i = 0
      
      With fso
        For Each xx In x()
          sCFolder = .GetParentFolderName(xx)
          sCBase = .GetBaseName(xx)
          sCExt = .GetExtensionName(xx)
          sCFBE = sCFolder & "\" & PrefixBeforeBracket(sCBase) & sCExt
          
          If sCFBE <> sLFBE Then
            i = i + 1
            ReDim Preserve y(i)
            y(i) = xx
            
            'Reset Last data to Current data based on loop checks above
            sLFolder = sCFolder
            sLBase = sCBase
            sLExt = sCExt
            sLFBE = sLFolder & "\" & PrefixBeforeBracket(sLBase) & sLExt
          End If
        Next xx
      End With
      
      'MsgBox Join(y(), vbLf) 'Truncates end of long strings.
      'Debug.Print Join(y, vbLf) 'May truncate from beginning of long string.
      'Add Hyperlinks...
      For i = 1 To UBound(y)
        r.Hyperlinks.Add r, y(i), TextToDisplay:=fso.GetBaseName(y(i))
        Set r = r.Offset(1)
      Next i
    End Sub
    
    
    Function PrefixBeforeBracket(aString As String) As String
      Dim i As Integer
      i = InStr(aString, "[")
      If i = 0 Then
        PrefixBeforeBracket = aString
        Else
        PrefixBeforeBracket = Left(aString, i - 1)
      End If
    End Function
    
    
    Function fGetFolder(Optional HeaderMsg As String, Optional sInitialFilename As String = "") As String
        With Application.FileDialog(msoFileDialogFolderPicker)
            If sInitialFilename = "" Then sInitialFilename = Application.DefaultFilePath
            .InitialFileName = sInitialFilename
            .Title = HeaderMsg
            If .Show = -1 Then
                fGetFolder = .SelectedItems(1)
            Else
                fGetFolder = ""
            End If
        End With
    End Function
    
    
    'Set extraSwitches, e.g. "/ad", to search folders only.
    'MyDir should end in a "\" character unless searching by wildcards, e.g. "x:\test\t*
    'Command line switches for the shell's Dir, http://ss64.com/nt/dir.html
    Function aFFs(myDir As String, Optional extraSwitches = "", _
      Optional tfSubFolders As Boolean = False) As Variant
      
      Dim s As String, a() As String, v As Variant
      Dim b() As Variant, i As Long
      
      If tfSubFolders Then
        s = CreateObject("Wscript.Shell").Exec("cmd /c dir " & _
          """" & myDir & """" & " /b /s " & extraSwitches).StdOut.ReadAll
        Else
        s = CreateObject("Wscript.Shell").Exec("cmd /c dir " & _
          """" & myDir & """" & " /b " & extraSwitches).StdOut.ReadAll
      End If
      
      a() = Split(s, vbCrLf)
      If UBound(a) = -1 Then
        MsgBox myDir & " not found.", vbCritical, "Macro Ending"
        Exit Function
      End If
      ReDim Preserve a(0 To UBound(a) - 1) As String 'Trim trailing vblfcr
      
      For i = 0 To UBound(a)
        If Not tfSubFolders Then
          s = Left$(myDir, InStrRev(myDir, "\"))
          'add the folder name
          a(i) = s & a(i)
        End If
      Next i
      aFFs = sA1dtovA1d(a)
    End Function
    
    
    Function sA1dtovA1d(strArray() As String) As Variant
      Dim varArray() As Variant, i As Long
      ReDim varArray(LBound(strArray) To UBound(strArray))
      For i = LBound(strArray) To UBound(strArray)
        varArray(i) = CVar(strArray(i))
      Next i
      sA1dtovA1d = varArray()
    End Function

  18. #18
    Kenneth, this works!
    Thx for the effort.

  19. #19
    Kenneth, your macro works very well but it is so different to the initial one I was using, and I'm finding it difficult to integrate with the rest of the VB project (not shown initially because I didn't think it was relevant when I posted). The detailed code is shown below. The items which I cannot resolve include the following.
    1. In addition to the hyperlink output, I also have others including Subject, Author and Title. These are Windows file attributes. Refer to Code 1.
    2. The cell output from the initial code included the hyperlink with the folder path written in. I still need this because I was using another macro to open up Windows Explorer using the cell output (from a right click menu). Refer to Code 2a and 2b.
    3. For each iteration I need to add a row into Excel, at the moment doing this by Rows(r).Insert.
    4. With the folder dialogue I would like this to remember the last location it was on.
    Sorry if this is too much. Whatever you can assist with.


    *** Code 1
    Sub File_Attributes()
        Dim sFolder As FileDialog
        Set sFolder = Application.FileDialog(msoFileDialogFolderPicker)
        If sFolder.Show = -1 Then
        File_Attributes_List_Files sFolder.SelectedItems(1), True
        End If
    End Sub
    
    Sub File_Attributes_List_Files(ByVal SourceFolderName As String, ByVal IncludeSubfolders As Boolean)
        Dim FSO As Object
        Dim SourceFolder As Object
        Dim SubFolder As Object
        Dim FileItem As Object
        Dim r As Long
        Set FSO = CreateObject("Scripting.FileSystemObject")
        Set SourceFolder = FSO.GetFolder(SourceFolderName)
        r = ActiveCell.Row
        For Each FileItem In SourceFolder.Files
        Rows(r).Insert
        Cells(r, 2).Formula = Get_File_Attribute_Subject(SourceFolder.Path, FileItem.Name)
        Cells(r, 3).Formula = Chr(61) & "HYPERLINK(" & Chr(34) & FileItem.Path & Chr(34) & "," & Chr(34) & FileItem.Name & Chr(34) & ")"
        Cells(r, 4).Formula = GetFileDataAuthor(SourceFolder.Path, FileItem.Name)
        Cells(r, 5).Formula = GetFileDataTitle(SourceFolder.Path, FileItem.Name)
        r = r + 1
        x = SourceFolder.Path
        Next FileItem
        If IncludeSubfolders Then
        For Each SubFolder In SourceFolder.SubFolders
        File_Attributes_List_Files SubFolder.Path, True
        Next SubFolder
        End If
        Set FileItem = Nothing
        Set SourceFolder = Nothing
        Set FSO = Nothing
        ActiveWorkbook.Saved = True
    End Sub
    
    Function Get_File_Attribute_Subject(ByVal Filepath As String, ByVal FileName As String)
        Dim objFolder As Object
        Dim objFolderItem As Object
        Dim objShell As Object
        FileName = StrConv(FileName, vbUnicode)
        Filepath = StrConv(Filepath, vbUnicode)
        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.Namespace(StrConv(Filepath, vbFromUnicode))
        If Not objFolder Is Nothing Then
        Set objFolderItem = objFolder.ParseName(StrConv(FileName, vbFromUnicode))
        End If
        If Not objFolderItem Is Nothing Then
        Get_File_Attribute_Subject = objFolder.GetDetailsOf(objFolderItem, 22) '11 (Windows xp), 22 (Windows Vista, Windows 7, Windows 8)
        Else
        Get_File_Attribute_Subject = ""
        End If
        Set objShell = Nothing
        Set objFolder = Nothing
        Set objFolderItem = Nothing
    End Function
    
    Function GetFileDataAuthor(ByVal Filepath As String, ByVal FileName As String)
        Dim objFolder As Object
        Dim objFolderItem As Object
        Dim objShell As Object
        FileName = StrConv(FileName, vbUnicode)
        Filepath = StrConv(Filepath, vbUnicode)
        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.Namespace(StrConv(Filepath, vbFromUnicode))
        If Not objFolder Is Nothing Then
        Set objFolderItem = objFolder.ParseName(StrConv(FileName, vbFromUnicode))
        End If
        If Not objFolderItem Is Nothing Then
        GetFileDataAuthor = objFolder.GetDetailsOf(objFolderItem, 20) '9 (Windows xp), 20 (Windows Vista, Windows 7, Windows 8)
        Else
        GetFileDataAuthor = ""
        End If
        Set objShell = Nothing
        Set objFolder = Nothing
        Set objFolderItem = Nothing
    End Function
    
    Function GetFileDataTitle(ByVal Filepath As String, ByVal FileName As String)
        Dim objFolder As Object
        Dim objFolderItem As Object
        Dim objShell As Object
        FileName = StrConv(FileName, vbUnicode)
        Filepath = StrConv(Filepath, vbUnicode)
        Set objShell = CreateObject("Shell.Application")
        Set objFolder = objShell.Namespace(StrConv(Filepath, vbFromUnicode))
        If Not objFolder Is Nothing Then
        Set objFolderItem = objFolder.ParseName(StrConv(FileName, vbFromUnicode))
        End If
        If Not objFolderItem Is Nothing Then
        GetFileDataTitle = objFolder.GetDetailsOf(objFolderItem, 21) '10 (Windows xp), 21 (Windows Vista, Windows 7, Windows 8)
        Else
        GetFileDataTitle = ""
        End If
        Set objShell = Nothing
        Set objFolder = Nothing
        Set objFolderItem = Nothing
    End Function

    *** Code 2a (under Workbook)
    Option Explicit
    
    Private Sub Workbook_Activate()
        Run "Hide_Sheet"
        Run "Open_Folder_Create_Menu"
    End Sub

    *** Code 2b
    Const strMacro = "Open Explorer"
    
    Sub Open_Folder_Create_Menu()
        Dim cBut
        Call Open_Folder_Remove_Menu
        Set cBut = Application.CommandBars("Cell").Controls.Add(Temporary:=True)
        With cBut
            .Caption = strMacro
            .Style = msoButtonCaption
            .OnAction = "Open_Folder"
        End With
    End Sub
    
    Sub Open_Folder_Remove_Menu()
        On Error Resume Next
        Application.CommandBars("Cell").Controls(strMacro).Delete
    End Sub
    
    Sub Open_Folder()
        Dim Folder As String
        Folder = Replace(ActiveCell.Formula, "=HYPERLINK(", "")
        Folder = Replace(Left(Folder, InStr(Folder, ",") - 1), """", "")
        Shell "C:\Windows\explorer.exe /select," & Folder, vbMaximizedFocus
    End Sub

  20. #20
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    This part of Main() is easily changed to use what you have for steps 1 and 3. I thought that was fairly easy to understand so I left it for you to add your file attribute parts. FSO can be used directly rather than calling the functions. While you can do it calling functions and I do use similar functions, instantiating the FSO object once is best.
    For i = 1 To UBound(y) [
      r.Hyperlinks.Add r, y(i), TextToDisplay:=fso.GetBaseName(y(i)) 
      Set r = r.Offset(1)  
    Next i
    Since I used the Range Hyperlink method rather than the Hyperlink formula as you did, doing 2 as a new function is even easier. I can show you if needed.

    For step 4, that is an FAQ. You have to decide where and how you want to use the stored value. If just needed in ThisWorkbook or ActiveWorkbook, I would use step 1 below. This is very simple. If you need help, post back later.
    1. Cell in ThisWorkbook or ActiveWorkbook.
    2. Cell in another workbook.
    3. Store in registry. See GetSetting().
    4. etc.

    So, post back for the parts where help is needed. If I get time later and you have not responded, I will work on it a bit.
    Last edited by Kenneth Hobs; 06-18-2016 at 07:04 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •