How to find a value with the Find function? - excel

How do I find a value with the Find function?
I want to copy specific data from an external Excel file to the current workbook.
I added Option Explicit to test for errors but it could just spot that I didn't declare the variable. The output is the same.
Sub ReadDataFromCloseFile()
'
' ReadDataFromCloseFile Macro
'
'
On Error GoTo ErrHandler
Application.ScreenUpdating = False
Dim wb As Workbook
Set wb = ThisWorkbook
Dim src As Workbook
' OPEN THE SOURCE EXCEL WORKBOOK IN "READ ONLY MODE".
Set src = Workbooks.Open("C:\test.xlsm", True, True)
Dim masterRow_count As Integer
masterRow_count = wb.Worksheets("Sheet1").Range("A1").End(xlDown).Row
Dim row_number As Integer
row_number = 2
Dim strSearch As String
Dim searchrange As Range
Do
Dim result As Range
strSearch = wb.Worksheets("Sheet1").Range("A" & row_number).Value
Set searchrange = src.Worksheets("Sheet1").Range("D:D")
Set result = searchrange.Find(what:=strSearch, LookIn:=xlValues, lookat:=xlValues)
If Not result Is Nothing Then
'Get the data from Asiamiles
src.Worksheets("Sheet1").Range("AB" & result.Row).Copy wb.Worksheets("Sheet1").Range("B", row_number)
src.Worksheets("Sheet1").Range("J" & result.Row).Copy wb.Worksheets("Sheet1").Range("C", row_number)
src.Worksheets("Sheet1").Range("I" & result.Row).Copy wb.Worksheets("Sheet1").Range("D", row_number)
src.Worksheets("Sheet1").Range("N" & result.Row).Copy wb.Worksheets("Sheet1").Range("E", row_number)
src.Worksheets("Sheet1").Range("AD" & result.Row).Copy wb.Worksheets("Sheet1").Range("F", row_number)
src.Worksheets("Sheet1").Range("P" & result.Row).Copy wb.Worksheets("Sheet1").Range("G", row_number)
src.Worksheets("Sheet1").Range("Q" & result.Row).Copy wb.Worksheets("Sheet1").Range("H", row_number)
End If
row_number = row_number + 1
Loop Until row_number = masterRow_count
src.Close SaveChanges:=False
Set src = Nothing
ErrHandler:
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
There is another problem .It could not close the Excel workbook. But that is not the largest issue.

LookAt:=xlValues should be LookAt:=xlPart or LookAt:=xlWhole, Range("B", row_number) should be Range("B" & row_number)
Option Explicit
Sub ReadDataFromCloseFile()
Const SRC_WB = "C:\test.xlsm"
Dim wb As Workbook, wbSrc As Workbook
Dim ws As Worksheet, wsSrc As Worksheet
Dim masterRow_count As Long, row_number As Long
Dim rngSearch As Range, rngResult As Range, strSearch As String
Dim i As Long, n As Long, ar, t0 As Single
t0 = Timer
' OPEN THE SOURCE EXCEL WORKBOOK IN "READ ONLY MODE".
Application.ScreenUpdating = False
Set wbSrc = Workbooks.Open(SRC_WB, True, True)
Set wsSrc = wbSrc.Worksheets("Sheet1")
With wsSrc
i = .Cells(.Rows.Count, "D").End(xlUp).Row
Set rngSearch = wsSrc.Range("D1:D" & i)
End With
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet1")
ar = Split("AB,J,I,N,AD,P,Q", ",")
With ws
masterRow_count = .Range("A" & .Rows.Count).End(xlUp).Row
For row_number = 2 To masterRow_count
strSearch = .Range("A" & row_number).Value
Set rngResult = rngSearch.Find(what:=strSearch, _
LookIn:=xlValues, lookat:=xlWhole)
If Not rngResult Is Nothing Then
'Get the data from Asiamiles
For i = 0 To UBound(ar)
.Cells(row_number, "B").Offset(0, i) = wsSrc.Cells(rngResult.Row, ar(i))
Next
n = n + 1
End If
Next
End With
wbSrc.Close SaveChanges:=False
Application.ScreenUpdating = True
MsgBox row_number - 1 & " rows scanned, " & _
n & " rows updated", vbInformation, Format(Timer - t0, "0.0 secs")
End Sub

