I want to select a array of sheets using the Sheets(Array()) method. The sheets I want to select are named in the cells of my workheet Printlijst. The sheetnames are listed form column D to K.
Not all cells are filled so if I use the folowing function
This is what the sheet looks like:
http://i.stack.imgur.com/uJqZc.jpg
And this is the code:
Sub PDF_maken()
Dim ws As Worksheet
Dim LR As Long
Dim r As Range
Dim Mypath As String
Dim strarray As String
Set ws = ActiveWorkbook.Worksheets("Printlijst")
LR = ws.Cells(Rows.Count, 1).End(xlUp).Row
For Each r In ws.Range("B20:B20").Cells
If Not IsEmpty("B" & r.Row) Then
Mypath = ws.Range("B" & r.Row).Text
colCheck = 4
Do Until Cells(r.Row, colCheck) = ""
strarray = strarray & IIf(colCheck > 4, ",", "") & Cells(r.Row, colCheck).Value
colCheck = colCheck + 1
Loop
ActiveWorkbook.Sheets(strarray).Select
ActiveWorkbook.SelectedSheets.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
Mypath & ws.Range("C" & r.Row).Text & ".pdf", Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
End If
Next r
End Sub
The errors happens when more than one sheet must be selected
When I use the errorcheck strarray is "2450,2451,2452,2453,2454,2455,2456,2457"
You cannot use strarray in ActiveWorkbook.Sheets(strarray). It is expecting a single sheet name or a collection of sheets in array.
Is this what you are trying?
'
'~~> Rest of your code
'
Dim strarray As String
Dim MyAr As Variant
Do Until Cells(r.Row, colCheck) = ""
strarray = strarray & IIf(colCheck > 4, ",", "") & Cells(r.Row, colCheck).Value
colCheck = colCheck + 1
Loop
If InStr(1, strarray, ",") Then
MyAr = Split(strarray, ",") '<~~ This is where we are creating an actual array
ActiveWorkbook.Sheets(MyAr).Select
Else
ActiveWorkbook.Sheets(strarray).Select
End If
'
'~~> Rest of your code
'
NOTE: BTW, you should avoid using .Select and directly perform the operation on those sheet(s). You may want to see How to avoid using Select in Excel VBA macros
Related
I have a string of predefined worksheets, that I need to run specific code for. I get a compile error.
The code is set up to copy data from one sheet to another.
How do I do the same for multiple sheets?
When I step through the code sht is showing the MHP60,MHP61,MHP62 and not just MHP60.
I get a subscript out of range error.
Sub Prepare_CYTD_Report()
Dim addresses() As String
Dim addresses2() As String
Dim SheetNames() As String
Dim SheetNames2() As String
Dim wb1 As Workbook, wb2 As Workbook
Dim my_Filename
'Declare variables for MHP60, MHP61, MHP62 Trial Balance Values
Dim i, lastcol As Long
Dim tabNames, cell As Range
Dim tabName As String
Dim sht As Variant
addresses = Strings.Split("A9,A12:A26,A32:A38,A42:A58,A62:A70,A73:A76,A83:A90", ",") 'Trial Balance string values
addresses2 = Strings.Split("G9,G12:G26,G32:G38,G42:G58,G62:G70,G73:G76,G83:G90", ",") 'Prior Month string values
SheetNames = Strings.Split("MHP60,MHP61,MHP62")
'SheetNames2 = Strings.Split("MHP60-CYTDprior,MHP61-CYTDprior,MHP62-CYTDprior")
Set wb1 = ActiveWorkbook 'Revenue & Expenditure Summary Workbook
'*****************************Open CYTD files
my_Filename = Application.GetOpenFilename(fileFilter:="Excel Files,*.xl*;*.xm*", Title:="Select File to create CYTD Reports")
If my_Filename = False Then
Exit Sub
End If
Application.ScreenUpdating = False
Set wb2 = Workbooks.Open(my_Filename)
'*****************************Load Column Header Strings & Copy Data
For Each sht In SheetNames
lastcol = wb1.Sheets(sht).Cells(5, Columns.Count).End(xlToLeft).Column
On Error Resume Next
Set tabNames = wb1.Sheets(sht).Cells(4, 3).Resize(1, lastcol - 2).SpecialCells(xlCellTypeConstants)
'actual non-formula text values on row 4 from column C up to column lastCol'
On Error GoTo 0
If Err.Number <> 0 Then
MsgBox "No headers were found on row 4 of MHP60", vbCritical
Exit Sub
End If
For Each cell In tabNames
tabName = Strings.Trim(cell.Value2)
'dedicated variable in case of requirement for further parsing (space/comma elimination?)'
If CStr(wb1.Sheets(sht).Evaluate("ISREF('[" & wb2.Name & "]" & tabName & "'!$A$1)")) = "True" Then
'If wb2 has a tab named for the value in tabName
For i = 0 To UBound(addresses)
wb2.Sheets(tabName).Range(addresses(i)).Value2 = wb1.Sheets(sht).Range(addresses(i)).Offset(0, cell.Column - 1).Value2
'Debug.Print "data for " & wb2.Sheets(tabName).Range(addresses(i)).Address(, , , True) & " copied from " & wb1.Sheets("MHP60").Range(addresses(i)).Offset(0, cell.Column - 1).Address(, , , True)
Next i
Else
Debug.Print "A tab " & tabName & " was not found in " & wb2.Name
End If
Next cell
Next sht
MsgBox "CYTD Report Creation Complete", vbOKOnly
Application.ScreenUpdating = True
End Sub
Split by what?
SheetNames = Strings.Split("MHP60,MHP61,MHP62")
Split by comma? Then use the following instead:
SheetNames = Strings.Split("MHP60,MHP61,MHP62", ",")
Alternative
Dim SheetNames() As Variant ' needs to be Variant to work with Array()
SheetNames = Array("MHP60", "MHP61", "MHP62")
This should be quicker as your macro does not need to split the string and has it as array directly.
I have a few different arrays that are worksheets. What I want to build out is making this code print a group sheets via an array, where the "packages_to_print" array is equal to all the relevant array of sheets that need to printed. If this is not possible, is there a way to select multiple arrays to print?
This code doesn't give me an error, it just doesn't print anything to pdf.
Here's the relevant code. (The lender_package is the same as another variable because I have not built out the case statement for setting that variable to an array yet). Thank you in advance for your help.
Dim common_disclosures As Variant
Dim nh_disclosure As Variant
Dim provident_disclosures As Variant
Dim packages_to_print As Variant
Dim lender_package As Variant
common_disclosures = Array("Certification", "Responsible Use", "Security Procedures", "Acknowledgment", "FACTA Credit Score", "Anti-Steering")
nh_disclosures = Array("Loan Origination and Comp", "Rate Lock", "ECOA")
provident_disclosures = Array("MBFA")
lender_package = Array(provident_disclosures)
If subject_state <> "MA" Then
packages_to_print = Array(common_disclosures, nh_disclosures, lender_package)
Else
packages_to_print = Array(common_disclosures, lender_package)
End If
For j = 1 To (customerpackages * 2)
Worksheets(packages_to_print).Select _
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\users\" & environ_user & "\desktop\" & borrower_array(j - 1) & " disclosures.pdf" _
, Quality:=xlQualityMinimum, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
Next j
Actually you are using array of arrays in WorkSheets(..) expression. Try joining the arrays as packages_to_print and it is running OK.
If subject_state <> "MA" Then
packages_to_print = Split(Join(common_disclosures, ",") & "," & Join(nh_disclosures, ",") & "," & Join(lender_package, ","), ",")
Else
packages_to_print = Split(Join(common_disclosures, ",") & "," & Join(lender_package, ","), ",")
End If
Full Trial Code, may try it on any new workbook with 8-8 sheets
Sub test()
Dim common_disclosures As Variant
Dim nh_disclosures As Variant
Dim lender_package As Variant
Dim packages_to_print As Variant
common_disclosures = Array("Sheet1", "Sheet4", "Sheet3", "Sheet2", "Sheet5")
nh_disclosures = Array("Sheet2", "Sheet5")
lender_package = Array("Sheet6", "Sheet8")
subject_state = "MA"
If subject_state <> "MA" Then
packages_to_print = Split(Join(common_disclosures, ",") & "," & Join(nh_disclosures, ",") & "," & Join(lender_package, ","), ",")
Else
packages_to_print = Split(Join(common_disclosures, ",") & "," & Join(lender_package, ","), ",")
End If
Worksheets(packages_to_print).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\Users\user\Desktop\Book1.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
False
End Sub
I'm a VBA newbie and I'm trying to make an array from some text (i.e. the names of the worksheets) I have listed out in a column ("B") - so I can save all my worksheets as a single PDF file, but with the option of adding or removing worksheets over time (as in, rewriting them under wksAllSheets over and over again).
So far I have:
Public Sub saveAsPDF()
Application.ScreenUpdating = False
Call print_reports 'a sub I created with the printing layours
Dim wksAllSheets As Variant
Dim wksSheet1 As Worksheet
Dim strFilename, strName As String, strFilepath As String
Set wksSheet1 = ThisWorkbook.Sheets("SheetCOVER") 'reference ws
wksAllSheets = Array("SheetCOVER", "Sheet1", "Sheet2", "Sheet3", "Sheet4", _
"Sheet5", _
"Sheet6", "Sheet7", "Sheet8")
ThisWorkbook.Sheets(wksAllSheets).Select
wksSheet1.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strFilename, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
wksSheet1.Select
Sheets("Home").Select
End Sub
Any help would be extremely appreciated!!
Here is how to create an array from a table starting from "B1"
Dim n_rows as Long, n_cols as Long
Dim r as Range
Set r = Range("B1")
' Count non-empty cells
n_rows = Range(r, r.End(xlDown)).Rows.Count
n_cols = 1 ' Assume table has one column.
' Set the range variable 'r' to the entire table of cells
Set r = r.Resize(n_rows, n_cols)
Dim vals() as Variant ' This is the dynamic array spec
vals = r.Value ' Here you fill the array from the cells
Dim i as Long
For i=1 to n_rows
Debug.Pring vals(i,1) 'You access the array with (i,j): i=row, j=column
Next i
to dynamically build the list of sheets you can use the sheets collection
For Each ws In Sheets
Select Case ws.Name
Case "Home","COVER" ' exclude these sheets
Case Else 'include all others
wksAllSheets = wksAllSheets & IIf(wksAllSheets = "", "", ",") & ws.Name
End Select
Next
wksAllSheets = Split(wksAllSheets, ",")
to build the list from a specific column in a sheet of your workbook
wksallsheets=application.transpose(sheets("listpdf").range("B1:B" & sheets("listpdf").cells(rows.count,"B").end(xlup).row))
I have this code that gets all file types.
Dim file as variant
file = Application.GetOpenFilename("All Files, *.*", , "Select File", , True)
Then I have to print it in the cells on a sheet.
For i = 1 To UBound(file)
lRow = Cells(Rows.count, 15).End(xlUp).Row
lRow = lRow + 1
ThisWorkbook.Sheets("Main").Range("O" & lRow).Value = CStr(file(i))
Next i
but what I want is first check the contents of the array. If the array has this file type, then I have to remove it in the arraylist. After that, a message will pop out that this files are removed.
dim arr() as string
arr = Split("ade|adp|app|asp|bas|bat|cer|chm|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|inf|ins|isp|its|js|jse|" _
& "ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh2|" _
& "mshxml|msh1xml|msh2xml|ade|adp|app|asp|bas|bat|cer|chm|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|" _
& "hta|msi|msp|mst|ops|pcd|pif|plg|prf|prg|pst|reg|scf|scr|sct|shb|shs|ps1|ps1xml|ps2|ps2xml|psc1|psc2|tmp|url|vb|vbe|vbs|vsmacros|vsw|ws|wsc|wsf|wsh|xnk", "|")
I just don't know where I have to start. I have found a little bit same problem here in this post, but I just can't understand it. Thanks!
You can use a RegExp and a varaint array to do this quickly
This code looks for path... dot extension end string so it is more robust than your current array which may remove files based on the path name rather than file type
Sub B()
Dim fName As Variant
Dim objRegex As Object
Dim lngCnt As Long
Dim rng1 As Range
Set objRegex = CreateObject("vbscript.regexp")
On Error Resume Next
fName = Application.GetOpenFilename("All Files, *.*", , "Select file", , True)
If Err.Number <> 0 Then Exit Sub
On Error GoTo 0
With objRegex
.Pattern = ".*\.(ade|adp|app|asp|bas|bat|cer|chm|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|inf|ins|isp|its|js|jse|" _
& "ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh2|" _
& "mshxml|msh1xml|msh2xml|ade|adp|app|asp|bas|bat|cer|chm|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|" _
& "hta|msi|msp|mst|ops|pcd|pif|plg|prf|prg|pst|reg|scf|scr|sct|shb|shs|ps1|ps1xml|ps2|ps2xml|psc1|psc2|tmp|url|vb|vbe|vbs|vsmacros|vsw|ws|wsc|wsf|wsh|xnk)$"
`replace matching file types with blank array entries
For lngCnt = 1 To UBound(fName)
fName(lngCnt) = .Replace(fName(lngCnt), vbNullString)
Next
End With
Set rng1 = Cells(Rows.Count, 15).End(xlUp).Offset(1,0)
'dump array to sheet
rng1.Resize(UBound(fName), 1) = Application.Transpose(fName)
` remove blank entries
On Error Resume Next
rng1.SpecialCells(xlCellTypeBlanks).Delete xlUp
On Error GoTo 0
End Sub
One way would be to check that the extension it's not present in the blacklist with InStr:
Const exts = _
".ade.adp.app.asp.bas.bat.cer.chm.cmd.com.cpl.crt.csh.der.exe.fxp.gadget" & _
".hlp.hta.inf.ins.isp.its.js.jse.ksh.lnk.mad.maf.mag.mam.maq.mar.mas.mat" & _
".mau.mav.maw.mda.mdb.mde.mdt.mdw.mdz.msc.msh.msh1.msh2.mshxml.msh1xml" & _
".msh2xml.ade.adp.app.asp.bas.bat.cer.chm.cmd.com.cpl.crt.csh.der.exe.fxp" & _
".gadget.hlp.hta.msi.msp.mst.ops.pcd.pif.plg.prf.prg.pst.reg.scf.scr.sct" & _
".shb.shs.ps1.ps1xml.ps2.ps2xml.psc1.psc2.tmp.url.vb.vbe.vbs.vsmacros.vsw" & _
".ws.wsc.wsf.wsh.xnk."
Dim file As Variant
file = Application.GetOpenFilename("All Files, *.*", , "Select File", , True)
Dim i As Long, data(), count As Long, ext As String
ReDim data(1 To UBound(file) + 1, 1 To 1)
' filter the list
For i = LBound(file) To UBound(file)
ext = LCase(Mid(file(i), InStrRev(file(i), ".")))
If InStr(1, exts, ext & ".") = 0 Then ' if not blacklisted
count = count + 1
data(count, 1) = file(i)
End If
Next
' copy the filtered list to the next available row in column "O"
If count Then
With ThisWorkbook.Sheets("Main").Cells(Rows.count, "O").End(xlUp)
.Offset(1).Resize(count).Value = data
End With
End If
I have this:
column A
row1: str1;str2;str3
row2: str4;str5;str6
row3: str7;str8;str9
....................
rown: strn;strn;strn
The code below finds ";" character into the column A:
Range("A:A").Find(What:=";", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
I want to put all rows (from column A, containing semicolon character) into an array. I tried to use SET, like this:
dim r as Variant
Set r = Range("A:A").Find(What:=rngsearch, After:=ActiveCell, LookIn:=xlFormulas, LookAt:=_
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext,MatchCase:=False _
, SearchFormat:=False).Activate
...but doesn't work. It's run-time error '13', type mismatch
I need this array (containing all the cells with semicolon) because I want to extract the strings (from str1 to strn) and separate them in different rows.
Can anyone help me? Maybe someone has another idea how I can do this?
There are probably more efficient ways to do this, I would personally prefer to avoid referring to an entire column, but this should hopefully do what you are expecting:
Sub test()
Dim ws As Worksheet
Dim rng As Range
Dim cel As Range
Dim strTmp As String
Dim arrFinal As Variant
Set ws = Sheets("Sheet1")
Set rng = ws.Range("A:A")
' Loop through all cells in column A
For Each cel In rng.Cells
' Is there a semicolon character in the cell?
If InStr(1, cel.Value, ";") > 0 Then
' Add the cell value to strTmp and add a _
semicolon at the end to separate this _
row from the next row
strTmp = strTmp & cel.Value & ";"
End If
Next cel
' Split strTmp into an array
arrFinal = Split(strTmp, ";")
End Sub
The end result Is an array called arrFinal of all strings between the semicolon characters
I was referring to something like this:
Sub GetSemicolonData()
Dim rngCell As Excel.Range
Dim asValues() As String
Dim lngCount As Long
Dim x As Long
With Range("A1").CurrentRegion.Columns(1)
.AutoFilter field:=1, Criteria1:="*;*"
lngCount = .SpecialCells(xlCellTypeVisible).Count
If lngCount > 1 Then
x = 1
' exclude header row
ReDim asValues(1 To lngCount - 1)
For Each rngCell In .SpecialCells(xlCellTypeVisible)
If rngCell.Row > 1 Then
' load value into array
asValues(x) = rngCell.Value
x = x + 1
End If
Next rngCell
End If
End With
End Sub
You could also use a variation of Dave's approach that loads all the data into an array and processes that - it should be faster than cell by cell reads.