excelvbaexcel-2021

Can a page break be added based on where there is already an automatic page break?


Ok. I have a sheet that fills certain cells based on answers to questions on another sheet. Some cells end up empty. At the end, I have a sub that hides all the blank rows to prep the document for printing. The first page needs a larger top margin to allow for a picture in the header. Following pages need smaller top margins.

I have other sheets that are similar, but don't end up with the blank row issue. I've managed to get them to print the first page with a 3" top margin and the second page with a 1" top margin. However, I can easily tell where I need to tell it to put a page break when looking at the 3" margin in order to make sure text doesn't move up to page one when setting the second page to the 1". If I don't add the page break, then as the margin decreases, text from page two moves to page one and then when page two prints, I lose text.

With a sheet that will have variable page break locations, is it possible to have vba look at the document after the 3" margin is set... see where the auto page breaks are and then set a manual page break in those locations? It would need to reset any manual page breaks previously set prior to doing that too.

I also have some tunnel vision going on, is there some other logic I can use to accomplish this?

This is what I have for a sheet that will print two pages and does not have to fight with the blank rows issue. I have it to set add the page break to the right spot, then it's set up for the variable margins.

Private Sub PrintOddEvenag()

    Dim lTotal As Long
    Dim a As Long
    Dim lNum As Long
    With ActiveSheet

        .PageSetup.PrintArea = .Range("A1:AH26").Address
        .Rows(17).PageBreak = xlPageBreakManual
        ActiveWindow.View = xlPageBreakPreview
        lTotal = .HPageBreaks.Count + 1
        For a = 1 To lTotal
            lNum = lNum + 1
            If lNum Mod 2 <> 0 Then
                With .PageSetup
                    .LeftMargin = Application.InchesToPoints(0.7)
                    .RightMargin = Application.InchesToPoints(0.7)
                    .TopMargin = Application.InchesToPoints(3)
                    .BottomMargin = Application.InchesToPoints(0.75)

                End With
                .PrintOut From:=lNum, To:=lNum
            Else
                With .PageSetup
                    .LeftMargin = Application.InchesToPoints(0.7)
                    .RightMargin = Application.InchesToPoints(0.7)
                    .TopMargin = Application.InchesToPoints(1)
                    .BottomMargin = Application.InchesToPoints(0.75)

                End With
                .PrintOut From:=lNum, To:=lNum
            End If
        Next a
    End With
    ActiveWindow.View = xlNormalView
End Sub

Solution

  • I think your question could have benefited from an image to illustrate the problem, so here is one I produced while testing.

    enter image description here


    Alternative approches

    Unlike Word, Excel wasn't made with advanced formatting differences between odd and even pages. So an option to consider would be to paste your tables into Word and then do the printing from there (Option 1):

    enter image description here

    If that's not viable for your case, you could also consider spliting the content into multiple Excel sheets where each of them have a different margin (Option 2).

    Otherwise, you could always add empty rows inside your sheet to appear at the top of odd sheets to replace the need to add margins with .PageSetup (Option 3).


    Solution with current approach

    If you want to stick to your current approach, you can save the location of the automatic pagebreak by making it manual so it stays in place for the next page (put this right before Next a):

    .HPageBreaks(a).Location.PageBreak = xlPageBreakManual
    

    Btw, your code makes use of the variable a and lNum but they are always equal so you could simply replace lNum by a.

    Then, also make sure to remove any page break set manually by using .ResetAllPageBreaks at the start of your procedure.