Related

I have 20 odd source file from where I am collating data into one file, facing issue in pulling the source file name also as identifier

My Code so far does paste the selected data from all the source files, however I also need the source file name to recognize which data belongs to which source file and this name should occur beside the column where data is pasted each time.
Sub OpenFilesCopyPasteVI()
Dim SFile As Workbook
Dim SFname As Worksheet
Dim SFname2 As Worksheet
Dim SFlname As String
Dim I As Long
Dim DFile As Workbook
Dim Acellrng As String
Pth = "C:\XYZ\"
Application.ScreenUpdating = False
Set SFile = ThisWorkbook
Set SFname = SFile.Worksheets("Sheet1")
Set SFname2 = SFile.Worksheets("Sheet3")
numrows = SFname.Range("A1", Range("A1").End(xlDown)).Rows.Count
For I = 1 To numrows
SFlname = SFname.Range("A" & I).Value
If SFname.Range("A" & I).Value <> "" Then
Workbooks.Open Pth & SFlname
Set DFile = Workbooks(SFlname)
Cells.Find(What:="ABC", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=True).Activate
Acellrng = ActiveCell.Address
Range(Acellrng).Select
ActiveSheet.Range(Selection, Selection.End(xlDown).End(xlToRight)).Copy Destination:=SFile.Worksheets("Sheet3").Cells(SFile.Worksheets("Sheet3").Rows.Count, "C").End(xlUp).Offset(1)
DFile.Close
**'I need help to automate this part where I need the source file name in the last column each time beside the data pasted**
SFname2.Range("K3", "K18").Value = SFlname
End If
Next I
MsgBox "job done"
Application.ScreenUpdating = True
End Sub
Try this out:
Sub OpenFilesCopyPasteVI()
Const PTH As String = "C:\XYZ\" 'use const for fixed values
Dim SFile As Workbook, SFname As Worksheet, SFname2 As Worksheet
Dim SFlname As String, I As Long, DFile As Workbook
Dim Acellrng As Range, ws As Worksheet, rngDest As Range, rngCopy As Range
Set SFile = ThisWorkbook
Set SFname = SFile.Worksheets("Sheet1")
Set SFname2 = SFile.Worksheets("Sheet3")
Application.ScreenUpdating = False
For I = 1 To SFname.Cells(Rows.Count, "A").End(xlUp).Row
SFlname = SFname.Range("A" & I).Value
If Len(SFlname) > 0 Then
Set DFile = Workbooks.Open(PTH & SFlname)
Set ws = DFile.Sheets(1) 'or other specifc sheet
Set Acellrng = ws.Cells.Find(What:="ABC", _
LookIn:=xlValues, lookat:=xlWhole, MatchCase:=True)
If Not Acellrng Is Nothing Then
Set rngCopy = ws.Range(Acellrng, Acellrng.End(xlDown).End(xlToRight))
Set rngDest = SFname2.Cells(Rows.Count, "C").End(xlUp).Offset(1)
rngCopy.Copy rngDest
'populate the file name in Column K next to the copied data
rngDest.EntireRow.Columns("K").Resize(rngCopy.Rows.Count).Value = SFlname
End If
DFile.Close savechanges:=False
End If
Next I
MsgBox "job done"
Application.ScreenUpdating = True
End Sub

Type mismatch in range

