Return Hyperlink for Corresponding File from a List on Worksheet.

jcoleman25

New Member
Joined
Jan 26, 2013
Messages
21
Forgive me if this is covered somewhere else, I've looked around but it seems to be fairly specific.

I have a list of customer part numbers that I would like to search for the corresponding file in a folder and subfolders. (the pdf print of a sheetmetal part for example).

The files will often have a revision on them. So the first part number might have a file name 172292_A or 172292_AB.

This is what the end result might look like:
PART#
Link
172292
(hyperlink)
135325
(hyperlink)
150413
Not Found
2104-149
(hyperlink)

<tbody>
</tbody>


I have very limited experience with VBA so this problem is over my head (for now). I usually just move information around within a workbook. This will eventually be used on Windows 7 machines with Excel 2010. Backwards compatibility is not necessary.

Any help is appreciated. Thanks

John
 
Last edited:
Thanks for the response and updates. I'm out of time this morning, I'll try to look at it later today.
 
Upvote 0

Excel Facts

How to find 2nd largest value in a column?
MAX finds the largest value. =LARGE(A:A,2) will find the second largest. =SMALL(A:A,3) will find the third smallest
Thanks for the update. I actually bought a Win 7/2010 machine for home so I can work on these a little more. I just had a macbook at home before. My work machine is XP/2003 but I usually can access a 7/2010.

Anyway, I was looking at this thing and getting a better feel for how it works. I was having an issue with the hyperlinks not actually opening the files but I tracked it down to the # symbol in the test files I was using. One thing I haven't figured out yet is the TextToDisplay on the hyperlinks. I'd like to just have the file name instead of the full path. I tried TTD:= file and TTD:= file.Name but they didn't work. I suspect that the file value doesn't get transferred back up?

A few other things I'd like to work out eventually: I'd love it if this thing could come back with multiple files/links if there are any and add rows to accomodate.
Also, when testing, I used #1 through #15. The #1 part number cell would get a link to file #11. That issue would likely be rare for us but I'd like to get it handled never the less.

Code below with some of my notes and a few questions if you'd be so kind. Thanks

Code:
Sub AddLinks()
Range(CellRange).Offset(0, 1).Clear
    Dim rngPartList As Range, rngPartNo As Range
    
    Set rngPartList = ActiveSheet.Range(CellRange)  'const
    For Each rngPartNo In rngPartList               'for each cell in cellrange
        FolderSearch FolderPath, rngPartNo, 0
        ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo.Offset(0, 1), Address:=strFilePath 'TextToDisplay:=file
        strFilePath = vbNullString
    Next rngPartNo
    
End Sub

Sub FolderSearch(MyPath, strMatch, counter As Boolean) 'mypath is folder path from above, strmatch is the filename from each cell, counter is true false?
    
    Dim fso, folder, SubFolders, subfolder, file
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.Getfolder(MyPath)                      'get the constant folder
    If counter = 0 Then
        For Each file In folder.files                                     'folder equals file system object and files is just next step down like each range in a range is a cell?
            If InStr(1, file.Name, strMatch, vbTextCompare) > 0 Then      'InStr   (start point, string, substring, type,
                strFilePath = file                                        'where does strfilepath come from?
               'Debug.Print file.Name
               Exit Sub
            End If
        Next file
    End If
    Set SubFolders = folder.SubFolders
    For Each subfolder In SubFolders
        For Each file In subfolder.files
            If InStr(1, file.Name, strMatch, vbTextCompare) > 0 Then
                strFilePath = file
                Exit Sub
            End If
        Next file
        FolderSearch subfolder, strMatch, 1
    Next subfolder
    
End Sub

[\Code]
 
Last edited:
Upvote 0
Well, thats embarrassing.


