[VBA] - Check for latest report folder within a directory.

RockandGrohl

Well-known Member
Joined
Aug 1, 2018
Messages
788
Office Version
  1. 2010
Platform
  1. Windows
Hello all,

We have a folder for a customer with reporting folders inside, so typically each customer folder will look like this:

Excel Formula:
2020-12
2021-01
2021-02
2021-03
2021-04
etc
2021-07
2021-08
[other folders]
[other files]

What I want to do is to get the latest dated folder that has the YYYY-MM format, ignoring all other files and folders.

So once that is found, it can be added to a string to open that particular folder like:

Company\Customers\Donk\2021-08\

I'd then want to open any xls file that had the name "Usage" in it.

Thanks guys!
 

Excel Facts

When did Power Query debut in Excel?
Although it was an add-in in Excel 2010 & Excel 2013, Power Query became a part of Excel in 2016, in Data, Get & Transform Data.
Right, how about the code below. Note the separate function procedures. They are necessary to make this all happen.

VBA Code:
Public Sub RockandGrohl()

    Const SEARCHFOLDER As String = "C:\Users\RockandGrohl\Company\Customers\Donk"       ' <<< change to suit
    Const SEARCHFORMAT As String = "####-##"

    Dim FullName As String
    FullName = GetFirstFolderByFormat(SEARCHFOLDER, SEARCHFORMAT, xlDescending)

End Sub