I am trying to copy a filtered range from a master dataset to a spreadsheet for each country (loop). I am getting a type mismatch error for Set rng1 = ws2.Range("E2:L" And lRow1) when I set a range in the filtered sheet. Can someone please help me identify the cause of the mismatch?
Sub CopyData_To_TemplateWorkbook2()
Dim wb As Workbook
Dim SavePath, TemplatePath, TemplateFile As String
Dim ws1, ws2, ws3, wbws1, wbws2, wbws3 As Worksheet
Dim rng1, rng2 As Range
Dim MSi As Variant
Dim lRow1, lRow2 As Long
Application.DisplayAlerts = False
'Application.ScreenUpdating = False
TemplatePath = "C:\Users\xyz\Test\"
TemplateFile = "Template_blank.xlsx"
SavePath = "C:\Users\xyz\Test\"
Set ws1 = ThisWorkbook.Sheets("Lists")
Set ws2 = ThisWorkbook.Sheets("Responses 2006 2020")
ws1.Select
For i = 2 To 5 'Loop through list of country names
Set MSi = ws1.Range("A" & i)
ws2.Activate
If ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If
ws2.Range("B1").AutoFilter Field:=2, Criteria1:=MSi 'Filter Criteria1 = i
lRow1 = ws2.Range("E" & Rows.Count).End(xlUp).Row
Set rng1 = ws2.Range("E2:L" And lRow1) 'Type mismatch here
'Set rng1 = ws2.Range("E2:L") 'Application-defined or object-defined error here if used
Set wb = Workbooks.Open(Filename:=TemplatePath & "Template_blank.xlsx", Editable:=True)
Set wbws1 = wb.Sheets("Cover sheet")
Set wbws2 = wb.Sheets("Responses")
wbws1.Range("B2").Value = MSi
wbws2.Range("B2").Value = MSi
lRow2 = wbws2.Range("A" & Rows.Count).End(xlUp).Row 'But there is no last row - blank sheet
Set rng2 = wbws2.Range("A6:H") ' And lRow2 ??
rng2.Value = rng1.Value
wb.SaveAs Filename:=SavePath _
& MSi & "_text" & Format(Date, "yyyymmdd") & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
wb.Close SaveChanges:=False
Set rng1 = Nothing
ws1.Select
Next i
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Collate data from multiple workbooks to a separate workbook based on column names

