意外的手动分页行为。为什么 excel 在错误的行上添加额外的分页符/分页符?

Unexpected manual page break behavior. Why is excel adding extra page breaks / breaking on the wrong row?

我正在办公室自动创建一些文书工作。在一个 sheet 中,我让用户输入需要有选择地复制到某些其他工作 sheet 的数据,这些数据将被打印出来以供在生产车间使用。 目前我的 "Ship" sheet. 的格式有问题,第一个 sheet 是空的。预计用户将使用此页面通过手写 "Prep" sheet 上的行项目中 "Container Type & Number" 下列出的每个唯一的箱子、捆绑包和托盘来汇总装箱单,这在第 2(+) 页。

运行启用宏后,似乎 Excel 在我手动设置分页符的每一行之后立即添加了一个额外的分页符。当我在 "Page Layout" 视图中并切换到 "Ship" 工作 sheet 时,我正在使用的当前示例数据似乎有 5 页长。但是,数据应该只需要 2 页,再加上封面 sheet,总共 3 页。第 2 页和第 4 页似乎只有一行,滚动时会快速跳转到下一页。另外,我刚刚注意到我用于第 2+ 页的页眉仅出现在第 2 页的单行上方以及第 3 页上显示的 "page 2" 的其余部分。第 4 页和第 4 页的页眉根本没有出现5. 这个问题很难捕捉到的是打印预览总共只显示了3页,之前应该有手动分页符的行被移动到前一页的最后一行。

我尝试用三种稍微不同的方式编写这个宏: 1. Sheet.Rows(#).PageBreak = xlPageBreakManual 2. Sheet.HPageBreaks.Add之前:=Sheet.Rows(#) 3. Sheet.HPageBreaks(#).Location = Sheet.Range("A" & #)

注意:我在遇到选项 (3) 的重复 "Run-time error '9': Subscript out of range" 错误后从 Microsoft 找到这篇文章,并相应地重新编码该选项 https://support.microsoft.com/en-us/help/210663/you-receive-a-subscript-out-of-range-error-message-when-you-use-hpageb

最奇怪的是,如果我在调试模式下逐行进入选项 (3),宏实际上会正确格式化页面...

相关代码如下:

Option Explicit

'Public sSht As Worksheet
'Public sDatRng As Range, pDatRng As Range, pCopyRng As Range
'Public sCopyRow As Long, pCopyRow As Long
'Public sNumRows As Long, sHeadFootRows As Long, pNumRows As Long, pHeadFootRows As Long

Sub formatShipV1(numPgs As Long)
    Dim rng As Range
    Dim i As Long
    Dim currcell As Range

    Application.PrintCommunication = False

    With sSht
        .Cells.PageBreak = xlPageBreakNone

        With .PageSetup
            .Zoom = False
            .PaperSize = xlPaperLetter
            .Orientation = xlPortrait
            .PrintArea = sSht.Range("A1:J" & ((sNumRows + sHeadFootRows) + (numPgs * (pNumRows + pHeadFootRows)))).Address
            .LeftMargin = Application.InchesToPoints(0.2)
            .RightMargin = Application.InchesToPoints(0.2)
            .TopMargin = Application.InchesToPoints(0.6)
            .BottomMargin = Application.InchesToPoints(0.6)
            .HeaderMargin = Application.InchesToPoints(0.1)
            .FooterMargin = Application.InchesToPoints(0.1)
            .FitToPagesWide = 1
            .FitToPagesTall = numPgs + 1
            .CenterHorizontally = True
            .CenterVertically = False
        End With

        For i = 0 To (numPgs - 1)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1).PageBreak = xlPageBreakManual

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1).RowHeight = Application.InchesToPoints(0.25)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 2).RowHeight = Application.InchesToPoints(0.3)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 3).RowHeight = Application.InchesToPoints(0.19)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 4).RowHeight = Application.InchesToPoints(0.57)

            Set rng = sSht.Range(Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 5), 1).Address & ":" & Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 26), 10).Address)
            rng.RowHeight = Application.InchesToPoints(0.38)

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 27).RowHeight = Application.InchesToPoints(0.23)
        Next
    End With

    Application.PrintCommunication = True