Public Function GetFirstFolderByFormat(ByVal argSearchFolder As String, ByVal argFormat As String, Optional ByVal argSortOrder As XlSortOrder = xlAscending) As String

    Dim FSO As Object, oFolder As Object, Dict As Object
    Dim FolderName  As String, i As Long

    If Len(argSearchFolder) > 0 And Len(argFormat) > 0 Then
        argSearchFolder = IIf(Right(argSearchFolder, 1) = "\", argSearchFolder, argSearchFolder & "\")
        Set FSO = CreateObject("Scripting.FileSystemObject")
        If FSO.FolderExists(argSearchFolder) Then

            Set Dict = CreateObject("Scripting.Dictionary")
            For Each oFolder In FSO.GetFolder(argSearchFolder).SubFolders
                Dict.Add oFolder.Name, oFolder.DateCreated
            Next oFolder
            Set Dict = DictSortByKey(Dict, argSortOrder)

            For i = 0 To Dict.Count - 1
                If Dict.Keys()(i) Like argFormat Then
                    GetFirstFolderByFormat = argSearchFolder & Dict.Keys()(i)
                    Exit For
                End If
            Next i
        End If
    End If
    Set oFolder = Nothing
    Set FSO = Nothing
    Set Dict = Nothing
End Function


Public Function DictSortByKey(ByVal argDict As Object, Optional ByVal argSortOrder As XlSortOrder = xlAscending) As Object

    Dim oArrList As Object, Dict As Object, Key As Variant

    Set Dict = CreateObject("Scripting.Dictionary")
    Set oArrList = CreateObject("System.Collections.ArrayList")

    For Each Key In argDict.Keys
        oArrList.Add Key
    Next Key
    oArrList.Sort
    If argSortOrder = xlDescending Then
        oArrList.Reverse
    End If
    For Each Key In oArrList
        Dict.Add Key, argDict(Key)
    Next Key
    Set DictSortByKey = Dict

    Set oArrList = Nothing
    Set Dict = Nothing
End Function
 
Upvote 0
Another option:
Just to get the latest dated folder (result in immediate window).
VBA Code:
Sub GetSubFolderNames_1180678()
Dim FileName As String
Dim PathName As String
Dim tx As String
PathName = "D:\zzz\try\"  '< --adjust
FileName = Dir(PathName, vbDirectory)

Do While FileName <> ""
    If GetAttr(PathName & FileName) = vbDirectory And FileName Like "####-##" Then tx = FileName
    FileName = Dir()
Loop

Debug.Print tx

End Sub
 
Upvote 0
Solution
Right, how about the code below. Note the separate function procedures. They are necessary to make this all happen.

VBA Code:
Public Sub RockandGrohl()

    Const SEARCHFOLDER As String = "C:\Users\RockandGrohl\Company\Customers\Donk"       ' <<< change to suit
    Const SEARCHFORMAT As String = "####-##"

    Dim FullName As String
    FullName = GetFirstFolderByFormat(SEARCHFOLDER, SEARCHFORMAT, xlDescending)

End Sub


Public Function GetFirstFolderByFormat(ByVal argSearchFolder As String, ByVal argFormat As String, Optional ByVal argSortOrder As XlSortOrder = xlAscending) As String

    Dim FSO As Object, oFolder As Object, Dict As Object
    Dim FolderName  As String, i As Long

    If Len(argSearchFolder) > 0 And Len(argFormat) > 0 Then
        argSearchFolder = IIf(Right(argSearchFolder, 1) = "\", argSearchFolder, argSearchFolder & "\")
        Set FSO = CreateObject("Scripting.FileSystemObject")
        If FSO.FolderExists(argSearchFolder) Then

            Set Dict = CreateObject("Scripting.Dictionary")
            For Each oFolder In FSO.GetFolder(argSearchFolder).SubFolders
                Dict.Add oFolder.Name, oFolder.DateCreated
            Next oFolder
            Set Dict = DictSortByKey(Dict, argSortOrder)

            For i = 0 To Dict.Count - 1
                If Dict.Keys()(i) Like argFormat Then
                    GetFirstFolderByFormat = argSearchFolder & Dict.Keys()(i)
                    Exit For
                End If
            Next i
        End If
    End If
    Set oFolder = Nothing
    Set FSO = Nothing
    Set Dict = Nothing
End Function


Public Function DictSortByKey(ByVal argDict As Object, Optional ByVal argSortOrder As XlSortOrder = xlAscending) As Object

    Dim oArrList As Object, Dict As Object, Key As Variant

    Set Dict = CreateObject("Scripting.Dictionary")
    Set oArrList = CreateObject("System.Collections.ArrayList")

    For Each Key In argDict.Keys
        oArrList.Add Key
    Next Key
    oArrList.Sort
    If argSortOrder = xlDescending Then
        oArrList.Reverse
    End If
    For Each Key In oArrList
        Dict.Add Key, argDict(Key)
    Next Key
    Set DictSortByKey = Dict

    Set oArrList = Nothing
    Set Dict = Nothing
End Function
Good lord that's a lot of code.

I'm about to jump on a call but I'll give it a go after, thanks.
 
Upvote 0
Another option:
Just to get the latest dated folder (result in immediate window).
VBA Code:
Sub GetSubFolderNames_1180678()
Dim FileName As String
Dim PathName As String
Dim tx As String
PathName = "D:\zzz\try\"  '< --adjust
FileName = Dir(PathName, vbDirectory)

Do While FileName <> ""
    If GetAttr(PathName & FileName) = vbDirectory And FileName Like "####-##" Then tx = FileName
    FileName = Dir()
Loop

Debug.Print tx

End Sub
How would this know that 2021-08 is later than 2021-03 for instance?

What if contents of 2021-03 were modified afterward?

Thanks.
 
Upvote 0
@Akuini, your code gives me an empty string. This can be explained by the fact that a file attribute usually consists of multiple attributes. We need to isolate the attribute we're checking from all the others. If you replace the = character by the AND operater you're close. Close, because my next remark would be the same as RockandGrohl's observation in hist post #7.
 
Upvote 0
I just checked Ak's and his gave me the correct folder, but that was because it was also made AFTER the 2021-07. I'm going to create a new folder called 2021-10 and then another one called 2021-09 and see what happens.

EDIT: Yeah, it works. I created 2021-10 first, then 2021-09 and it gave me 2021-10 as the result.

No offense GWteb, but AK's is fast & compact :) Easy for my pigeon brain to decipher.
 
Upvote 0
No offense GWteb, but AK's is fast & compact
Don't worry, if you are happy, so am I.

@Akuini's alternative works for now, but only on the basis of coincidences. This has to do with how the NTFS file system works.
In any case, change the = with the AND operator because once your folder has been indexed, @Akuini's code won't work anymore.
 
Upvote 0

Forum statistics

Threads
1,214,786
Messages
6,121,553
Members
449,038
Latest member
Guest1337

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top