I have multiple workbooks in a folder and i need to copy paste data from some of them based on naming convention. I am copy pasting data based on column names to a master sheet as order of columns in source files is not the same. Code pasted below does the task but it looks for exact match in column names and as a result i am only able to capture 80% of the data as few column names in source files are not an exact match. For eg: A column in the Target file with header Premium is mentioned as Premium # 25% in the Source file. This is just an example.
Sub ImportExcelfiles()
Dim strPath As String
Dim strFile As String
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim bookName As Worksheet
Dim rowCountSource As Long
Dim colCountSource As Long
Dim rowOutputTarget As Long
Dim colOutputTarget As Long
Dim found1 As Range, found2 As Range, j As Long, Cr1 As String, srcRow As Range
'Variables for Sheet - Workbook Name
Dim nameCount As Long
Dim fileName As String
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'====================================
'SET THE PATH AND FILE TO THE FOLDER
'====================================
strPath = ThisWorkbook.Worksheets("Control").Range("C4")
fileName = ThisWorkbook.Worksheets("Control").Range("C5")
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
'set the target worksheet
Set wsTarget = ThisWorkbook.Worksheets("Master Data")
Set bookName = ThisWorkbook.Worksheets("Workbook Name")
'set the initial output row and column count for master data and workbook name
nameCount = 2
rowOutputTarget = wsTarget.Cells(Rows.Count, 1).End(xlUp).Row
'get the first file
strFile = Dir(strPath & "*.xlsx*")
'loop throught the excel files in the folder
Do While strFile <> ""
If InStr(strFile, fileName) > 0 Then
'open the workbook
Set wbSource = Workbooks.Open(strPath & strFile)
Set wsSource = wbSource.Worksheets("Details")
'get the row and column counts
With wsSource
colCountSource = .Cells(2, Columns.Count).End(xlToLeft).Column
For j = 1 To colCountSource
Cr1 = .Cells(2, j).Value
Set srcRow = .Range("A2", .Cells(1, colCountSource))
Set found1 = srcRow.Find(What:=Cr1, LookAt:=xlWhole, MatchCase:=True)
If Not found1 Is Nothing Then
colCountSource = wsTarget.Cells(1, Columns.Count).End(xlToLeft).Column
Set srcRow = wsTarget.Range("A1", wsTarget.Cells(1, colCountSource))
Set found2 = srcRow.Find(What:=Cr1, LookAt:=xlWhole, MatchCase:=F)
If Not found2 Is Nothing Then
rowCountSource = .Cells(Rows.Count, found1.Column).End(xlUp).Row
.Range(.Cells(3, found1.Column), .Cells(rowCountSource, found1.Column)).Copy
found2.Offset(rowOutputTarget, 0).PasteSpecial Paste:=xlPasteValues
End If
End If
Next j
End With
bookName.Range("A" & nameCount).Value = wbSource.Name
'update output row '2+12-1=13
nameCount = nameCount + 1
rowOutputTarget = rowOutputTarget + rowCountSource - 2
'close the opened workbook
wbSource.Close SaveChanges:=False
End If
'get the next file
strFile = Dir()
Loop
Application.ScreenUpdating = True
MsgBox "Data imported.", vbInformation
End Sub
This code takes approximately 5 mins to copy paste data. Is there a way to optimise it and also solve my problem of missing 20% data.
Because the target column name is the shorter you need to search the source column names for each target column name.
Option Explicit
Sub ImportExcelfiles()
Dim strPath As String, strFile As String, fileName As String
Dim wbSource As Workbook
Dim wsSource As Worksheet, wsTarget As Worksheet
Dim bookName As Worksheet
Dim rowCountSource As Long, colCountSource As Long
Dim colCountTarget As Long
Dim rowOutputTarget As Long, colOutputTarget As Long
Dim found1 As Range, found2 As Range, j As Long
Dim Cr1 As String, srcRow As Range
'Variables for Sheet - Workbook Name
Dim nameCount As Long
Dim t0 As Single: t0 = Timer
strPath = ThisWorkbook.Worksheets("Control").Range("C4")
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
fileName = ThisWorkbook.Worksheets("Control").Range("C5")
'set the target worksheet
With ThisWorkbook
Set wsTarget = .Sheets("Master Data")
Set bookName = .Sheets("Workbook Name")
End With
'set the initial output row and column count
'for master data and workbook name
nameCount = 2
Dim arTarget, rngSrc As Range, rngTarget As Range
Dim lastrow As Long, n As Long
With wsTarget
rowOutputTarget = 1 + .Cells(.Rows.Count, 1).End(xlUp).Row
' array of target column names
colCountTarget = .Cells(1, .Columns.Count).End(xlToLeft).Column
arTarget = .Cells(1, 1).Resize(, colCountTarget)
End With
'get the first file
strFile = Dir(strPath & "*.xlsx*")
'loop throught the excel files in the folder
Application.ScreenUpdating = False
Do While strFile <> ""
If InStr(strFile, fileName) > 0 Then
'open the workbook
Set wbSource = Workbooks.Open(strPath & strFile, ReadOnly:=True)
Set wsSource = wbSource.Worksheets("Details")
With wsSource
'get the row and column counts'get the row and column counts
colCountSource = .Cells(2, Columns.Count).End(xlToLeft).Column
Set srcRow = .Range("A2", .Cells(1, colCountSource))
' loop through target columns
For j = 1 To UBound(arTarget, 2)
Cr1 = arTarget(1, j)
Set found1 = srcRow.Find(What:=Cr1, LookAt:=xlPart, MatchCase:=True)
' found
If Not found1 Is Nothing Then
rowCountSource = .Cells(.Rows.Count, found1.Column).End(xlUp).Row
n = rowCountSource - 2
Set rngSrc = .Range(.Cells(3, found1.Column), .Cells(rowCountSource, found1.Column))
Set rngTarget = wsTarget.Cells(rowOutputTarget, j)
rngTarget.Resize(n).Value2 = rngSrc.Value2
If lastrow < rowOutputTarget + n Then
lastrow = rowOutputTarget + n
End If
End If
Next
End With
bookName.Range("A" & nameCount).Value = wbSource.Name
'update output row '2+12-1=13
nameCount = nameCount + 1
rowOutputTarget = lastrow
'close the opened workbook
wbSource.Close SaveChanges:=False
End If
'get the next file
strFile = Dir()
Loop
Application.ScreenUpdating = True
MsgBox "Data imported.", vbInformation, Format(Timer - t0, "0.0 secs")
End Sub