Code:
Sub AddLinks()
Range(CellRange).Offset(0, 1).Clear
    Dim rngPartList As Range, rngPartNo As Range

    Set rngPartList = ActiveSheet.Range(CellRange)  'const
    For Each rngPartNo In rngPartList               'for each cell in cellrange
        FolderSearch FolderPath, rngPartNo, 0
        ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo.Offset(0, 1), Address:=strFilePath 'TextToDisplay:=file
        strFilePath = vbNullString
    Next rngPartNo

End Sub

Sub FolderSearch(MyPath, strMatch, counter As Boolean) 'mypath is folder path from above, strmatch is the filename from each cell, counter is true false?

    Dim fso, folder, SubFolders, subfolder, file

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.Getfolder(MyPath)                      'get the constant folder
    If counter = 0 Then
        For Each file In folder.files                                     'folder equals file system object and files is just next step down like each range in a range is a cell?
            If InStr(1, file.Name, strMatch, vbTextCompare) > 0 Then      'InStr   (start point, string, substring, type,
                strFilePath = file                                        'where does strfilepath come from?
               'Debug.Print file.Name
               Exit Sub
            End If
        Next file
    End If
    Set SubFolders = folder.SubFolders
    For Each subfolder In SubFolders
        For Each file In subfolder.files
            If InStr(1, file.Name, strMatch, vbTextCompare) > 0 Then
                strFilePath = file
                Exit Sub
            End If
        Next file
        FolderSearch subfolder, strMatch, 1
    Next subfolder

End Sub
 
Upvote 0
I changed up the code to accommodate your request of returning multiple files. Note! The different files are added in columns, not rows (easier to make it work that way). I also added the functionality that the file name is displayed in the hyperlink, not the full path. Not sure how to handle 'Part 1' returning 'Part 1A', but not 'Part 11'. The way the code is written is that it searches for 'Part 1" anywhere in the file name (as you requested), so it will return 'Part 1A' and 'Part 11'. Are there any other rules with the part nos, e.g. there is always an underscore (_) between the part no and revision, or something like that?

Code:
Const FolderPath As String = "C:\Users\jcoleman\Desktop\temp test"Const CellRange As String = "A2:A5"
Dim MyFiles As New Collection
Sub AddLinks()


    Dim rngPartList As Range, rngPartNo As Range
    Dim i As Long, j As Long
    
    Set rngPartList = ActiveSheet.Range(CellRange)
    FileList FolderPath, 0
    For Each rngPartNo In rngPartList
        j = 0
        For i = 1 To MyFiles.Count
            If InStr(1, MyFiles.Item(i)(1), rngPartNo, vbTextCompare) > 0 Then
                j = j + 1
                ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo.Offset(0, j), Address:=MyFiles.Item(i)(0), TextToDisplay:=MyFiles.Item(i)(1)
            End If
        Next i
    Next rngPartNo
    Set MyFiles = Nothing
    
End Sub
Sub FileList(MyPath, counter)


    Dim fso, folder, SubFolders, subfolder, file
    
    On Error Resume Next
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.Getfolder(MyPath)
    If counter = 0 Then
        For Each file In folder.files
            MyFiles.Add Array(file, file.Name)
        Next file
    End If
    Set SubFolders = folder.SubFolders
    For Each subfolder In SubFolders
        For Each file In subfolder.files
            MyFiles.Add Array(file, file.Name)
        Next file
        FileList subfolder, 1
    Next
    
End Sub
 
Upvote 0
About 90% of the time there will be an underscore in the cases I'm thinking of. Having it list every match instead of just the first will help with the Part 1, Part 1A, Part 11 stuff.

What are the (1) and the (0) doing in this code? Thanks to debug.print, I know what they output but I'm not sure why.

For i = 1 To MyFiles.Count
If InStr(1, MyFiles.Item(i)(1), rngPartNo, vbTextCompare) > 0 Then
j = j + 1
ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo_Offset(0, j), Address:=MyFiles.Item(i)(0), TextToDisplay:=MyFiles.Item(i)(1)
 
Upvote 0
MyFiles is a collection of arrays containing full paths and file names. (0) refers to the full paths and (1) refers to the file names.
 
