I have patched together the following code and it almost does what I need. In short, I need to find any row that contains data for a person and paste the whole row to an output spreadsheet. The remaining problem I have is in the comments for the last subroutine. I want to paste both the Format (date, number, money, text) and the Values into the target spreadsheet but what I have now produces #REF! for any formula referencing another spreadsheet.
I patched together the following tasks from forums around the net:
1 – Load a tag file list of names into an array
2 – Pull all files in all subdirectories to be searched sequentially/recursively (since my files don’t have multiple worksheets, I didn’t try to include that loop)
3 – Select rows that contain names of interest
4 – Paste the rows to an output sheet accompanied by identifying filename and tag reference
The last task also needs a pastevalues result but I can’t figure out a syntax that will work with rows inside a loop.
Since this program loops through (many files X many rows X many names), it will take many hours to complete. Any suggestions to increase efficiency or correct bad programming methods are welcome. I know some of my code is kludgey but that’s what my random stumbling forced to work so far. I have a similar VBS that does this task for text files but VBA seems a little slower in simple two-file tests so far and all this work will be for nothing if it needs more than overnight to produce results.
Public SearchList(20, 4) As Variant Public SearchLimit Sub CombineFiles() Application.AskToUpdateLinks = False Application.DisplayAlerts = False Set wTarget = ThisWorkbook.ActiveSheet TargetName = ActiveWorkbook.Name ‘ Dialog for search directory Application.FileDialog(msoFileDialogFolderPicker).Show oDirectory = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1) oFile = Dir(oDirectory & “*.xls*”) Set FSO = CreateObject(“Scripting.FileSystemObject”) Set sFolder = FSO.GetFolder(oDirectory) ‘ Dialog for Tag file With Application.FileDialog(msoFileDialogFilePicker) .AllowMultiSelect = False .Show ‘ Display path of file selected MsgBox “You have selected ” & .SelectedItems(1) TagFile = .SelectedItems(1) End With ‘read Tag file into array SearchLimit = UBound(SearchList, 1) SearchCounter = 0 Set Search_File = FSO.OpenTextFile(TagFile) Do Until Search_File.AtEndOfStream SearchCounter = SearchCounter + 1 If SearchCounter > SearchLimit Then MsgBox (“table greater than ” & SearchLimit) CurLine = Search_File.ReadLine SearchLine = Split(CurLine, “,”, -1, 1) SearchList(SearchCounter, 1) = SearchLine(0) SearchList(SearchCounter, 2) = SearchLine(1) SearchList(SearchCounter, 3) = SearchLine(2) SearchList(SearchCounter, 4) = SearchLine(3) testemail = “.com” If InStr(SearchList(SearchCounter, 3), testemail) = 0 Then SearchList(SearchCounter, 3) = “impossible@none.com” End If Loop SearchLimit = SearchCounter Search_File.Close MsgBox SearchLimit & ” search list items” ‘process files in Directory then process subdirectories For Each File In sFolder.Files ‘process spreadsheet Call SearchSheet(File) Next Call RecurseSubDir(oDirectory) ‘end Application.AskToUpdateLinks = True Application.DisplayAlerts = True MsgBox (“DONE”) End Sub Sub RecurseSubDir(Folder) Set rFSO = CreateObject(“Scripting.FileSystemObject”) Set rFolder = rFSO.GetFolder(Folder) For Each rSubfolder In rFolder.SubFolders Set rFolder = rFSO.GetFolder(rSubfolder.Path) For Each File In rFolder.Files ‘process spreadsheet Call SearchSheet(File) Next Call RecurseSubDir(rSubfolder) Next End Sub Sub SearchSheet(sFile) If Right(sFile, 4) = “.xls” Or Right(sFile, 5) = “.xlsx” Then Set wTarget = ThisWorkbook.ActiveSheet lMaxTargetRow = wTarget.Cells(65536, 1).End(xlUp).Row Set wbkSource = Workbooks.Open(sFile) Set wSource = wbkSource.ActiveSheet lMaxSourceRow = wSource.Cells(65536, 1).End(xlUp).Row ‘force values for everything ‘ With wSource.UsedRange ‘ .Copy ‘ .PasteSpecial xlPasteValues ‘ End With ‘copy everything ‘ wSource.Range(“1:” & lMaxSourceRow).Copy _ ‘ Destination:=wTarget.Cells(lMaxTargetRow + 1, 1) ‘ MsgBox wTarget.Name & ” ” & lMaxSourceRow & ” ” & lMaxTargetRow For sRow = 1 To lMaxSourceRow TagFound = “NG” For SRCHcount = 1 To SearchLimit target1 = SearchList(SRCHcount, 1) target2 = SearchList(SRCHcount, 2) target3 = SearchList(SRCHcount, 3) Set Found1 = wSource.Rows(sRow).Find(what:=target1, LookIn:=xlValues, lookat:=xlPart, MatchCase:=False) Set Found2 = wSource.Rows(sRow).Find(what:=target2, LookIn:=xlValues, lookat:=xlPart, MatchCase:=False) Set Found3 = wSource.Rows(sRow).Find(what:=target3, LookIn:=xlValues, lookat:=xlPart, MatchCase:=False) If (Not Found1 Is Nothing And Not Found2 Is Nothing) Or Not Found3 Is Nothing Then TagFound = SearchList(SRCHcount, 4) LastCol = wSource.Cells(sRow, Columns.Count).End(xlToLeft).Column wSource.Rows(sRow).Copy Destination:=wTarget.Rows(lMaxTargetRow + 1) ‘these commented lines have invalid syntax ‘ wSource.Range(Cells(sRow, 1), Cells(sRow, LastCol)).Copy Destination:=wTarget.Range(Cells(lMaxTargetRow + 1, 1), Cells(lMaxTargetRow + 1, LastCol)).PasteSpecial Paste:=xlPasteValues ‘ wTarget.Rows(lMaxTargetRow + 1).PasteSpecial Paste:=xlPasteValues ‘ wTarget.Rows(lMaxTargetRow + 1).Select ‘ Selection.PasteSpecial Paste:=xlPasteValues wTarget.Cells(lMaxTargetRow + 1, 1).Insert Shift:=xlToRight wTarget.Cells(lMaxTargetRow + 1, 2).Insert Shift:=xlToRight wTarget.Cells(lMaxTargetRow + 1, 1) = sFile wTarget.Cells(lMaxTargetRow + 1, 2) = TagFound lMaxTargetRow = lMaxTargetRow + 1 End If If TagFound “NG” Then Exit For Next Next wbkSource.Close End If End Sub