Loop through range then update worksheet reference

I have a document that contains a couple of macros.
First extracts data from a data sheet (datasheet) and copies to a specific worksheet (reportsheet) when the criteria is met.
Second saves this as a PDF, creates an email and sends it.
I have 100+ sheets and would require duplicating these macros 100 times.
I want to combine these into one macro. I would like to loop through a range ("B6:B123") and if in that range the cell <> 0 then the macro needs to run but the report sheet reference I'd like to update dynamically using the adjacent cell value (Dx) that would trigger these to run.
Macro 1
Sub Search_extract_135()
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Dim ocname As String
Dim finalrow As Integer
Dim i As Integer
Set datasheet = Sheet121 ' stays constant
Set reportsheet = Sheet135 'need to update based on range that <>0 then taking cell reference as
ocname = reportsheet.Range("A1").Value 'stays constant
reportsheet.Range("A1:U499").EntireRow.Hidden = False
reportsheet.Range("A5:U499").ClearContents
datasheet.Select
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To finalrow
If Cells(i, 1) = ocname Then
Range(Cells(i, 1), Cells(i, 21)).Copy
reportsheet.Select
Range("A500").End(xlUp).Offset(1, 0).PasteSpecial xlPasteAll
datasheet.Select
End If
Next i
reportsheet.Select
Range("A4").Select
Call HideRows
End Sub
Macro 2
Sub Send_Email_135()
Dim wPath As String, wFile As String, wMonth As String, strPath As String, wSheet As Worksheet
Set wSheet = Sheet135
wMonth = Sheets("Journal").Range("K2")
wPath = ThisWorkbook.Path ThisWorkbook.Path
wFile = wSheet.Range("A1") & ".pdf"
wSheet.Range("A1:U500").ExportAsFixedFormat Type:=xlTypePDF, Filename:=wPath & "-" & wFile, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
strPath = wPath & "-" & wFile
Set dam = CreateObject("Outlook.Application").CreateItem(0)
'
dam.To = wSheet.Range("A2")
dam.cc = wSheet.Range("A3")
dam.Subject = "Statement " & wMonth
dam.Body = "Hi" & vbNewLine & vbNewLine & "Please find attached your statement." & Chr(13) & Chr(13) & "Regards," & Chr(13) & "xxxxx"
dam.Attachments.Add strPath
dam.Send
MsgBox "Email sent"
End Sub
The Excel document has names in column A, numeric values in column B and SheetCode in column D.
When cell within Range("B6:B123") <> 0 then run the two macros above but need report sheet from macro 1 & wSheet from macro 2 to use the same value in column D to references the specific worksheet code for the person that doesn't equal 0.
The solution it to use a dictionary to convert the codenames into sheet numbers and pass parameters into the subroutines so the same code can be applied to many different sheets.
Option Explicit
Sub Reporter()
' Journal sheet layout
Const ROW_START = 6
Const COL_NZ = "B" ' column to check <> 0
Const COL_CODE = "D" ' sheet codenames
' Fixed sheet code names
Const WS_DATA = "Sheet121"
Const WS_JOURNAL = "Sheet5"
Dim wb As Workbook, ws As Worksheet
Dim wsReport As Worksheet, wsJournal As Worksheet, wsData As Worksheet
Dim iLastRow As Long, i As Long, n As Long
Dim sCodeName As String, sMonth As String
' build a dictionary of codename->sheetno
Dim dict As Object, key As String
Set dict = CreateObject("Scripting.Dictionary")
Set wb = ThisWorkbook
For Each ws In wb.Sheets
dict.Add ws.CodeName, ws.Index
Next
' assign Fixed sheets
Set wsData = wb.Sheets(dict(WS_DATA)) ' or Sheet121
Set wsJournal = wb.Sheets(dict(WS_JOURNAL)) ' or Sheet5
sMonth = wsJournal.Range("K2")
' scan list of persons
With wsJournal
iLastRow = .Cells(Rows.Count, COL_CODE).End(xlUp).Row
For i = ROW_START To iLastRow
If .Cells(i, COL_NZ) <> 0 Then ' col B
sCodeName = .Cells(i, COL_CODE) ' col D
' set sheet, create report and email it
Set wsReport = wb.Sheets(dict(sCodeName))
Call Create_Report(wsReport, wsData)
Call Email_Report(wsReport, sMonth)
n = n + 1
End If
Next
End With
MsgBox n & " emails sent", vbInformation
End Sub
Sub Create_Report(wsReport As Worksheet, wsData)
Dim ocname As String, iLastRow As Long, i As Long
Dim rngReport As Range
With wsReport
ocname = .Range("A1").Value 'stays constant
.Range("A1:U500").EntireRow.Hidden = False
.Range("A5:U500").ClearContents
Set rngReport = .Range("A5")
End With
' scan down data sheet and copy to report sheet
Application.ScreenUpdating = False
With wsData
iLastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To iLastRow
If wsData.Cells(i, 1) = ocname Then
.Cells(i, 1).Resize(1, 21).Copy rngReport
Set rngReport = rngReport.Offset(1)
End If
Next i
End With
'Call HideRows
Application.ScreenUpdating = True
End Sub
Sub Email_Report(wsReport As Worksheet, sMonth As String)
Dim sPDFname As String, oMail As Outlook.MailItem
sPDFname = ThisWorkbook.Path & "\" & wsReport.Range("A1") & ".pdf"
Dim oOut As Object ' Outlook.Application
Set oOut = CreateObject("Outlook.Application")
Set oMail = oOut.CreateItem(0)
With oMail
wsReport.Range("A1:U500").ExportAsFixedFormat _
Type:=xlTypePDF, Filename:=sPDFname, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
.To = wsReport.Range("A2").Value2
.cc = wsReport.Range("A3").Value2
.Subject = "Statement " & sMonth
.Body = "Hi" & vbNewLine & vbNewLine & _
"Please find attached your statement." & vbCr & vbCr & _
"Regards," & vbCr & "xxxxx"
.Attachments.Add sPDFname
.Display ' or .Send
End With
MsgBox "Email sent to " & wsReport.Range("A2").Value2, , wsReport.Name
oOut.Quit
End Sub