End Sub

Sub formatShipV2(numPgs As Long)
    Dim rng As Range
    Dim i As Long
    Dim currcell As Range

    Application.PrintCommunication = False

    With sSht
        .ResetAllPageBreaks

        With .PageSetup
            .Zoom = False
            .PaperSize = xlPaperLetter
            .Orientation = xlPortrait
            .PrintArea = sSht.Range("A1:J" & ((sNumRows + sHeadFootRows) + (numPgs * (pNumRows + pHeadFootRows)))).Address
            .LeftMargin = Application.InchesToPoints(0.2)
            .RightMargin = Application.InchesToPoints(0.2)
            .TopMargin = Application.InchesToPoints(0.6)
            .BottomMargin = Application.InchesToPoints(0.6)
            .HeaderMargin = Application.InchesToPoints(0.1)
            .FooterMargin = Application.InchesToPoints(0.1)
            .FitToPagesWide = 1
            .FitToPagesTall = numPgs + 1
            .CenterHorizontally = True
            .CenterVertically = False
        End With

        For i = 0 To (numPgs - 1)
            .HPageBreaks.Add Before:=sSht.Rows(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1))

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1).RowHeight = Application.InchesToPoints(0.25)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 2).RowHeight = Application.InchesToPoints(0.3)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 3).RowHeight = Application.InchesToPoints(0.19)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 4).RowHeight = Application.InchesToPoints(0.57)

            Set rng = sSht.Range(Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 5), 1).Address & ":" & Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 26), 10).Address)
            rng.RowHeight = Application.InchesToPoints(0.38)

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 27).RowHeight = Application.InchesToPoints(0.23)
        Next
    End With

    Application.PrintCommunication = True
End Sub

Sub formatShipV3(numPgs As Long)
    Dim rng As Range
    Dim i As Long
    Dim currcell As Range

    Call endOptimize
    Set currcell = ActiveCell
    Range("IV65536").Select

    Application.PrintCommunication = False

    With sSht
        .Activate
        ActiveWindow.View = xlPageBreakPreview
        .ResetAllPageBreaks

        With .PageSetup
            .Zoom = False
            .PaperSize = xlPaperLetter
            .Orientation = xlPortrait
            .PrintArea = sSht.Range("A1:J" & ((sNumRows + sHeadFootRows) + (numPgs * (pNumRows + pHeadFootRows)))).Address
            .LeftMargin = Application.InchesToPoints(0.2)
            .RightMargin = Application.InchesToPoints(0.2)
            .TopMargin = Application.InchesToPoints(0.6)
            .BottomMargin = Application.InchesToPoints(0.6)
            .HeaderMargin = Application.InchesToPoints(0.1)
            .FooterMargin = Application.InchesToPoints(0.1)
            .FitToPagesWide = 1
            .FitToPagesTall = numPgs + 1
            .CenterHorizontally = True
            .CenterVertically = False
        End With

        For i = 0 To (numPgs - 1)
            Set .HPageBreaks(i + 1).Location = sSht.Range("A" & ((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1))
            DoEvents

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 1).RowHeight = Application.InchesToPoints(0.25)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 2).RowHeight = Application.InchesToPoints(0.3)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 3).RowHeight = Application.InchesToPoints(0.19)
            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 4).RowHeight = Application.InchesToPoints(0.57)

            Set rng = sSht.Range(Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 5), 1).Address & ":" & Cells(((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 26), 10).Address)
            rng.RowHeight = Application.InchesToPoints(0.38)

            .Rows((sNumRows + sHeadFootRows) + (i * (pNumRows + pHeadFootRows)) + 27).RowHeight = Application.InchesToPoints(0.23)
        Next

        ActiveWindow.View = xlPageLayoutView

    End With

    Application.PrintCommunication = True

    sSht.Activate
    sSht.Range(currcell.Address).Select
    Call startOptimize
