I think I have it sorted now. it was a bit sneaky, and it hasn't reappeared in a number of test I did subsequently. I also found a few other minor bugs....
I put a timer in the final product to see where it was using most and in what ratio. The four times shown (first msgbox is first time run, clear spreadsheet on 1500 files in 244 directories, on directory with 600 files, the 2nd msgbox is the same directory structure on a second run) are:
- start-up, preparing arrays & ranges
- filling arrays with file structure
- printing to screen
- setting hyperlinks
so as expected going through the tree takes most time, nearly 2 seconds on my harddrive. the rest is negligable
OK, here goes:
<font face=Courier New> <SPAN style="color:#00007F">Dim</SPAN> t <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Integer</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> CheckPath <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> aFD <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>, aHypL <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br><br><SPAN style="color:#00007F">Sub</SPAN> GetDirectory()<br> Application.Calculation = xlCalculationManual<br> <SPAN style="color:#00007F">Dim</SPAN> Msg <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Byte</SPAN>, lR <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lC <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> NewItem <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Boolean</SPAN>, NewDir <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Boolean</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> aOld <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> wsReg <SPAN style="color:#00007F">As</SPAN> Worksheet, rOut <SPAN style="color:#00007F">As</SPAN> Range<br> <br> CheckPath = "O:\Timesheets and Forms\2013 Timesheets\Test Folder"<br> <SPAN style="color:#00007F">If</SPAN> CheckPath = "" <SPAN style="color:#00007F">Then</SPAN><br> MsgBox "No folder was selected. Procedure aborted.", vbExclamation, "StaffSmart Add-In"<br> <SPAN style="color:#00007F">Exit</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> Application.ScreenUpdating = <SPAN style="color:#00007F">False</SPAN><br> <SPAN style="color:#00007F">Set</SPAN> wsReg = Sheets("Register")<br> <br> <SPAN style="color:#00007F">With</SPAN> wsReg<br> <SPAN style="color:#00007F">Set</SPAN> rOut = .Range("A3").CurrentRegion <SPAN style="color:#007F00">' header row of table</SPAN><br> <br> <SPAN style="color:#007F00">' load entire existing page in array</SPAN><br> <SPAN style="color:#00007F">If</SPAN> rOut.Cells.Count = 1 <SPAN style="color:#00007F">Then</SPAN><br> aOld = rOut.Resize(3, 3) <SPAN style="color:#007F00">' arbitrary size to avoid crash</SPAN><br> <SPAN style="color:#00007F">Else</SPAN><br> aOld = rOut<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">With</SPAN> .Range("A1")<br> .Value = CheckPath<br> .Font.Bold = <SPAN style="color:#00007F">True</SPAN><br> .Font.Size = 12<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">With</SPAN><br> <SPAN style="color:#007F00">'initialise column counter for the arrays</SPAN><br> t = 1<br> <SPAN style="color:#007F00">' make filelist array and hyperlink array same size but a bit larger as aOld to start of with, _<br> so only needs to be resized for large number additional files or directories, as this is a pain</SPAN><br> <SPAN style="color:#00007F">ReDim</SPAN> aFD(1 <SPAN style="color:#00007F">To</SPAN> 500 + <SPAN style="color:#00007F">UBound</SPAN>(aOld, 1), 1 <SPAN style="color:#00007F">To</SPAN> 20 + <SPAN style="color:#00007F">UBound</SPAN>(aOld, 2))<br> <SPAN style="color:#00007F">ReDim</SPAN> aHypL(1 <SPAN style="color:#00007F">To</SPAN> 500 + <SPAN style="color:#00007F">UBound</SPAN>(aOld, 1), 1 <SPAN style="color:#00007F">To</SPAN> 20 + <SPAN style="color:#00007F">UBound</SPAN>(aOld, 2))<br> <br> ListFilesInFolder CheckPath<br> <br> <SPAN style="color:#007F00">' list all files included subfolders</SPAN><br> .Range("A3").Resize(1, .Range("A3").End(xlToRight).Column).Font.Bold = <SPAN style="color:#00007F">True</SPAN><br> <SPAN style="color:#007F00">' print array to sheet</SPAN><br> <SPAN style="color:#00007F">Set</SPAN> rOut = .Range("a3").Resize(UBound(aFD, 1), <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2))<br> rOut.Value = aFD<br> <br> <SPAN style="color:#007F00">' set hyperlinks</SPAN><br> <SPAN style="color:#00007F">Set</SPAN> rOut = .Range("a3")<br> <SPAN style="color:#00007F">For</SPAN> lC = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2)<br> NewDir = <SPAN style="color:#00007F">False</SPAN><br> <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1)<br> <SPAN style="color:#007F00">' check wich names need hyperlink renewed</SPAN><br> <SPAN style="color:#00007F">If</SPAN> Len(aFD(lR, lC)) <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#007F00">'only check if file</SPAN><br> <SPAN style="color:#00007F">If</SPAN> lR > <SPAN style="color:#00007F">UBound</SPAN>(aOld, 1) <SPAN style="color:#00007F">Or</SPAN> lC > <SPAN style="color:#00007F">UBound</SPAN>(aOld, 2) <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#007F00">' additional files outside old range</SPAN><br> NewItem = <SPAN style="color:#00007F">True</SPAN><br> <SPAN style="color:#00007F">ElseIf</SPAN> aOld(lR, lC) <> aFD(lR, lC) <SPAN style="color:#00007F">Then</SPAN> <SPAN style="color:#007F00">' if name different</SPAN><br> NewItem = <SPAN style="color:#00007F">True</SPAN><br> <SPAN style="color:#00007F">If</SPAN> lR = 1 <SPAN style="color:#00007F">Then</SPAN> NewDir = <SPAN style="color:#00007F">True</SPAN> <SPAN style="color:#007F00">' new directory</SPAN><br> <SPAN style="color:#007F00">' NewDir is used to flag up that the directory is different</SPAN><br> <SPAN style="color:#007F00">' so all links in column have to be renewed (there can be a same name file in two dirs)</SPAN><br> <SPAN style="color:#00007F">Else</SPAN><br> NewItem = <SPAN style="color:#00007F">False</SPAN><br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">If</SPAN> (NewItem <SPAN style="color:#00007F">Or</SPAN> NewDir) And lR > 1 <SPAN style="color:#00007F">Then</SPAN><br> Worksheets("Register").Hyperlinks.Add Anchor:=rOut.Offset(lR - 1, lC - 1), Address:=aHypL(lR, lC)<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">ElseIf</SPAN> lR < <SPAN style="color:#00007F">UBound</SPAN>(aOld, 1) And lC < UBound(aOld, 2) <SPAN style="color:#00007F">Then</SPAN><br> <SPAN style="color:#007F00">' check if less files in directory, delete hyperlinks</SPAN><br> <SPAN style="color:#00007F">If</SPAN> Len(aOld(lR, lC)) <SPAN style="color:#00007F">Then</SPAN><br> rOut.Offset(lR - 1, lC - 1).Resize(<SPAN style="color:#00007F">UBound</SPAN>(aOld, 1), 1).Clear<br> <SPAN style="color:#00007F">Dim</SPAN> lRO <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br> <SPAN style="color:#007F00">' clear rest of column in aOld as we need to do this only once</SPAN><br> <SPAN style="color:#00007F">For</SPAN> lRO = lR <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aOld, 1)<br> aOld(lRO, lC) = ""<br> <SPAN style="color:#00007F">Next</SPAN> lRO<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">Next</SPAN> lR<br> <SPAN style="color:#00007F">Next</SPAN> lC<br> .Range("a4").Select<br> ActiveWindow.FreezePanes = <SPAN style="color:#00007F">True</SPAN><br> .Range("a3").Sort Key1:=.Range("A4"), Order1:=xlAscending, Header:=xlYes<br> .Range("a3").Select<br> ActiveWindow.LargeScroll Up:=100<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">With</SPAN><br> Application.ScreenUpdating = <SPAN style="color:#00007F">True</SPAN><br> Application.Calculation = xlCalculationAutomatic<br><SPAN style="color:#007F00">' MsgBox "Done", vbOKOnly, "StaffSmart Add-In"</SPAN><br><br><br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br><SPAN style="color:#00007F">Private</SPAN> <SPAN style="color:#00007F">Sub</SPAN> ListFilesInFolder(SourceFolderName <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN>)<br><SPAN style="color:#007F00">' lists information about the files in SourceFolder</SPAN><br><SPAN style="color:#007F00">' example: ListFilesInFolder "C:\FolderName\", True</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> FSO <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Object</SPAN> <SPAN style="color:#007F00">'Scripting.FileSystemObject</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> SourceFolder <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Object</SPAN> <SPAN style="color:#007F00">'Scripting.Folder</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> SubFolder <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Object</SPAN> <SPAN style="color:#007F00">'Scripting.Folder</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> FileItem <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Object</SPAN> <SPAN style="color:#007F00">'Scripting.File</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> r <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> strAddress <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> strDisplayText <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN><br> <br> <SPAN style="color:#00007F">Set</SPAN> FSO = CreateObject("Scripting.FileSystemObject")<br> <SPAN style="color:#00007F">Set</SPAN> SourceFolder = FSO.GetFolder(SourceFolderName)<br> r = 2 <SPAN style="color:#007F00">'first row for the file list</SPAN><br><br> <SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Each</SPAN> SubFolder <SPAN style="color:#00007F">In</SPAN> SourceFolder.SubFolders<br> ListFilesInFolder SubFolder.path<br> t = t + 1<br> <SPAN style="color:#00007F">If</SPAN> t > <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2) <SPAN style="color:#00007F">Then</SPAN><br> <SPAN style="color:#007F00">' redim aFD & HypL</SPAN><br> <SPAN style="color:#007F00">' this can be done using Redim Preserve</SPAN><br> <SPAN style="color:#007F00">' Add 20 columns for some reserve</SPAN><br> <br> <SPAN style="color:#00007F">ReDim</SPAN> <SPAN style="color:#00007F">Preserve</SPAN> aFD(1 <SPAN style="color:#00007F">To</SPAN> UBound(aFD, 1), 1 <SPAN style="color:#00007F">To</SPAN> (<SPAN style="color:#00007F">UBound</SPAN>(aFD, 2) + 20))<br> <SPAN style="color:#00007F">ReDim</SPAN> <SPAN style="color:#00007F">Preserve</SPAN> aHypL(1 <SPAN style="color:#00007F">To</SPAN> UBound(aHypL, 1), 1 <SPAN style="color:#00007F">To</SPAN> (<SPAN style="color:#00007F">UBound</SPAN>(aHypL, 2) + 20))<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">Next</SPAN> <SPAN style="color:#00007F">Sub</SPAN>Folder<br> <br> <SPAN style="color:#007F00">' put subfolder name in first row</SPAN><br> aFD(1, t) = Right(SourceFolder.path, Len(SourceFolder.path) - Len(CheckPath))<br> <SPAN style="color:#00007F">If</SPAN> Len(aFD(1, t)) = 0 <SPAN style="color:#00007F">Then</SPAN> aFD(1, t) = "\"<br><br> <SPAN style="color:#00007F">For</SPAN> <SPAN style="color:#00007F">Each</SPAN> FileItem <SPAN style="color:#00007F">In</SPAN> SourceFolder.Files<br> <SPAN style="color:#007F00">' display file properties</SPAN><br> aFD(r, t) = FileItem.Name<br> aHypL(r, t) = FileItem.ParentFolder.path & "\" & FileItem.Name<br> r = r + 1 <SPAN style="color:#007F00">' next row number</SPAN><br> <SPAN style="color:#00007F">If</SPAN> r > <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1) <SPAN style="color:#00007F">Then</SPAN><br> <SPAN style="color:#007F00">' redim aFD & aHypL, add 500 rows</SPAN><br> <SPAN style="color:#007F00">' Redim Preserve cannot be used to change nr of rows</SPAN><br> <SPAN style="color:#007F00">' so copy to temp arrays and then increase size and</SPAN><br> <SPAN style="color:#007F00">' copy back</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> aTemp1 <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN>, aTemp2 <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Variant</SPAN><br> <SPAN style="color:#00007F">Dim</SPAN> lR <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, lC <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br> <SPAN style="color:#00007F">ReDim</SPAN> aTemp1(1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1), 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2))<br> <SPAN style="color:#00007F">ReDim</SPAN> aTemp2(1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1), 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2))<br> <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1)<br> <SPAN style="color:#00007F">For</SPAN> lC = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2)<br> aTemp1(lR, lC) = aFD(lR, lC)<br> aTemp2(lR, lC) = aHypL(lR, lC)<br> <SPAN style="color:#00007F">Next</SPAN> lC<br> <SPAN style="color:#00007F">Next</SPAN> lR<br> <SPAN style="color:#00007F">ReDim</SPAN> aFD(1 <SPAN style="color:#00007F">To</SPAN> (500 + <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1)), 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2))<br> <SPAN style="color:#00007F">ReDim</SPAN> aHypL(1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 1), 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aFD, 2))<br> <SPAN style="color:#00007F">For</SPAN> lR = 1 <SPAN style="color:#00007F">To</SPAN> <SPAN style="color:#00007F">UBound</SPAN>(aTemp1, 1)<br> <SPAN style="color:#00007F">For</SPAN> lC = 1 <SPAN style="color:#00007F">To</SPAN> UBound(aTemp1, 2)<br> aFD(lR, lC) = aTemp1(lR, lC)<br> aHypL(lR, lC) = aTemp2(lR, lC)<br> <SPAN style="color:#00007F">Next</SPAN> lC<br> <SPAN style="color:#00007F">Next</SPAN> lR<br> <SPAN style="color:#00007F">ReDim</SPAN> aTemp1(1, 1)<br> <SPAN style="color:#00007F">ReDim</SPAN> aTemp2(1, 1)<br> <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br> <SPAN style="color:#00007F">Next</SPAN> FileItem<br> <SPAN style="color:#00007F">Set</SPAN> FileItem = <SPAN style="color:#00007F">Nothing</SPAN><br> <SPAN style="color:#00007F">Set</SPAN> SourceFolder = <SPAN style="color:#00007F">Nothing</SPAN><br> <SPAN style="color:#00007F">Set</SPAN> FSO = <SPAN style="color:#00007F">Nothing</SPAN><br><SPAN style="color:#00007F">End</SPAN> Sub</FONT>