Convert Multiple Excel Sheet Ranges as PDF VBA

The below code is take the Status of Col"E" If it is = Include then its corresponding sheets ranges will will be converted to PDF.
I have tried at my end but its not working receiving an error invalid procedure call or argument on the line
rng.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=saveLocation
Your help will be appreciated to fix the problem.
Sub SelectSheets_Ranges()
Dim sh As Worksheet, lastR As Long, rng As Range, arr, arrSplit, i As Long, k As Long
Set sh = ActiveSheet
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
ReDim arr(lastR - 1)
For i = 6 To lastR
If sh.Range("E" & i).Value = "Include" Then
arr(k) = sh.Range("C" & i).Value & "|" & sh.Range("D" & i).Value: k = k + 1
End If
Next i
ReDim Preserve arr(k - 1)
For i = 0 To UBound(arr)
arrSplit = Split(arr(i), "|")
Set rng = Worksheets(arrSplit(0)).Range(arrSplit(1))
'Create and assign variables
Dim saveLocation As String
saveLocation = "C:\Users\marks\OneDrive\Documents\myPDFFile.pdf"
'Save a range as PDF
rng.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=saveLocation
Next
End Sub
Please, try the next code. It saves in ThisWorkbook path, naming the pdf file as "myPDFFile_sheetName.pdf". Each created file will be open in the default pdf application. If it works OK, you can appropriately change the last parameter:
Sub SelectSheets_Ranges_ExpPdf()
Dim sh As Worksheet, lastR As Long, rng As Range, arr, arrSplit, i As Long, k As Long
Set sh = ActiveSheet
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
ReDim arr(lastR - 1)
For i = 6 To lastR
If sh.Range("E" & i).Value = "Include" Then
arr(k) = sh.Range("C" & i).Value & "|" & sh.Range("D" & i).Value: k = k + 1
End If
Next i
If k > 0 Then
ReDim Preserve arr(k - 1)
Else
MsgBox "No appropriate range (containing ""Include"") could be found...:exit sub"
End If
Dim boolHide As Boolean, boolProt As Boolean
ActiveWorkbook.Unprotect "4321" 'in order to unprotect he workbook structure
For i = 0 To UBound(arr)
boolHide = False: boolProt = False
arrSplit = Split(arr(i), "|")
Set rng = Worksheets(arrSplit(0)).Range(arrSplit(1))
If ActiveWorkbook.Sheets(arrSplit(0)).ProtectContents Then _
ActiveWorkbook.Sheets(arrSplit(0)).Unprotect "4321": boolProt = True
Debug.Print arrSplit(0)
If ActiveWorkbook.Sheets(arrSplit(0)).Visible <> xlSheetVisible Then _
ActiveWorkbook.Sheets(arrSplit(0)).Visible = xlSheetVisible: boolHide = True
'Create and assign variables
Dim saveLocation As String
saveLocation = ThisWorkbook.Path & "\myPDFFile_" & arrSplit(0) & ".pdf"
'Save a range as PDF
rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
saveLocation, Quality:=xlQualityStandard, IgnorePrintAreas:=False, OpenAfterPublish:=True
If boolHide Then ActiveWorkbook.Sheets(arrSplit(0)).Visible = xlSheetHidden
If boolProt Then ActiveWorkbook.Sheets(arrSplit(0)).Protect "4321"
Next
ActiveWorkbook.Protect "4321"
End Sub
Try this:
Sub SelectSheets_Ranges()
Dim sh As Worksheet, i As Long
Dim saveLocation As String, FirstSheet As Boolean
saveLocation = "C:\Users\marks\OneDrive\Documents\myPDFFile.pdf"
Set sh = ActiveSheet
FirstSheet = True
For i = 6 To sh.Range("C" & sh.Rows.Count).End(xlUp).Row
If sh.Cells(i, "E") = "Include" Then
'FirstSheet determines whether the sheet is added to currently-selected
' sheets or not (if not then it replaces them)
ThisWorkbook.Sheets(sh.Cells(i, "C").Value).Select FirstSheet
FirstSheet = False
End If
Next i
If Not FirstSheet Then
'at least one sheet was included
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=saveLocation
End If
End Sub
I assume you want all the ranges from the different sheets in one pdf.
Option Explicit
Sub SelectSheets_Ranges()
Const FOLDER = "C:\Users\marks\OneDrive\Documents\"
Const FILENAME = "myPDFFile.pdf"
Dim wb As Workbook, wbPDF As Workbook
Dim sh As Worksheet, wsPDF As Worksheet
Dim lastR As Long, rng As Range, r As Long, n As Integer, m As Integer
Set sh = ActiveSheet
Set wb = ActiveWorkbook
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
' create temp workbook to hold ranges
Set wbPDF = Workbooks.Add
m = wbPDF.Sheets.Count
n = m
With sh
For r = 6 To lastR
If .Cells(r, "E").Value = "Include" Then
Set rng = wb.Sheets(.Cells(r, "C").Value).Range(.Cells(r, "D").Value)
Set wsPDF = wbPDF.Sheets.Add(After:=wbPDF.Sheets(n))
rng.Copy wsPDF.Range("A1")
n = n + 1
End If
Next
End With
' delete initial sheets
Application.DisplayAlerts = False
For n = m To 1 Step -1
wbPDF.Sheets(n).Delete
Next
Application.DisplayAlerts = True
'end
wbPDF.ExportAsFixedFormat Type:=xlTypePDF, FILENAME:=FOLDER & FILENAME
'wbPDF.SaveAs FOLDER & "debug.xlsx"
wbPDF.Close False
MsgBox "PDF created " & FOLDER & FILENAME, vbInformation
End Sub

Resources