Upvote 0
Thanks so much for your help on this, I've learned a lot. I've done some work on it using bits of macros I've done before and a few books I have. I think I have the multiple links in column instead of rows licked. I also added some user input and error handling. Any input from you is absolutely appreciated. Code under Before and After.

Before and After:
PART#
Description
138929
data I don’t want to lose
155181
data I don’t want to lose
26-03-10000_K
data I don’t want to lose
158180
data I don’t want to lose
26-20-01030_A
data I don’t want to lose
155183
data I don’t want to lose
141131
data I don’t want to lose
158180
data I don’t want to lose
155390
data I don’t want to lose
133519
data I don’t want to lose
133399
data I don’t want to lose
101785-036
data I don’t want to lose
101785-025
data I don’t want to lose
124979-033
data I don’t want to lose
124979
data I don’t want to lose
PART#
Description
138929
138929_B 7610 ISS Test Instructions.doc
data I don’t want to lose
138929_B 7610 ISS Test Instructions.pdf
138929_B 7610 ISS Test Instructions.doc
138929_B 7610 ISS Test Instructions.pdf
138929_B 7610 ISS Test Instructions.doc
138929_B 7610 ISS Test Instructions.pdf
138929_B 7610 ISS Test Instructions.doc
138929_B 7610 ISS Test Instructions.pdf
155181
155181_A.doc
data I don’t want to lose
155181_A.pdf
155181_A.doc
155181_A.pdf
155181_A.doc
155181_A.pdf
155181_A.doc
155181_A.pdf
26-03-10000_K
26-03-10000_K.pdf
data I don’t want to lose
26-03-10000_K.zip
26-03-10000_K.pdf
26-03-10000_K.zip
26-03-10000_K.pdf
26-03-10000_K.zip
26-03-10000_K.pdf
26-03-10000_K.zip
158180
data I don’t want to lose
26-20-01030_A
26-20-01030_A.doc
data I don’t want to lose
26-20-01030_A.pdf
26-20-01030_A.doc
26-20-01030_A.pdf
26-20-01030_A.doc
26-20-01030_A.pdf
26-20-01030_A.doc
26-20-01030_A.pdf
155183
155183_A.doc
data I don’t want to lose
155183_A.pdf
141131
data I don’t want to lose
158180
data I don’t want to lose
155390
data I don’t want to lose
133519
133519-A.pdf
data I don’t want to lose
RI_133519_A.doc
133399
data I don’t want to lose
101785-036
data I don’t want to lose
101785-025
data I don’t want to lose
124979-033
data I don’t want to lose
124979
data I don’t want to lose

<tbody>
</tbody>


Code:
Dim MyFiles As New Collection
'C:\Users\root\Dropbox\Excel Stuff\Cym Prints
Sub BOM_Hyperlinks_Setup()

If MsgBox("Hello. Please make sure you have a backup of this workbook before proceeding." & vbCrLf & _
      "Actions taken by this program cannot be undone." & vbCrLf & "Do you wish to continue?", vbYesNo) _
       = vbNo Then Exit Sub _
       Else: continueprocedure = True


