How to end this loop? - vba

I currently have a VBA Code written to ask for a users input of a string as well as a certain directory, and it searches through each folder, subfolder, workbook and worksheets until it finds the string the user put in. The issue I'm running into is that after it finds the string, it continues to search the rest of the folders. The application I'll be using this in, there is only one of that string being searched. I have tried debugging, and using an if statement with "c" to match str but it keeps throwing an error. The code is attached below, any help is appreciated.
Public WS As Worksheet
Sub SearchWKBooksSubFolders(Optional Folderpath As Variant, Optional Str As Variant)
Dim myfolder As String
Dim a As Single
Dim sht As Worksheet
Dim Lrow As Single
Dim Folders() As String
Dim Folder As Variant
ReDim Folders(0)
If IsMissing(Folderpath) Then
Set WS = Sheets.Add
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
myfolder = .SelectedItems(1) & "\"
End With
Str = Application.InputBox(prompt:="Search string:", Title:="Search all workbooks in a folder", Type:=2)
If Str = "" Then Exit Sub
WS.Range("A1") = "Search string:"
WS.Range("B1") = Str
WS.Range("A2") = "Path:"
WS.Range("B2") = myfolder
WS.Range("A3") = "Folderpath"
WS.Range("B3") = "Workbook"
WS.Range("C3") = "Worksheet"
WS.Range("D3") = "Cell Address"
WS.Range("E3") = "Link"
Folderpath = myfolder
Value = Dir(myfolder, &H1F)
Else
If Right(Folderpath, 2) = "\\" Then
Exit Sub
End If
Value = Dir(Folderpath, &H1F)
End If
Do Until Value = ""
If Value = "." Or Value = ".." Then
Else
If GetAttr(Folderpath & Value) = 16 Then
Folders(UBound(Folders)) = Value
ReDim Preserve Folders(UBound(Folders) + 1)
ElseIf (Right(Value, 3) = "xls" Or Right(Value, 4) = "xlsx" Or Right(Value, 4) = "xlsm") And Left(Value, 1) <> "~" Then
On Error Resume Next
Dim wb As Workbook
Set wb = Workbooks.Open(Filename:=Folderpath & Value, Password:="zzzzzzzzzzzz")
On Error GoTo 0
'If there is an error on Workbooks.Open, then wb Is Nothing:
If wb Is Nothing Then
Lrow = WS.Range("A" & Rows.Count).End(xlUp).Row + 1
WS.Range("A" & Lrow).Value = Value
WS.Range("B" & Lrow).Value = "Password protected"
Else
For Each sht In wb.Worksheets
'Expand all groups in sheet
sht.Unprotect
sht.Outline.ShowLevels RowLevels:=8, ColumnLevels:=8
Set c = sht.Cells.Find(Str, After:=sht.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not c Is Nothing Then
firstAddress = c.Address
Do
Lrow = WS.Range("A" & Rows.Count).End(xlUp).Row + 1
WS.Range("A" & Lrow).Value = Folderpath
WS.Range("B" & Lrow).Value = Value
WS.Range("C" & Lrow).Value = sht.Name
WS.Range("D" & Lrow).Value = c.Address
WS.Hyperlinks.Add Anchor:=WS.Range("E" & Lrow), Address:=Folderpath & Value, SubAddress:= _
"'" & sht.Name & "'" & "!" & c.Address, TextToDisplay:="Link"
Set c = sht.Cells.FindNext(After:=c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
Next sht
wb.Close False
End If
End If
End If
Value = Dir
Loop
For Each Folder In Folders
Call SearchWKBooksSubFolders(Folderpath & Folder & "\", Str)
Next Folder
Cells.EntireColumn.AutoFit
End Sub

Add a boolean variable that you set to True to indicate that you've found what you're looking for. Something like this:
Sub SearchWKBooksSubFolders(Optional Folderpath As Variant, Optional Str As Variant)
Dim myfolder As String
Dim a As Single
Dim sht As Worksheet
Dim Lrow As Single
Dim Folders() As String
Dim Folder As Variant
ReDim Folders(0)
If IsMissing(Folderpath) Then
Set WS = Sheets.Add
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
myfolder = .SelectedItems(1) & "\"
End With
Str = Application.InputBox(prompt:="Search string:", Title:="Search all workbooks in a folder", Type:=2)
If Str = "" Then Exit Sub
WS.Range("A1") = "Search string:"
WS.Range("B1") = Str
WS.Range("A2") = "Path:"
WS.Range("B2") = myfolder
WS.Range("A3") = "Folderpath"
WS.Range("B3") = "Workbook"
WS.Range("C3") = "Worksheet"
WS.Range("D3") = "Cell Address"
WS.Range("E3") = "Link"
Folderpath = myfolder
value = Dir(myfolder, &H1F)
Else
If Right(Folderpath, 2) = "\\" Then
Exit Sub
End If
value = Dir(Folderpath, &H1F)
End If
'---Add this:
Dim TimeToStop As Boolean
'---Change this:
Do Until TimeToStop
If value = "." Or value = ".." Then
Else
If GetAttr(Folderpath & value) = 16 Then
Folders(UBound(Folders)) = value
ReDim Preserve Folders(UBound(Folders) + 1)
ElseIf (Right(value, 3) = "xls" Or Right(value, 4) = "xlsx" Or Right(value, 4) = "xlsm") And Left(value, 1) <> "~" Then
On Error Resume Next
Dim wb As Workbook
Set wb = Workbooks.Open(fileName:=Folderpath & value, Password:="zzzzzzzzzzzz")
On Error GoTo 0
'If there is an error on Workbooks.Open, then wb Is Nothing:
If wb Is Nothing Then
Lrow = WS.Range("A" & Rows.Count).End(xlUp).Row + 1
WS.Range("A" & Lrow).value = value
WS.Range("B" & Lrow).value = "Password protected"
Else
For Each sht In wb.Worksheets
'Expand all groups in sheet
sht.Unprotect
sht.Outline.ShowLevels RowLevels:=8, ColumnLevels:=8
Set c = sht.Cells.Find(Str, After:=sht.Cells(1, 1), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not c Is Nothing Then
'---Add this
TimeToStop = True 'since we found what we're looking for
firstAddress = c.Address
Do
Lrow = WS.Range("A" & Rows.Count).End(xlUp).Row + 1
WS.Range("A" & Lrow).value = Folderpath
WS.Range("B" & Lrow).value = value
WS.Range("C" & Lrow).value = sht.Name
WS.Range("D" & Lrow).value = c.Address
WS.Hyperlinks.Add Anchor:=WS.Range("E" & Lrow), Address:=Folderpath & value, SubAddress:= _
"'" & sht.Name & "'" & "!" & c.Address, TextToDisplay:="Link"
Set c = sht.Cells.FindNext(After:=c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
Next sht
wb.Close False
End If
End If
End If
value = Dir
'---Add these 3 lines
If Len(value) = 0 Then
TimeToStop = True
End If
Loop
For Each Folder In Folders
Call SearchWKBooksSubFolders(Folderpath & Folder & "\", Str)
Next Folder
Cells.EntireColumn.AutoFit
End Sub
Do note that you're calling your routine recursively:
For Each Folder In Folders
Call SearchWKBooksSubFolders(Folderpath & Folder & "\", Str)
Next Folder
Once you've gone through all your searching routine, you're going to start all over again because you're calling your Sub from within your Sub. Don't know if this is what you're after, and it may be an additional cause of further unexpected looping.

"If Str = c.Value Then GoTo 85"
Change to
"If Str = c.Value Then End"

Related

Create folders using 2 column values from Excel

So I need to make a whole bunch of folders from a spreadsheet.
I have in column A the Surname and in Column B the name of a person, I need to generate folders based on this.
I have found a bit of code that someone else posted, that works, but I need to add a space between the name and surname in the created folder.
The original poster said that they did manage to add a space, but never indicated how.
Sub MakeFoldersForEachRow()
Dim Rng As Range
Dim maxRows, maxCols, r, c As Integer
Dim s As String
Set Rng = Selection
maxRows = Rng.Rows.Count
maxCols = Rng.Columns.Count
For r = 1 To maxRows
s = ""
For c = 1 To maxCols
s = s & Rng(r, c)
Next c
If Len(Dir(ActiveWorkbook.Path & "\" & s, vbDirectory)) = 0 Then
MkDir (ActiveWorkbook.Path & "\" & s)
On Error Resume Next
End If
Next r
End Sub
Please, try the next code:
Sub createFoldNamesFromTwoColumns()
Dim sh As Worksheet, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet 'use here your necessary sheet
lastR = sh.Range("A" & sh.Rows.count).End(xlUp).row
For i = 1 To lastR
fldName = sh.Range("A" & i) & " " & sh.Range("B" & i)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub
Edited:
I could see now your last request, meaning to process the selected columns:
Sub createFoldNamesFromTwoSelectedColumns()
Dim sh As Worksheet, rngSel As Range, C1 As Long, lastR As Long, fldName As String, i As Long
Set sh = ActiveSheet
Set rngSel = Selection
If rngSel.Columns.count <> 2 Then MsgBox "You must select two columns!": Exit Sub
C1 = rngSel.cells(1).Column: Stop
lastR = sh.cells(sh.Rows.count, C1).End(xlUp).row
For i = 1 To lastR
fldName = sh.cells(i, C1) & " " & sh.cells(i, C1 + 1)
If Dir(ActiveWorkbook.Path & "\" & fldName, vbDirectory) = "" Then
MkDir ActiveWorkbook.Path & "\" & fldName
End If
Next i
End Sub

VBA - Run time Error '91' Object variable or with block variable not set

I have created a file which I run multiple macros (for example 5). Everything works when I run all macros and I shared the file to a colleague (A) who said it works good. But when colleague (A) share to colleague (B), they encountered this error.
Can you please guide me on where I have been wrong?
Sub CaseListing()
Dim wbSource As Workbook, lastRow As Long
Application.ScreenUpdating = False
ThisWorkbook.Sheets("SR - Information").Range("A2:B1048576").Clear
Set wbSource = Workbooks.Open(Filename:="https://*/All_Region_Case_List_CURRENT.xlsx", UpdateLinks:=False, ReadOnly:=True)
lastRow = wbSource.Sheets("Sheet1").Range("B" & Rows.Count).End(xlUp).Row
wbSource.Activate
Range("B4:B" & lastRow & ",K4:K" & lastRow).Copy ThisWorkbook.Sheets("SR - Information").Range("A2")
wbSource.Close
With ThisWorkbook.Sheets("SR - Information").Range("A1:A" & Range("A" & Rows.Count).End(xlDown).Row)
.NumberFormat = "General"
.Value = .Value
End With
ThisWorkbook.Sheets("SR - Information").Range("E1") = "<-- last refreshed on " & Now()
Application.ScreenUpdating = True
End Sub
EMAIL
Public wsSR As Worksheet
Sub CreateEmail()
Dim TempFilePath As String, TempFileName As String, FileExtStr As String, myFile As String
Dim LastCell As Long, endR As Long
Dim Fname As String, Lname As String, EmailAddress As String
Dim ol As Outlook.Application
Dim mi As Outlook.MailItem
Dim c1, c2 As Collection, msg As String, i As Variant
Set wbMe = ThisWorkbook
Set wsBW = wbMe.Sheets("B+W")
Set wsSR = wbMe.Sheets("SR - Information")
Set wsFinal = wbMe.Sheets("Report")
Set wsCNA = ThisWorkbook.Sheets("C+N ")
Set wsWebCNA = ThisWorkbook.Sheets("Web")
Set c1 = New Collection
Set c2 = New Collection
pwd = "abc"
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
wsFinal.Unprotect pwd
'Clear and Copy to the Final sheet
wsFinal.Range("A5:V1048576").Clear
LastCell = wsBW.Range("A" & Rows.Count).End(xlUp).Row
wsBW.Range("A4:V" & LastCell).Copy
wsFinal.Range("A4").PasteSpecial Paste:=xlPasteValues
Set wsSR = ThisWorkbook.Sheets("SR - Information")
endR = wsSR.Range("Q" & Rows.Count).End(xlUp).Row
wsSR.Visible = False
wsBW.Visible = False
wsCNA.Visible = False
wsWebCNA.Visible = False
wsFinal.Range("A4:V" & Cells(Rows.Count, 1).End(xlUp).Row).Columns.AutoFit
Set ol = New Outlook.Application
Set mi = ol.CreateItem(olMailItem)
For Each cel In Sheets("SR - Information").Range("Q2:Q" & endR).Cells
wsFinal.Activate
wsFinal.Unprotect pwd
Range("A4:V" & Cells(Rows.Count, 22).End(xlUp).Row).AutoFilter Field:=22, Criteria1:=cel ', visibledropdown:=False
Set IndxLookupRange = Sheets("SR - Information").Range("H:I")
Set Matchlookuprange = Sheets("SR - Information").Range("H:H")
cel.Offset(0, 1) = Application.WorksheetFunction.IfError(Application.Index(IndxLookupRange, Application.Match(cel, Matchlookuprange, 0), 2), "-")
EmailAddress = cel.Offset(0, 1)
'Temporary file details
TempFilePath = Environ$("temp") & "\"
TempFileName = " Report - " & Format(Now, "mmmm dd, yyyy")
FileExtStr = "." & LCase(Right(ThisWorkbook.Name, Len(ThisWorkbook.Name) - InStrRev(ThisWorkbook.Name, ".", , 1)))
If EmailAddress <> "-" Then
For Each oAccount In ol.Session.Accounts
If oAccount = "pqrs.abc#xyz.com" Then 'BD_Best_Practice
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
'Get the file ready - protection and hide
wsBW.protect pwd
wbMe.protect Password:=pwd, Structure:=True, Windows:=True
'Keep the desired sheet activate and save as temp file
wsFinal.Activate
wsFinal.protect pwd
wbMe.SaveCopyAs TempFilePath & TempFileName & FileExtStr
On Error Resume Next
With OutMail
.To = EmailAddress
.CC = ""
.BCC = ""
.Subject = " Report" '& Format(Now, "mmmm dd, yyyy") '" & Fname & "," & "<br> <br> "
.HTMLBody = "<BODY style='font-family:Calibri; font-size:11pt';>Hi, <br><br>" & _
"Please find the attached the Report. This report shows your Plan Sponsor's Enhanced Access user activity." & _
"<br> <br> Thank you, <br> xyz" & Range("F3") & "</font></BODY>"
.Attachments.Add TempFilePath & TempFileName & FileExtStr
Set .SendUsingAccount = oAccount
'.Display
.send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End If
Next oAccount
'Delete the temp file
Kill TempFilePath & TempFileName & FileExtStr
Else
c1.Add cel, CStr(cel)
c2.Add cel, CStr(cel)
End If
Next cel
wbMe.Unprotect Password:=pwd
wsBW.Visible = True
wsSR.Visible = True
wsCNA.Visible = True
wsWebCNA.Visible = True
If c1.Count = 0 Then
msg = "All Service Reps are matched!"
Range("Q:R").Clear
MsgBox msg
Exit Sub
Else
msg = "Make sure to update the below list of Service Reps information manually!" & vbCrLf
For i = 1 To c1.Count
msg = msg & vbCrLf & c1.Item(i)
Next i
End If
MsgBox msg '& vbCrLf & vbCrLf & "Make sure Service Reps Details are updated manually!"
wsSR.Range("Q:R").Clear
wsBW.Select
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
IMPORTFILES
Public wbMe As Workbook
Public wsBW As Worksheet, wsSR As Worksheet, wsFinal As Worksheet
Public wsBoxi As Worksheet, wsWeb As Worksheet, wsWebCNA As Worksheet, wsNDR As Worksheet
Public pwd As Variant, domain As String
Public wsCNA As Worksheet
Sub ImportFiles()
'PURPOSE: 1 B and 1 W
Dim f, fpath As String
If MsgBox("Is it 2 B and 1 W?", vbYesNo) = vbNo Then
Set wbMe = ThisWorkbook
Set wsBW = wbMe.Sheets("B+W")
Set wsSR = wbMe.Sheets("SR - Information")
Set wsFinal = wbMe.Sheets("Report")
pwd = "abc"
Application.ScreenUpdating = False
wsBW.Unprotect pwd
If wsBW.AutoFilterMode = True Then wsBW.AutoFilterMode = False
wsBW.Range("A4:Y1048576").Clear
wbMe.Unprotect Password:=pwd ', Structure:=False, Windows:=False
wsSR.Visible = True
wsSR.Columns("P:R").Clear
P = wbMe.Sheets.Count
For m = P To 1 Step -1
t = wbMe.Sheets(m).Name
If t <> "B+W" And t <> "SR - Information" And t <> "Report" And t <> "C+ " And t <> "Web" And t <> "NDRs" Then
Application.DisplayAlerts = False
wbMe.Sheets(m).Delete
Application.DisplayAlerts = True
End If
Next m
fpath = GetFolder & "\"
Application.ScreenUpdating = False
If fpath = "\" Then
Exit Sub
Else
f = Dir(fpath)
Do While Len(f) > 0
Select Case Right(f, Len(f) - InStrRev(f, "."))
Case "xls", "xlsx", "csv"
OpenFile (fpath & f)
End Select
f = Dir
Loop
Set wsBoxi = wbMe.Sheets("Sheet1")
Set wsWeb = wbMe.Sheets("GBA Access IDS")
Call Merger
Call Reorder_Columns
'Apply Formats
wsWeb.Range("A1").Copy
wsBW.Range("A4:W4").PasteSpecial xlFormats
wsBW.Rows("4:4").Columns.AutoFit
Application.CutCopyMode = False
Range("A4").Select
P = wbMe.Sheets.Count
For m = P To 1 Step -1
t = wbMe.Sheets(m).Name
If t <> "BOXI+WEB" And t <> "SR - Information" And t <> "Report" And t <> "C+N " And t <> "Web" And t <> "NDRs" Then
Application.DisplayAlerts = False
wbMe.Sheets(m).Delete
Application.DisplayAlerts = True
End If
Next m
wsBW.Range("$A$4:$U$1048576").AutoFilter Field:=1, Criteria1:="C ", Operator:=xlOr, Criteria2:="N "
MsgBox "Merge Successful!"
Application.ScreenUpdating = True
End If
Else
Call LoopAllFilesInFolder
End If
End Sub
Function GetFolder() As String
Dim f As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select multiple Files"
.AllowMultiSelect = False
.InitialFileName = ThisWorkbook.Path
If .Show <> -1 Then GoTo There
f = .SelectedItems(1)
End With
There:
GetFolder = f
End Function
Private Sub OpenFile(filepath)
Dim sh, wb As Workbook
Set wb = Workbooks.Open(filepath)
'Debug.Print filepath
For Each sh In wb.Sheets
sh.Copy After:=wbMe.Sheets(wbMe.Sheets.Count)
Next sh
wb.Close False
End Sub
Private Sub Merger()
Dim lastRow As Long
wsBoxi.Rows("2:2").EntireRow.Delete
wsWeb.Rows("1:2").EntireRow.Delete
'Reorder BOXI columns
wsBoxi.Columns("D:D").Cut
wsBoxi.Columns("A:A").Insert Shift:=xlToRight
Set IndexRange = wsBoxi.Range("A:G") 'BOXI
Set MatchLookupRng = wsBoxi.Range("A:A")
lastRow = wsWeb.Range("A" & Rows.Count).End(xlUp).Row
wsWeb.Activate
For Each AdID In wsWeb.Range("E2:E" & lastRow).Cells
Range("P" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 2), "-") 'Market Segment
Range("Q" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 3), "-") 'Region code
Range("R" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 4), "-") 'Cleint#
Range("S" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 5), "-") 'Admin Access Level
Range("T" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 6), "-") 'Admin Location Access
Range("U" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 7), "-") 'Admin Access to all Locations
Next AdID
wsWeb.Range("P1").Value = "Market Segment"
wsWeb.Range("Q1").Value = "Region Code"
wsWeb.Range("R1").Value = "Client#"
wsWeb.Range("S1").Value = "Admin Access Level"
wsWeb.Range("T1").Value = "Admin Location Access"
wsWeb.Range("U1").Value = "Admin Access to all Locations"
wsWeb.Range("A1:U" & lastRow).Copy wsBW.Range("A4")
wsBW.Range("A4:Y1048576").Font.Name = "Calibri"
wsBW.Range("A4:Y1048576").Font.Size = 10
End Sub
Private Sub Reorder_Columns() 'Final Columns
Dim ColumnOrder As Variant, ndx As Integer
Dim Found As Range, counter As Integer
ColumnOrder = Array("Market Segment", "Region Code", "Requestor Access ID", "Requestor Email", "Client#", "Transaction Type", _
"Date Processed", "Admin First Name", "Admin Last Name", "Admin Language", "Admin Email", "Admin Access ID", "Admin Access Level", _
"Admin Location Access", "Admin Access to all Locations", "Changed Admin First Name", "Changed Admin Last Name", "Changed Admin Language", _
"Changed Admin Email", "Changed Admin Access Level", "Changed Admin Location Access")
counter = 1
wsBW.Activate
For ndx = LBound(ColumnOrder) To UBound(ColumnOrder)
Set Found = Rows("4:4").Find(ColumnOrder(ndx), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not Found Is Nothing Then
If Found.Column <> counter Then
Found.EntireColumn.Cut
Columns(counter).Insert Shift:=xlToRight
Application.CutCopyMode = False
End If
counter = counter + 1
End If
Next ndx
Call HighlightPlanAdmin
End Sub
Private Sub HighlightPlanAdmin()
Dim ReqID As Range, nReqID As String, rReqID As String, tType As String, ntType As String
wsBW.Activate
For Each ReqID In Range("C5:C" & Cells(Rows.Count, 1).End(xlUp).Row).Cells
rReqID = Trim(ReqID)
tType = Trim(ReqID.Offset(0, 3)) '"Add Plan Admin"
If tType = "Add Plan Admin" Then
nReqID = Trim(ReqID.Offset(1, 0)) 'Requestor ID next row
If rReqID = nReqID Then
ntType = Trim(ReqID.Offset(1, 3))
If ntType <> "Add Plan Admin to OASIS." Then
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
Else
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
If nReqID = "" Then
ntType = Trim(ReqID.Offset(1, 3))
If ntType = "" Then
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
End If
End If
Next ReqID
End Sub
Sub LoopAllFilesInFolder()
'PURPOSE: 2 B and 1 W. To loop through all Excel files in a user specified folder and perform ...
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set wsBW = ThisWorkbook.Sheets("B+W")
Set wsCNA = ThisWorkbook.Sheets("C+N ")
Set wsWebCNA = ThisWorkbook.Sheets("Web")
Set wsFinal = ThisWorkbook.Sheets("Report")
Set wsSR = ThisWorkbook.Sheets("SR - Information")
wsBW.Unprotect "abc"
If wsBW.AutoFilterMode = True Then wsBW.AutoFilterMode = False
wsSR.Range("Q1:R1048576").Clear
wsBW.Range("A4:Y1048576").Clear
wsCNA.Range("A1:G1048576").Clear
wsWebCNA.Range("A1:Z1048576").Clear
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Select A Target Folder"
.Show
If .SelectedItems.Count <> 0 Then
xDirect = .SelectedItems(1) & "\"
xFname = Dir(xDirect, 7)
Do While xFname <> ""
If InStr(1, xFname, "C ", vbTextCompare) <> 0 Then
Set wb = Workbooks.Open(Filename:=xDirect & xFname)
dendRow = wsCNA.UsedRange.Rows.Count
wb.Worksheets(1).UsedRange.Copy
If dendRow = 1 Then
wsCNA.Range("A" & dendRow).PasteSpecial Paste:=xlPasteValues
Else
wsCNA.Range("A" & dendRow + 1).PasteSpecial Paste:=xlPasteValues
End If
wb.Close
ElseIf InStr(1, xFname, "N ", vbTextCompare) <> 0 Then
Set wb = Workbooks.Open(Filename:=xDirect & xFname)
dendRow = wsCNA.UsedRange.Rows.Count
wb.Worksheets(1).UsedRange.Copy
wsCNA.Range("A" & dendRow + 1).PasteSpecial Paste:=xlPasteValues
wb.Close
ElseIf InStr(1, xFname, "Web", vbTextCompare) <> 0 Then
Set wb = Workbooks.Open(Filename:=xDirect & xFname)
wb.Worksheets(1).UsedRange.Copy
wsWebCNA.Range("A1").PasteSpecial Paste:=xlPasteValues
wb.Close
End If
xFname = Dir
Loop
End If
End With
wsCNA.Activate
For Each cel In wsCNA.Range("A3:A" & Range("A" & Rows.Count).End(xlUp).Row).Cells
If InStr(1, cel, "Market Segment", vbTextCompare) <> 0 Then
cel.Offset(1, 0).EntireRow.Delete
cel.EntireRow.Delete
End If
Next cel
Call MergerFolder
Call Reorder_Columns_Folder
'Apply Formats
wsBW.Range("A4:W4").Font.Bold = True
wsBW.Range("A4:W4").Font.Underline = xlUnderlineStyleSingle
wsBW.Rows("4:4").Columns.AutoFit
Application.CutCopyMode = False
Range("A4").Select
wsBW.Range("$A$4:$U$1048576").AutoFilter Field:=1, Criteria1:="Corporate Accounts", Operator:=xlOr, Criteria2:="N "
MsgBox "Merge Successful!"
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Private Sub MergerFolder()
Dim lastRow As Long
wsCNA.Rows("2:2").EntireRow.Delete
wsWebCNA.Rows("1:2").EntireRow.Delete
'Reorder BOXI columns
wsCNA.Columns("D:D").Cut
wsCNA.Columns("A:A").Insert Shift:=xlToRight
Set IndexRange = wsCNA.Range("A:G") 'BOXI
Set MatchLookupRng = wsCNA.Range("A:A")
lastRow = wsWebCNA.Range("A" & Rows.Count).End(xlUp).Row
wsWebCNA.Activate
For Each AdID In wsWebCNA.Range("E2:E" & lastRow).Cells
Range("P" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 2), "-") 'Market Segment
Range("Q" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 3), "-") 'Region code
Range("R" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 4), "-") 'Cleint#
Range("S" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 5), "-") 'Admin Access Level
Range("T" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 6), "-") 'Admin Location Access
Range("U" & AdID.Row).Value = Application.IfError(Application.Index(IndexRange, Application.Match(AdID, MatchLookupRng, 0), 7), "-") 'Admin Access to all Locations
Next AdID
wsWebCNA.Range("P1").Value = "Market Segment"
wsWebCNA.Range("Q1").Value = "Region Code"
wsWebCNA.Range("R1").Value = "Client#"
wsWebCNA.Range("S1").Value = "Admin Access Level"
wsWebCNA.Range("T1").Value = "Admin Location Access"
wsWebCNA.Range("U1").Value = "Admin Access to all Locations"
wsWebCNA.Range("A1:U" & lastRow).Copy wsBW.Range("A4")
wsBW.Range("A4:Y1048576").Font.Name = "Calibri"
wsBW.Range("A4:Y1048576").Font.Size = 10
End Sub
Private Sub Reorder_Columns_Folder() 'Final Columns
Dim ColumnOrder As Variant, ndx As Integer
Dim Found As Range, counter As Integer
ColumnOrder = Array("Market Segment", "Region Code", "Requestor Access ID", "Requestor Email", "Client#", "Transaction Type", _
"Date Processed", "Admin First Name", "Admin Last Name", "Admin Language", "Admin Email", "Admin Access ID", "Admin Access Level", _
"Admin Location Access", "Admin Access to all Locations", "Changed Admin First Name", "Changed Admin Last Name", "Changed Admin Language", _
"Changed Admin Email", "Changed Admin Access Level", "Changed Admin Location Access")
counter = 1
wsBW.Activate
For ndx = LBound(ColumnOrder) To UBound(ColumnOrder)
Set Found = Rows("4:4").Find(ColumnOrder(ndx), LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not Found Is Nothing Then
If Found.Column <> counter Then
Found.EntireColumn.Cut
Columns(counter).Insert Shift:=xlToRight
Application.CutCopyMode = False
End If
counter = counter + 1
End If
Next ndx
Call HighlightPlanAdmin_Folder
End Sub
Private Sub HighlightPlanAdmin_Folder()
Dim ReqID As Range, nReqID As String, rReqID As String, tType As String, ntType As String
wsBW.Activate
For Each ReqID In Range("C5:C" & Cells(Rows.Count, 1).End(xlUp).Row).Cells
ReqID.Select
rReqID = Trim(ReqID)
tType = Trim(ReqID.Offset(0, 3)) '"Add Plan Admin"
If tType = "Add Plan Admin" Then
nReqID = Trim(ReqID.Offset(1, 0)) 'Requestor ID next row
If rReqID = nReqID Then
ntType = Trim(ReqID.Offset(1, 3))
If ntType <> "Add Plan Admin to OASIS." Then
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
Else
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
If nReqID = "" Then
ntType = Trim(ReqID.Offset(1, 3))
If ntType = "" Then
ReqID.Offset(0, 3).Font.ColorIndex = 3
End If
End If
End If
Next ReqID
End Sub
SRMATCH
Public wsSR As Worksheet
Sub ServiceRepMatch()
Set wsSR = ThisWorkbook.Sheets("SR - Information")
Set wsBW = ThisWorkbook.Sheets("B+W")
Set SRLookupRng = wsSR.Range("A:B")
Set macth = wsSR.Range("B1:B1048576")
Application.ScreenUpdating = False
wsBW.Range("V4").Value = "Service Reps"
For Each cel In wsBW.Range("E5:E" & Cells(Rows.Count, 1).End(xlUp).Row).Cells
cel.Offset(0, 17) = Application.IfError(Application.VLookup(cel, SRLookupRng, 2, 0), "-")
Next cel
wsBW.Range("V4:V" & Cells(Rows.Count, 22).End(xlUp).Row).Copy wsSR.Range("P1")
wsSR.Select
wsSR.Range("P1:P" & Cells(Rows.Count, 16).End(xlUp).Row).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=wsSR.Range("Q1"), Unique:=True
wsSR.Columns("P").Clear
wsBW.Select
MsgBox "DONE!"
Application.ScreenUpdating = True
End Sub
In nutshell, we first run IMPORTFILES to merge 2 reports it can either be 2 or 3 and perform some data manipluations. Secondly, CASELISTING is used to get the SR's client#. Third, we match the respective sales representatives through SRMATCH. Last, we use CREATEEMAIL to send individual emails for SR's their report and confidently message in the Body.

Excel VBA manually choosing a folder to loop thorugh all excel files in it

I have the following VBA code, to go through all the excel files in a folder and copy the needed columns from all file to one. Here is the code:
Option Explicit
Const FOLDER_PATH = "C:\Users\user\Desktop\04. April 2018\"
Sub ImportIncidentWorksheets()
Dim sFile As String
Dim wsTarget As Worksheet
Dim wbsource As Workbook
Dim wsSource As Worksheet
Dim rowTarget As Long
Dim rowSource As Long
rowTarget = 2
If Not FileFolderExists(FOLDER_PATH) Then
MsgBox "Specified folder does not exist, exiting!"
Exit Sub
End If
On Error GoTo errHandler
Application.ScreenUpdating = True
Set wsTarget = Sheets("SC")
sFile = Dir(FOLDER_PATH & "*.xlsx*")
Do Until sFile = ""
Set wbsource = Workbooks.Open(FOLDER_PATH & sFile)
Set wsSource = wbsource.Worksheets("sheet1")
With wsSource
rowSource = Application.Max(.Range("A" & .Rows.Count).End(xlUp).Row, .Range("B" & .Rows.Count).End(xlUp).Row, .Range("C" & .Rows.Count).End(xlUp).Row, .Range("D" & .Rows.Count).End(xlUp).Row, .Range("E" & .Rows.Count).End(xlUp).Row)
End With
With wsTarget
.Range("A" & rowTarget & ":E" & rowTarget + rowSource - 2).Value = wsSource.Range("A2:E" & rowSource).Value
.Range("A" & rowTarget & ":C" & rowTarget + rowSource - 2).Value = wsSource.Range("A2:C" & rowSource).Value
.Range("D" & rowTarget & ":D" & rowTarget + rowSource - 2).Value = wsSource.Range("E2:E" & rowSource).Value
.Range("E" & rowTarget & ":E" & rowTarget + rowSource - 2).Value = wsSource.Range("D2:D" & rowSource).Value
.Range("F" & rowTarget).Value = wbsource.Name
End With
wbsource.Close SaveChanges:=False
rowTarget = rowTarget + rowSource - 1
sFile = Dir()
Loop
errHandler:
On Error Resume Next
Application.ScreenUpdating = True
Set wsSource = Nothing
Set wbsource = Nothing
Set wsTarget = Nothing
End Sub
Private Function FileFolderExists(strPath As String) As Boolean
If Not Dir(strPath, vbDirectory) = vbNullString Then FileFolderExists = True
End Function
How can I modify the first part that the path of the folder won't be hard coded but it will give me a pop up window and I can choose the folder manually?
You can use code like below to get path while running the code.
Dim strFolderPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Show
If .SelectedItems.Count <> 0 Then
strFolderPath = .SelectedItems(1)
Else
MsgBox "Path not selected!", vbExclamation
End If
End With

copy files from source folder to target based on excel list

I am using this to try and copy photos that exist in the list within a list in excel. it seems check but doesn't see anything in the source folder and returns the "Does N" from the code below. I have enabled macros and the folders don't see locked. any help would be much appriciated
Option Explicit
Sub CopyFiles()
Dim iRow As Integer ' ROW COUNTER.
Dim sSourcePath As String
Dim sDestinationPath As String
Dim sFileType As String
Dim bContinue As Boolean
bContinue = True
iRow = 1
' THE SOURCE AND DESTINATION FOLDER WITH PATH.
sSourcePath = "C:\Users\username\Desktop\source\"
sDestinationPath = "C:\Users\username\Desktop\TARGET\"
sFileType = ".jpg" ' TRY WITH OTHER FILE TYPES LIKE ".pdf".
' LOOP THROUGH COLUMN "A" TO PICK THE FILES.
While bContinue
If Len(Range("A" & CStr(iRow)).Value) = 0 Then ' DO NOTHING IF THE COLUMN IS BLANK.
MsgBox "Process executed" ' DONE.
bContinue = False
Else
' CHECK IF FILES EXISTS.
If Len(Dir(sSourcePath & Range("A" & CStr(iRow)).Value & sFileType)) = 0 Then
Range("B" & CStr(iRow)).Value = "Does N"
Range("B" & CStr(iRow)).Font.Bold = True
Else
Range("B" & CStr(iRow)).Value = "On Hand"
Range("B" & CStr(iRow)).Font.Bold = False
If Trim(sDestinationPath) <> "" Then
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
' CHECK IF DESTINATION FOLDER EXISTS.
If objFSO.FolderExists(sDestinationPath) = False Then
MsgBox sDestinationPath & " Does Not Exists"
Exit Sub
End If
'*****
' HERE I HAVE INCLUDED TWO DIFFERENT METHODS.
' I HAVE COMMENTED THE SECOND METHOD. TO THE SEE THE RESULT OF THE
' SECOND METHOD, UNCOMMENT IT AND COMMENT THE FIRST METHOD.
' METHOD 1) - USING "CopyFile" METHOD TO COPY THE FILES.
objFSO.CopyFile Source:=sSourcePath & Range("A" & CStr(iRow)).Value & _
sFileType, Destination:=sDestinationPath
' METHOD 2) - USING "MoveFile" METHOD TO PERMANENTLY MOVE THE FILES.
'objFSO.MoveFile Source:=sSourcePath & Range("A" & CStr(iRow)).Value & _
sFileType, Destination:=sDestinationPath
'*****
End If
End If
End If
iRow = iRow + 1 ' INCREMENT ROW COUNTER.
Wend
End Sub
You shouldn’t be creating a new FileSystemObject on every iteration. Also, the destination folder can only be checked once - no need to check it every time.
See below your code with a few changes.
Option Explicit
Sub CopyFiles()
On Error GoTo Errproc
Const sSourcePath As String = "C:\Users\username\Desktop\source\"
Const sDestinationPath As String = "C:\Users\username\Desktop\TARGET\"
Const sFileType As String = ".jpg"
'validate destination folder
If Len(Dir(sDestinationPath)) = 0 Then
MsgBox "Destination path does not exist..."
Exit Sub
End If
Dim iRow As Integer
iRow = Range("A" & Rows.Count).End(xlUp).Row
Dim rr As Range, r As Range
Set rr = Range("A1:A" & iRow)
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each r In rr
With objFSO
If Not .FileExists(sSourcePath & r.Value & sFileType) Then
r.Offset(0, 1).Value = "Does N"
r.Offset(0, 1).Font.Bold = True
Else
r.Offset(0, 1).Value = "On Hand"
r.Offset(0, 1).Font.Bold = False
objFSO.CopyFile sSourcePath & r.Value & sFileType, sDestinationPath, True 'Overwrite
'objFSO.MoveFile Source:=sSourcePath & r.Value & sFileType , Destination:=sDestinationPath
End If
End With
Next r
Leave:
Set objFSO = Nothing
On Error GoTo 0
Exit Sub
Errproc:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub

Nielsen Nitro range (Blueberry range) refresh

I am looking for VBA to refresh Nielsen Nitro range.
Nielsen Nitro is an application to extract data from the Database. Also range is called Blueberry range to refresh the data
I've tried to use below VBA, but it was not working
Dim acnNitro As New ACNNITRO
Dim acnNitroUpdate As ACNielsenNitro.ACNNitroUpdate
Dim WS As Worksheet
Dim bret as Boolean
acnNitro.ParentApp = Application
acnNitroUpdate = acnNitro.ACNNitroUpdate
WS = ActiveSheet 'or Set WS = WorkSheets("My Sheet")
bret = acnNitroUpdate.UpdateAllNRanges(WS, ntrSelectGet)
acnNitro = Nothing
acnNitroUpdate = Nothing
WB = Nothing
screenshot
I have also provided screenshot for the range.
Can you please suggest me for VBA code?
I have written a similar code for a project, find code below. It might help you!
Public Sub NeilsenRefresh()
Dim str_RngDesc As Variant
Dim bRet As Boolean
Dim RngObj As NITRORange
Dim acnNITROUpdt As Object
Dim acnNITRO As Object
Dim NRangeObj As NITRORange
Dim cRange As Object
Dim Bubble As String
Set acnNITRO = CreateObject("ACNielsenNitro.ACNNitro")
Set acnNITRO.ParentApp = ActiveWorkbook.Application
Set acnNITROUpdt = acnNITRO.ACNNitroUpdate
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
With ThisWorkbook.Sheets("Macro")
WkbName = .Range("G9").Value
Path = .Range("G12").Value
Bubble = .Range("G15").Value
Atribute = .Range("G18").Value
WkList = .Range("G6").Value
End With
'Sheets("Data").Activate
With ThisWorkbook.Sheets("Data")
lr = .Range("A1048576").End(xlUp).Row
If lr > 1 Then
.Range("Q1:Q" & lr).ClearContents
.Range("A2:A" & lr).ClearContents
.Range("B3:C" & lr).ClearContents
.Range("D2:D" & lr).ClearContents
.Range("R2:R" & lr).ClearContents
.Range("S2:S" & lr).ClearContents
End If
Set WkbList = Workbooks.Open(Path & "\" & WkList & ".xlsx")
Set wks = WkbList.Sheets("Sheet1")
lrw = wks.Range("A1048576").End(xlUp).Row
wks.Range("A2:A" & lrw).Copy
.Range("A2").PasteSpecial Paste:=xlPasteValues
wks.Range("B2:B" & lrw).Copy
.Range("D2").PasteSpecial Paste:=xlPasteValues
lr = .Range("A1048576").End(xlUp).Row
.Range("B2:C" & lr).FillDown
.Calculate
Set wksmiss = ThisWorkbook.Sheets("Missing Records")
lrw = wksmiss.Range("A1048576").End(xlUp).Row
If lrw > 1 Then wksmiss.Range("A2:B" & lrw).ClearContents
.Range("A1:D" & lr).AutoFilter Field:=2, Criteria1:="#N/A"
lrw = .Range("A1048576").End(xlUp).Row
If lrw > 1 Then
.Range("B2:B" & lrw).SpecialCells(xlCellTypeVisible).Copy
wksmiss.Range("A2").PasteSpecial Paste:=xlPasteValues
.Range("D2:D" & lrw).SpecialCells(xlCellTypeVisible).Copy
wksmiss.Range("B2").PasteSpecial Paste:=xlPasteValues
.Range("A2:D" & lrw).SpecialCells(xlCellTypeVisible).Delete Shift:=xlUp
End If
.Range("A1:D" & lr).AutoFilter
.Range("B2:C" & lr).FillDown
.Calculate
.Calculate
.Range("A2:A" & lr).Copy
.Range("Q1").PasteSpecial Paste:=xlPasteValues
.Range("Q1:Q" & lr).RemoveDuplicates Columns:=1, Header:=xlNo
lrd = .Range("Q1048576").End(xlUp).Row
.Range("R1:R" & lrd).FillDown
.Range("S1:S" & lrd).FillDown
.Range("A1").Value = "Cum Name"
.Calculate
For i = 1 To lrd
CumName = .Range("Q" & i).Value
Cnt = .Range("R" & i).Value
FstIndex = .Range("S" & i).Value
RowNo = FstIndex + Cnt - 1
val1 = .Range("C" & RowNo).Value
If CumConcat = "" Then
CumConcat = val1 & ","
Else
val1 = Replace(val1, "MKT", "")
CumConcat = CumConcat & val1 & ","
End If
Next
End With
Set wkb = Workbooks.Open(Path & "\" & WkbName & ".xlsx")
Set RngObj = acnNITRO.ACNRangeUtility.GetNRange(Bubble, ActiveWorkbook)
RngObj.DimCount = 4
RngObj.DimIndex = Atribute
RngObj.DimGetString = CumConcat
str_RngDesc = RngObj.RangeDescription
Set acnNITROUpdt = acnNITRO.ACNNitroUpdate
bRet = acnNITROUpdt.UpdateNRange(ActiveWorkbook, Bubble, 0)
WkbList.Close
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
ThisWorkbook.Sheets("Macro").Activate
MsgBox "Nielsen Refresh Completed", vbInformation
End Sub