End Sub

Sub startOptimize()
    Application.ScreenUpdating = False
    Application.DisplayStatusBar = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    ActiveSheet.DisplayPageBreaks = False
End Sub

Sub endOptimize()
    Application.ScreenUpdating = True
    Application.DisplayStatusBar = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    ActiveSheet.DisplayPageBreaks = True
End Sub

'Sub runMacro()
'    Call startOptimize
'    ...
'    Dim sNumSht As Long
'    ...
'    Other variable declarations
'    ...
'    Set sSht = datBk.Worksheets("Ship")
'    Set sDatRng = sSht.Range("B6:J27")
'    Set pDatRng = sSht.Range("B32:J53")
'    Set pCopyRng = sSht.Range("A28:J54")
'    sNumRows = 22
'    sHeadFootRows = 5
'    pCopyRow = 55
'    pNumRows = 22
'    pHeadFootRows = 5
'    ...
'    Other variable initializations
'    ...
'    Code to calculate what data to copy to the "Ship" sheet, and how many pages "sNumSht" should equal
'    ...
'    Call formatShipV1((sNumSht + 1))
'    '-OR-
'    Call formatShipV2((sNumSht + 1))
'    '-OR-
'    Call formatShipV3((sNumSht + 1))
'    ...
'    Code to copy previously determined data to ship sheet
'    ...
'    Code to execute the rest of the macro
'    ...
'    Call endOptimize
'End Sub

"Ship" sheet [通过 "stepping into" 选项 (3) 生成] 的预期格式:

"Ship" sheet 的实际格式(通常 运行 时的选项 1-3):

-如 Excel 中所示(仅显示第 1-3 页,共 5 页):

-通过 Excel 的打印预览打印为 PDF:

许多附近休息的原因:
它们可能是在密集测试期间输入的。

错误背景:

  • 您尝试先通过 Worksheet.Cells.PageBreak = xlPageBreakNone 重置所有分页符。
    那没有用,所以您所有的手动测试休息时间仍然存在。

  • 如果定义PageSetup.Zoom = FalsePageSetup.FitToPagesTall = 3
    那么额外的手动分页符不会生效。
    仍然可以设置手动中断,但既无效也不可见。


解决方案 1:如果 ...

  • 打印区域适合页面宽度通常没问题
  • 与自动缩放
  • 相比,您的任何页面的行数必须
  • 和 none 页面的行数必须比自动缩放

...然后如下设置手动水平分页符:

  1. 先按Worksheet.ResetAllPageBreaks

  2. 重置所有分页符
  3. 然后通过
    定义分页符的自动部分 PageSetup.FitToPagesWide = 1
    Pagesetup.FitToPagesTall = False
    不要设置缩放。它被上面的行设置为 False。

  4. 在每页末尾放置一个手动水平分页符,其包含的行数应少于自动设置的行数。从上到下这样做。


解决方案 2:如果您的任何页面需要比上面 多行 ,那么这样做:

  1. 先按 Worksheet.ResetAllPageBreaks
  2. 重置所有分页符
  3. 定义合适的缩放级别,适合多行的页面,例如。 g.
    PageSetup.Zoom = 80
    PageSetup.FitToPagesWide = False
    PageSetup.FitToPagesTall = False
  4. 放置手动水平分页符以根据需要缩短页面。从文档的开头到结尾都这样做。

可以通过以下任一方法设置手动水平分页符:

  • Worksheet.HPageBreaks.Add Before:=ws.Rows(10)
  • Worksheet.Rows(10).PageBreak = xlPageBreakManual

第一种方法比第二种faster


Worksheet.HPageBreaks.Count 将显示打印区域中的水平分页符数,包括自动分页符。下面不会"convert"先自动分页。它只移动第一个手动中断,如果至少有一个:

  • Set Worksheet.HPageBreaks(1).Location = ws.Rows(20)