Option Explicit
'References required
'mscorlib.dll (C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb)
Public Sub Find_Files_Create_Hyperlinks()
Dim mainFolder As String
Dim cell As Range
Dim filesArrayList As mscorlib.ArrayList
Dim fileFoundIndex As Long
Dim file As clsFile
Dim fileComparer As clsFileComparer
mainFolder = "../../A_DOCUMENTS\" 'PATH TO A_DOCUMENTS FOLDER - EDIT AS REQUIRED"
'Get listing of all files in main folder and its subfolders and put into an ArrayList.
'Each ArrayList item is a clsFile object which has separate properties for the file name and folder path, so that just the file name part can be searched
Set filesArrayList = New mscorlib.ArrayList
Get_Files_In_Folder mainFolder, filesArrayList
'Sort the ArrayList in ascending order of file name, for fast searching using BinarySearch_3 method below
'https://docs.microsoft.com/en-us/dotnet/api/system.collections.arraylist.sort?view=net-6.0
'ArrayList.Sort(IComparer)
'Sorts the elements in the entire ArrayList using the specified comparer.
Set fileComparer = New clsFileComparer
filesArrayList.Sort_2 fileComparer
Set file = New clsFile
For Each cell In ActiveSheet.UsedRange
If InStr(cell.Value, ".") Then
'Put this cell's value (the file name being sought) in a clsFile structure and search for it in filesArrayList using a binary search
file.fileName = cell.Value
file.folderPath = ""
'https://docs.microsoft.com/en-us/dotnet/api/system.collections.arraylist.binarysearch?view=net-6.0
'ArrayList.BinarySearch(Object, IComparer)
'Searches the entire sorted ArrayList for an element using the specified comparer and returns the zero-based index of the element.
'Returns:
'The zero-based index of value in the sorted ArrayList, if value is found; otherwise, a negative number, which is the bitwise complement of the
'index of the next element that is larger than value or, if there is no larger element, the bitwise complement of Count.
fileFoundIndex = filesArrayList.BinarySearch_3(file, fileComparer)
If fileFoundIndex >= 0 Then
Set file = filesArrayList(fileFoundIndex)
cell.Worksheet.Hyperlinks.Add Anchor:=cell, Address:=file.folderPath & file.fileName, TextToDisplay:=cell.Value
Else
'file not found
End If
End If
Next
End Sub
Private Sub Get_Files_In_Folder(folderPath As String, filesArrayList As mscorlib.ArrayList)
Dim WSh As Object 'WshShell
Dim command As String
Dim files As Variant
Dim file As clsFile
Dim i As Long, p As Long
Set WSh = CreateObject("WScript.Shell") 'New WshShell
'Get list of all files in specified folder and its subfolders
command = "cmd /c DIR /S /B " & Chr(34) & folderPath & Chr(34)
files = Split(WSh.Exec(command).StdOut.ReadAll, vbCrLf)
'Put the files in an ArrayList. Each file item is a clsFile object
For i = 0 To UBound(files) - 1
p = InStrRev(files(i), "\")
Set file = New clsFile
file.fileName = Mid(files(i), p + 1)
file.folderPath = Left(files(i), p)
filesArrayList.Add file
Next
End Sub