ResumePath:
On Error GoTo ErrorHandle
FolderPath = InputBox("Please enter the path of the folder you wish to search: ")
Set PathCheck = CreateObject("Scripting.FileSystemObject")
Set folder = PathCheck.getfolder(FolderPath)
ResumeColumn:
On Error GoTo ErrorHandle
PartNoColumn = InputBox("Enter the column that the part numbers are in: ")
Range(PartNoColumn & "1").Select
ResumeFirstPart:
On Error GoTo ErrorhandleRow
FirstPart = InputBox("Enter the row that the first part number is in: ")
Range(PartNoColumn & FirstPart).Select
On Error GoTo 0
Add_Links FolderPath, PartNoColumn, FirstPart
Application.ScreenUpdating = True
MsgBox ("All done!")
Exit Sub
ErrorHandle:
Debug.Print Err.Number
Select Case Err.Number
    Case 76
        If MsgBox("That is not a valid file path." & vbCrLf & "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumePath
    Case 5
        If MsgBox("Sorry, without a folder I cannot continue." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumePath
    Case 1004
        If MsgBox("That is not a valid column." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumeColumn
End Select
ErrorhandleRow:
Debug.Print Err.Number
Select Case Err.Number
    Case 1004
        If MsgBox("That is not a valid row." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumeFirstPart
End Select
MsgBox ("Something unexpected has happened. This program will end." & vbCrLf & _
"Please write down this error number for debugging and program improvement." & vbCrLf & _
"The error number is " & Err.Number)

End Sub
Sub Add_Links(FolderPath, PartNoColumn, FirstPart)
Application.ScreenUpdating = False
'Columns(Columns(PartNoColumn.Count) + 1).Insert
Debug.Print PartNoColumn
'Range(PartNoColumn).Offset(0.1).Insert
Range(PartNoColumn & ":" & PartNoColumn).Offset(0, 1).Insert

Dim CellRange As String
CellRange = PartNoColumn & FirstPart & ":" & PartNoColumn & ActiveSheet.UsedRange.Rows.Count
'Range("B1:C5").Clear
    Dim rngPartList As Range, rngPartNo As Range
    Dim i As Long, j As Long

    Set rngPartList = ActiveSheet.Range(CellRange)
    FileList FolderPath, 0
    For Each rngPartNo In rngPartList
    If rngPartNo.Value = "" Then GoTo BlankCell
    Debug.Print rngPartNo
        j = 0
        For i = 1 To MyFiles.Count
            If InStr(1, MyFiles.Item(i)(1), rngPartNo, vbTextCompare) > 0 Then
            If rngPartNo.Cells.Offset(j, 1).Value <> "" Then j = j + 1
              If j > 0 Then Rows(rngPartNo.Row + j).Insert

            Debug.Print rngPartNo.Row
            Debug.Print rngPartNo

                ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo.Offset(j, 1), Address:=MyFiles.Item(i)(0), TextToDisplay:=MyFiles.Item(i)(1)

            End If
        Next i
BlankCell:
    Next rngPartNo
    Set MyFiles = Nothing

Columns(PartNoColumn & ":" & PartNoColumn).Offset(0, 1).AutoFit

End Sub
Sub FileList(MyPath, counter)

    Dim fso, folder, SubFolders, subfolder, file

    On Error Resume Next
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.getfolder(MyPath)
    If counter = 0 Then
        For Each file In folder.files
            MyFiles.Add Array(file, file.Name)

        Next file
    End If
    Set SubFolders = folder.SubFolders
    For Each subfolder In SubFolders
        For Each file In subfolder.files
            MyFiles.Add Array(file, file.Name)

        Next file
        FileList subfolder, 1
    Next

End Sub
 
Last edited:
Upvote 0
I cleaned up the code a bit. I have another challenge for this one. I'd like to add the ability for the user to add multiple folders to search (add all additional folders at the beginning, it would be too easy otherwise). I've been looking around and will continue to but if anyone has any thoughts...

Thanks

Code:
Dim MyFiles As New Collection
'Last Updated 2-5-13 by John Coleman

Sub BOM_Hyperlinks_Setup()
Dim TrimRange As Range
Dim TrimCell As Range
'reminder to backup
Select Case MsgBox("Hello. Actions taken by this program cannot be undone." & vbCrLf & _
      "Would you like to save this workbook first?.", vbYesNoCancel)
       Case vbYes
       ThisWorkbook.Save
       Case vbCancel
       Exit Sub
End Select
       
'get user input
      
ResumePath:
On Error GoTo ErrorHandle
FolderPath = InputBox("Please enter the path of the folder you wish to search: ")
Set PathCheck = CreateObject("Scripting.FileSystemObject")
Set folder = PathCheck.getfolder(FolderPath)
ResumeColumn:
On Error GoTo ErrorHandle
PartNoColumn = InputBox("Enter the column that the part numbers are in: ")
Range(PartNoColumn & "1").Select
ResumeFirstPart:
On Error GoTo ErrorHandleRow
FirstPart = InputBox("Enter the row that the first part number is in: ")
Range(PartNoColumn & FirstPart).Select
On Error GoTo 0
ST = Timer
Set TrimRange = Range(PartNoColumn & FirstPart & ":" & PartNoColumn & ActiveSheet.UsedRange.Rows.Count)
   For Each TrimCell In TrimRange
    TrimCell = Trim(TrimCell)
    Next TrimCell
'go to the ADD_Links Sub
Add_Links FolderPath, PartNoColumn, FirstPart
'allow screen update before the message box pops up
Application.ScreenUpdating = True
MsgBox ("All done!")
'THE END
Exit Sub
'folder and column error handling
ErrorHandle:
Select Case Err.Number
    Case 76
        If MsgBox("That is not a valid file path." & vbCrLf & "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumePath
    Case 5
        If MsgBox("Sorry, without a folder I cannot continue." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumePath
    Case 1004
        If MsgBox("That is not a valid column." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumeColumn
End Select
'row error handling
ErrorHandleRow:
Select Case Err.Number
    Case 1004
        If MsgBox("That is not a valid row." & vbCrLf & _
        "Try again?", vbYesNo) _
    = vbNo Then Exit Sub Else _
        Resume ResumeFirstPart
End Select
'unknown error handling
MsgBox ("Something unexpected has happened. This program will end." & vbCrLf & _
"Please write down this error number for debugging and program improvement." & vbCrLf & _
"The error number is " & Err.Number)

End Sub
Sub Add_Links(FolderPath, PartNoColumn, FirstPart)
'dimensions
Dim CellRange As String
Dim rngPartList As Range
Dim rngPartNo As Range
Dim i As Long
Dim j As Long

Application.ScreenUpdating = False
'insert column next to part numbers
Range(PartNoColumn & ":" & PartNoColumn).Offset(0, 1).Insert
'set CellRange
CellRange = PartNoColumn & FirstPart & ":" & PartNoColumn & ActiveSheet.UsedRange.Rows.Count
'set rngPartList
Set rngPartList = ActiveSheet.Range(CellRange)
    FileList FolderPath, 0
      
    For Each rngPartNo In rngPartList
    If rngPartNo.Value = "" Then GoTo BlankCell
        j = 0
        For i = 1 To MyFiles.Count
            If InStr(1, MyFiles.Item(i)(1), rngPartNo, vbTextCompare) > 0 Then
            If rngPartNo.Cells.Offset(j, 1).Value <> "" Then j = j + 1
              If j > 0 Then Rows(rngPartNo.Row + j).Insert
              ActiveSheet.Hyperlinks.Add Anchor:=rngPartNo.Offset(j, 1), Address:=MyFiles.Item(i)(0), TextToDisplay:=MyFiles.Item(i)(1)
            End If
        Next i
BlankCell:
    Next rngPartNo
    Set MyFiles = Nothing
    
Columns(PartNoColumn & ":" & PartNoColumn).Offset(0, 1).AutoFit
    
End Sub
Sub FileList(MyPath, counter)

Dim fso, folder, SubFolders, subfolder, file
    
    On Error Resume Next
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.getfolder(MyPath)
    If counter = 0 Then
        For Each file In folder.Files
            MyFiles.Add Array(file, file.Name)
        Next file
    End If
    Set SubFolders = folder.SubFolders
    For Each subfolder In SubFolders
        For Each file In subfolder.Files
            MyFiles.Add Array(file, file.Name)
        Next file
        FileList subfolder, 1
    Next
    
    
End Sub
 
Upvote 0

Forum statistics

Threads
1,216,522
Messages
6,131,146
Members
449,626
Latest member
Stormythebandit

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