With wb
Set Sh2 = .Sheets("sheet2)
With Sh2.PageSetup
.PrintArea = "$B$2:$S$80"
.PaperSize = xlPaperLegal
End With
Set Sh3 = .Sheets("sheet3")
With Sh3.PageSetup
.PrintArea = "$B$2:$M$104"
.PaperSize = xlPaperLegal
.Orientation = xlPortrait
End With
Set execsum1 = .Sheets("sheet4")
With execsum1.PageSetup
.PrintArea = "$B$7:$N$63"
.PaperSize = xlPaperLegal
.Orientation = xlLandscape
.PrintTitleRows = "$B$2:$N$6"
End With
Set execsum2 = .Sheets("sheet5")
With execsum2.PageSetup
.PrintArea = "$B$64:$N$106"
.PaperSize = xlPaperLegal
.Orientation = xlLandscape
.PrintTitleRows = "$B$2:$N$6"
End With
'ActiveSheet.PrintPreview
Set noi1 = .Sheets("sheet6")
With noi1.PageSetup
.PrintArea = "$B$10:$N$44"
.PaperSize = xlPaperLegal
.Orientation = xlLandscape
.PrintTitleRows = "$B$2:$N$8"
.FitToPagesTall = 1
End With
Set noi2 = .Sheets("sheet7")
With noi2.PageSetup
.PrintArea = "$B$46:$N$192"
.PaperSize = xlPaperLegal
.Orientation = xlLandscape
.PrintTitleRows = "$B$2:$N$8"
'.FitToPagesWide = 1
.FitToPagesTall = 1
End With
End With
Dim sheet As Variant
For Each sheet In Array(execsum1, execsum2, Sh2, Sh3, noi1, noi2)
sheet.PrintOut Copies:=1
Next
'Save and Close Workbook
'wb.Close SaveChanges:=False
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
Hello all, I'm new to VBA and I'm trying to print 6 worksheets/pages per workbooks found in a folder. Execsum1 and execsum2 are from the same worksheet with different print areas; same story with noi1 and noi2. When I run the code, it prints out the second designated page twice (execsum2 and noi2). Why isn't execsum1/noi1 printing out and if possible, how can I make the code more efficient? Thanks.
It prints the same sheet twice because you aren't printing the worksheet between changing the PageSetup from your first version to your second version. You collect worksheet references here...
Set execsum1 = .Sheets("Exec Summary")
'...
Set execsum2 = .Sheets("Exec Summary")
...that are identical to each other. A worksheet only has 1 PageSetup, so when you do this...
For Each sheet In Array(execsum1, execsum2, Sh2, Sh3, noi1, noi2)
sheet.PrintOut Copies:=1
Next
...you get the last thing it was set to.
Just skip the loop entirely and print each individually. There is absolutely no benefit to looping over them.
With execsum1.PageSetup
.PrintArea = "$B$7:$N$63"
.PaperSize = xlPaperLegal
.Orientation = xlLandscape
.PrintTitleRows = "$B$2:$N$6"
End With
execsum1.PrintOut Copies:=1 '<--- After each With block.
If you want to simplify the code, just extract out the common .PageSetup into a function, and pass everything else as a parameter (note that this is just an example - I didn't include everything you're using). I.e.:
Private Sub PrintCustomRange(sheet As Worksheet, area As String, title As String, _
orient As XlPageOrientation, paper As XlPaperSize)
With sheet.PageSetup
.PrintArea = area
.PaperSize = paper
.Orientation = orient
If Len(title) > 0 Then .PrintTitleRows = title
End With
.PrintOut Copies:=1
End Sub
Then call it like this:
PrintCustomRange Sheets("Proforma NOI"), "$B$46:$N$192", "$B$2:$N$8", xlLandscape, xlPaperLegal
Related
I am trying to save my worksheet as a pdf file with the use of vba. The worksheet is wider than an A4 page and contains a few shapes (side to side). I want the worksheet to fit on one A4 page, so it should be rescaled as seen on screen. I am using the following code:
Sub Print_PDF()
Dim sFilename As String
Worksheets.Add.Name = "Helpsheet"
sFilename = "G:\anything\test.pdf"
ThisWorkbook.Worksheets("Newsletter").Range("A2:D81").CopyPicture xlScreen, xlBitmap
ThisWorkbook.Sheets("Helpsheet").Activate
ThisWorkbook.Sheets("Helpsheet").Paste
ActiveSheet.PageSetup.PrintArea = ThisWorkbook.Sheets("Helpsheet").Range("A1:O86")
With ActiveSheet.PageSetup
.Orientation = xlPortrait
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
ThisWorkbook.Sheets("Helpsheet").ExportAsFixedFormat Type:=xlTypePDF, Filename:=sFilename, quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
Application.DisplayAlerts = False
ThisWorkbook.Sheets("Helpsheet").Delete
Application.DisplayAlerts = True
End Sub
The code actually saves a PDF file in the expected location. However, the PDF file is 4 pages instead of the expected 1 page. So it seems that the printarea is not defined correctly. What am I doing wrong?
Have you tried adjusting your PageSetup parameters as per this example?
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.Zoom = False
'.PrintArea = Worksheets(ReportWsName).UsedRange
.FitToPagesWide = 1
'.FitToPagesTall = 1
End With
Application.PrintCommunication = True
Think explicitly setting .Zoom to false is important.
Source:
excel vba not exporting pagesetup to pdf correctly
Assuming the activesheet is also the sheet("Helpsheet")
The print area need the address of the print range.
ActiveSheet.PageSetup.PrintArea = ThisWorkbook.Sheets("Helpsheet").Range("A1:O86").Address
I am new to excel macros, I am working on creating a macro which needs to format the cells and also to generate the bar code for column A. Created a function Code128() to convert the string in to bar code as given in the blog and it works fine.
I am using them in the macros I am creating like below
With ActiveSheet.PageSetup
.PrintTitleRows = "$1:$1"
.PrintGridlines = True
.Orientation = xlLandscape
.PaperSize = xlPaperA4
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
End With
Columns("A").ColumnWidth = 10
For Each Target In Range("A1", Range("A" & Rows.Count).End(xlUp))
If Target.Value <> vbNullString Then
Target.Value = PERSONAL.XLSB!Code128(Target.Value)
Target.Resize(, 12).WrapText = True
Target.Font = "Code 128"
End If
Next
Next
But when I run the macro on the excel I am getting the run time error like
You should be able to use Application.Run to evaluate a function that exists in another workbook. The format of that is:
Target.Value = Application.Run("PERSONAL.XLSB!Module2.Code128", Target.Value)
Or more generally:
= Application.Run(workbookname$ & "!" & modulename & "." & functionname, args())
Barring that, you could Add a reference to Personal.xlb in your Book1.
I have this code to set the print area of certain sheets in a workbook. I'm trying to set the print area so it fits each tab on one page and doesn't divide it into several pages. Also could someone please help me with code to not set the print area on certain tabs based on the same cell value in each tab?
Sub PrintArea()
Dim I As Integer
Dim ws As Worksheet
WS_Count = ActiveWorkbook.Worksheets.Count
For I = 1 To 6
Set ws = ThisWorkbook.Sheets(I)
ws.PageSetup.PrintArea = ws.Range("A1:Z24").Address
With ws.PageSetup
.Orientation = xlLandscape
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Next I
End Sub
You were almost there. You can loop through the worksheets directly and not have to reference them with a counter.
This should set you up pretty nicely :)
Sub PrintArea()
Application.ScreenUpdating = False
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
Select Case ws.Index
Case Is = 1, 2, 3, 4, 5, 6 'only perform action on first 6 sheets
If ws.Range("A25") = "Yes" Then 'adjust to desired range and indicator
With ws.PageSetup
.PrintArea = ws.Range("A1:Z24").Address
.Orientation = xlLandscape
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
'set print area to only 1 page
With ws
.Activate 'need to activate sheet to view Page Break Preview
ActiveWindow.View = xlPageBreakPreview 'need to view Page Break Preview to drag page breaks
.VPageBreaks(1).DragOff Direction:=xlToRight, RegionIndex:=1 `drag page over so it's just one page
ActiveWindow.View = xlNormalView 'set view back to normal
End With
End If
End Select
Next ws
End Sub
One needs to set not just the .FitToPagesWide = 1 and .FitToPagesTall = 1 but also, .Zoom = false. The code snippet should be:
Sub PrintArea()
Application.ScreenUpdating = False
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
Select Case ws.Index
Case Is = 1, 2, 3, 4, 5, 6 'only perform action on first 6 sheets
If ws.Range("A25") = "Yes" Then 'adjust to desired range and indicator
With ws.PageSetup
.PrintArea = ws.Range("A1:Z24").Address
.Zoom = False
.Orientation = xlLandscape
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
'set print area to only 1 page
With ws
.Activate 'need to activate sheet to view Page Break Preview
ActiveWindow.View = xlPageBreakPreview 'need to view Page Break Preview to drag page breaks
.VPageBreaks(1).DragOff Direction:=xlToRight, RegionIndex:=1 `drag page over so it's just one page
ActiveWindow.View = xlNormalView 'set view back to normal
End With
End If
End Select
Next ws
End Sub
For me worked this code, actually zoom seted to False changed the behavior. This can be called without activation of each sheet:
Public Function SetPrintArea(rows As Integer, cols As Integer)
Dim MySheet As Excel.Worksheet
MySheet = Globals.ThisAddIn.Application.Worksheets(sheetname)
MySheet.PageSetup.PrintArea = MySheet.Range(MySheet.Cells(1, 1),
MySheet.Cells(rows, cols)).Address
MySheet.PageSetup.FitToPagesWide = 1
MySheet.PageSetup.FitToPagesTall = 1
MySheet.PageSetup.Orientation = 2 '2 is code for xlLandscape
MySheet.PageSetup.Zoom = False
End Function
So I've been playing around with macros and buttons and I am trying to make a button, that on clicking it, it will go to the previous sheet (they are names Day 1, 2, 3, etc...) so I figure this shouldn't be too difficult!
Here is the code that I have got so far:
Sub Previous_Day()
Worksheets("Day " & (sheetNum - 1)).Visible = xlSheetVisible
Worksheets("Day " & (sheetNum - 1)).Activate
Worksheets("Day " & sheetNum).Visible = xlSheetHidden
sheetNum = sheetNum - 1
End Sub
I get an error when I click the button with this which says "subscript out of range", I'm not entirely sure why this is happening, I globally define sheetNum in the 'This Workbook' module, and I shall show that code below:
Public sheetNum As Integer
Private Sub Workbook_Open()
Dim thisSheet As Worksheet
Dim sh As Worksheet
Dim start As Worksheet
Dim shName As String
Dim lastSheet As String
'name of the sheet template
shName = "Food Diary Template.xltm"
lastSheet = "Food Diary Last Entry.xltm"
Set start = Worksheets(1)
With start
If .Range("A1") = "" Then
.Range("A1") = Date
ActiveSheet.Shapes("Button 5").Select
Selection.Delete
.Range("B4").Select
End If
End With
Worksheets(Sheets.Count).Activate
'#### I like to use variables for worksheets:
Set thisSheet = ThisWorkbook.ActiveSheet
'Insert sheet template
With thisSheet
If .Range("A1") < Date Then
ActiveSheet.Buttons.Add(436.5, 104.25, 58.5, 18.75).Select
Selection.OnAction = "nextDay_Click"
ActiveSheet.Shapes("Button 1").Select
Selection.Characters.Text = "Button 1"
With Selection.Characters(start:=1, Length:=8).Font
.Name = "Calibri"
.FontStyle = "Regular"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
End With
ActiveSheet.Shapes("Button 1").Select
Selection.Characters.Text = "Next Day"
With Selection.Characters(start:=1, Length:=8).Font
.Name = "Calibri"
.FontStyle = "Regular"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
End With
.Range("B4").Select
Set sh = Sheets.Add(Type:="C:\Users\edawes\AppData\Roaming\Microsoft\Templates\" & lastSheet, _
after:=Sheets(Sheets.Count))
'#### Put today's date in the new sheet:
sh.Range("A1") = Date
sh.Name = "Day " & Worksheets.Count
'Worksheets(sh).Active
sh.Range("B4").Select
'#### Hide the old sheet
.Visible = xlSheetHidden
End If
End With
sheetNum = Sheets.Count
End Sub
This bit works fine as I want it to, but it's the sheetNum that I'm not sure about, have I done it right? I want it to be the total number of sheets when the file is opened and then when the button is pressed, (there is also a next day button, but that will be pretty simple when I get this one working), it will update the sheetNum variable so that it can keep track and the previous button can keep being pressed...
Any ideas?
You could just parse the Name of he active sheet, subtract one from the day number and activate the previous sheet.
Sub ButtonCode()
dy = CLng(Split(ActiveSheet.Name, " ")(1))
dy = dy - 1
If dy = 0 Then Exit Sub
Sheets("Day " & dy).Activate
End Sub
So if the name of the active sheet is Day 4, then sheet Day 3 would be activated.
I wonder if anybody can help me. I have a macro which selects sheets that are named as employees and puts them into the correct workbook dependant on where they work.
I have made the macro so that it selects all sheets for the depot then copies them into a new workbook.
My problem is when it can't find one of the sheets it skips all of them for that location workbook. and moves to the next location. Is there a way round this so if the macro can't find one of the sheets it moves the rest of them anyway.
Sub BIR()
On Error GoTo Getout
Sheets(Array("Martyn Arthur Lewis", "Norman Stewart Gray")).Move
Sheets.Select
For Each ws In Worksheets
ws.Activate
With ActiveSheet.PageSetup
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.Orientation = xlLandscape
.Draft = False
.PaperSize = xlPaperA4
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = 90
.printerrors = xlPrintErrorsBlank
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = False
End With
Next
ChDir "\\afi-uplift\documents\company\Support Services\Support Services Level 1\Reports\Transport Reports\Vehicle KPI"
ActiveWorkbook.SaveAs Filename:="\\afi-uplift\documents\company\Support Services\Support Services Level 2\Support Services\Transport\Drivers\Driver Performance\BIR Driver KPI " & Format(Date, "yyyy.mm.dd") & ".xlsx" _
, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Windows("Driver Report.xlsm").Activate
Getout:
End Sub
I don't understand why people always need to use .select and .activate
First it slows the program, and second, usualy, you don't even need to select/activate.
Doesn't your code work if you write it like this :
option explicit 'forces user to dim variables, , alot easier to find errors
err.clear
on error goto 0 'how can you debug errors with a on error goto (or on error resume next) ?
dim ws as worksheet
For Each ws In Sheets(Array("Martyn Arthur Lewis", "Norman Stewart Gray"))
With ws.PageSetup
'your code
end with
next ws