【问题标题】:How to identify page breaks in excel with VBA, varying conditions如何在不同条件下使用 VBA 识别 excel 中的分页符
【发布时间】:2020-01-28 18:12:37
【问题描述】:

这是我一直在努力解决的问题。请原谅我没有引用我研究过的确切线程,但我没有记录日志。我下面的代码示例是通过查看有关此主题的许多线程构建的。但是,我需要的确切解决方案仍然无法解决。

简单地说:在 Excel VBA 中,我需要能够在动态创建后识别长表中每一页的最后一行和第一/最后一列,该长表的长度可能为 1 到 5 页(水平)和人口稠密。我也很欣赏一种快速确定填充数据停止位置的方法,但如果没有简单的解决方案,可以从生成例程中获取。以下代码将识别单个页表的正确最后一行和一列......一次。我可以进行必要的修改以检查多页表的后续页面。我遇到的真正问题是,一旦填充并清除了一个单元格,excel就会将该单元格包含在已用单元格的范围内。相同代码的后续执行失败,因为不再正确识别最后一个单元格。有没有办法扭转这种情况,或者我可以采取不同的方法?

我真的不喜欢填充单元格并删除它们来查找分页符,但我还没有找到避免这样做的解决方案。感谢您提供的任何指导。 ,迈克·沙纳汉

Sub Findpagebreaks()

Dim x As HPageBreaks, pb_x As HPageBreak
Dim y As VPageBreaks, pb_y As VPageBreak, PageMatrix() As Integer
Dim LastPopulated(1) As Integer, test As Integer, target As Integer

ReDim PageMatrix(1 To 1, 0 To 2) As Integer
With ActiveSheet
    Debug.Print "============================================"

    Debug.Print "Horizontal Page Breaks"
    Set x = .HPageBreaks
    Debug.Print "Initial Hbreaks: ", x.Count
    LastPopulated(0) = .Cells.SpecialCells(xlCellTypeLastCell).Row
    Debug.Print "Last row of data: ", LastPopulated(0)
    target = x.Count + 1
    test = LastPopulated(0)
    Do While x.Count < target
        test = test + 10
        .Cells(test, 1).Value = "."
        Debug.Print "cell: " & .Cells(test, 1).Address & " populated"
        If test > 100 Then Exit Do
    Loop
    For Each pb_x In x
        If pb_x.Extent = xlPageBreakFull Then
            Debug.Print "Row: " & pb_x.Location.Row, "Full Page Break"
            PageMatrix(1, 2) = pb_x.Location.Row - 1
        Else
            Debug.Print "Row: " & pb_x.Location.Row, "Partial Page Break"
        End If
    Next pb_x
    .Range(.Cells(LastPopulated(0) + 1, 1), .Cells(test, 1)).ClearContents
    Debug.Print "cells: " & .Range(.Cells(LastPopulated(0), 1), .Cells(test, 1)).Address & " cleared."
    Debug.Print "Horizontal Exploration complete."


    Debug.Print "Vertical Page Breaks"
    Set y = .VPageBreaks
    Debug.Print "Initial vbreaks: ", y.Count
    LastPopulated(1) = .Cells.SpecialCells(xlCellTypeLastCell).Column
    Debug.Print "Last column of data: ", LastPopulated(1)
    target = y.Count + 1
    test = LastPopulated(1)
    Do While y.Count < target
        test = test + 10
        .Cells(1, test).Value = "."
        Debug.Print "cell: " & .Cells(1, test).Address & " populated"
        If test > 100 Then Exit Do
    Loop
    PageMatrix(1, 0) = 1
    For Each pb_y In y
        If pb_y.Extent = xlPageBreakFull Then
            Debug.Print "column: " & pb_y.Location.Column, "Full Page Break"
            PageMatrix(1, 1) = pb_y.Location.Column - 1
        Else
            Debug.Print "Row: " & pb_y.Location.Column, "Partial Page Break"
        End If
    Next pb_y
    .Range(.Cells(1, LastPopulated(1) + 1), .Cells(1, test)).ClearContents
        Debug.Print "cells: " & .Range(.Cells(1, LastPopulated(1)), .Cells(1, test)).Address & " cleared."
    Debug.Print "Vertical Exploration complete."


    Debug.Print "Page", "First Col", "Last Col", "Last Row"
    Debug.Print 1, PageMatrix(1, 0), PageMatrix(1, 1), PageMatrix(1, 2)
    Debug.Print "~~~~~~~~~~~~~~~~~~~~~~"
    Debug.Print "Sub complete."
    Debug.Print

End With
End Sub

【问题讨论】:

  • xlCellTypeLastCell 不是您想要使用的。看看GetLastCell函数here
  • 谢谢 Yan F。我会研究那个功能。

标签: excel vba


【解决方案1】:

不是一个完整的答案,但大大减少了一些代码。

当然看起来很多代码只是为了找到分页符。对于分页符,试试这个简单的例程。根据您的情况进行修改。

Sub Sample()
  'Horizontal Pagebreaks
  For h = 1 To 100
    If Sheets("Sheet1").Rows(h).PageBreak <> xlPageBreakNone Then MsgBox "Hor " & n
  Next
  'Vertical Pagebreaks
  For v = 1 To 100
    If Sheets("Sheet1").Columns(v).PageBreak <> xlPageBreakNone Then MsgBox "Ver " & n
  Next

End Sub

【讨论】:

  • 谢谢米奇。不幸的是,这只适用于已建立的分页符。当数据尚未跨越时,我需要能够找到分页符(即 .VPageBreaks.Count = 0)。不过没关系,我认输并选择更简单的方法,如果不那么复杂的话。
【解决方案2】:
Sub List_VPageBreaks()
Set f = ThisWorkbook.Worksheets("Sheet2")
For i = 1 To f.VPageBreaks.Count
 Worksheets("Sheet3").Cells(i, 1).value=f.VPageBreaks(i).Location.Column
Next
End Sub

【讨论】:

  • 谢谢Docmarti。不幸的是,这只适用于已建立的分页符。当数据尚未跨越时,我需要能够找到分页符(即 .VPageBreaks.Count = 0)。不过没关系,我认输并选择更简单的方法,如果不那么复杂的话。
【解决方案3】:

该行是否在风险区内?使用和修改此功能

Function PageBreak(iRow As Integer) As Boolean
Dim wsBook As Workbook
Dim ws As Worksheet

Set wsBook = ActiveWorkbook
Set ws = wsBook.ActiveSheet

Dim iCellHeight As Integer, i As Integer
Dim iSense As Integer, iBreak As Integer, iPage As Integer

'How sensitive +/- should the PageBreak be?
iSense = 32
'At what height does your printer brake? 'PageBreak 757 <> 758
iBreak = 758

'Sum of all pages
For i = 1 To iRow
    iCellHeight = iCellHeight + ws.Cells(i, 1).Height
Next i

'How many pages
iPage = iCellHeight \ (iBreak + iSense) + 1
'Get height from last page
iCellHeight = iCellHeight \ iPage

If (iCellHeight > iBreak - iSense And iCellHeight < iBreak + iSense) Then
    PageBreak = True
Else
    PageBreak = False
End If

End Function

【讨论】:

    【解决方案4】:

    所以我选择了一种解决方案,可以减少编码并制作更强大的产品。这不是我正在寻找的复杂答案,仍然属于蛮力方法,但它绝对不那么繁琐。

    这是我目前最好的。如果有人找到更优雅的解决方案,请随时发布!谢谢大家。

    Sub Findpagebreaks()
    
    Dim y As VPageBreaks, pb_y As VPageBreak, PageMatrix() As Integer
    Dim LastPopulated(1) As Integer, roww As Integer, coll As Integer
    Dim lastpage As Integer, LookingForLastPage As Boolean, last_row As Integer
    
    ReDim PageMatrix(0 To 2, 1 To 1) As Integer
    PageMatrix(0, 1) = 1   'First column of page 1, always = 1
    LookingForLastPage = True
    lastpage = 1
    
    With ActiveSheet
        '  In practice, this sub will be passed values for row and coll
        '  which represent the anticipated row & col that are populated
        '  to span the used range.
        roww = 13
        coll = 1
        LastPopulated(0) = .Cells(.Rows.Count, coll).End(xlUp).Row
        LastPopulated(1) = .Cells(roww, .Columns.Count).End(xlToLeft).Column
        Debug.Print "Last row of data: ", LastPopulated(0)
        Debug.Print "Last column of data: ", LastPopulated(1)
        .Cells(LastPopulated(0) + 50, LastPopulated(1) + 10).Value = "."
        last_row = .HPageBreaks(1).Location.Row - 1
        Set y = .VPageBreaks
        For Each pb_y In y
            If LookingForLastPage Then
                If lastpage > 1 Then
                    ReDim Preserve PageMatrix(0 To 2, 1 To lastpage) As Integer
                    PageMatrix(0, lastpage) = PageMatrix(1, lastpage - 1) + 1
                End If
                PageMatrix(1, lastpage) = pb_y.Location.Column - 1
                PageMatrix(2, lastpage) = last_row
                If pb_y.Location.Column > LastPopulated(1) Then _
                    LookingForLastPage = False Else: lastpage = lastpage + 1
            End If
        Next pb_y
        .Cells(LastPopulated(0) + 50, LastPopulated(1) + 10).ClearContents
        Debug.Print "Page", "First Col", "Last Col", "Last Row"
        For i = 1 To lastpage
            Debug.Print i, PageMatrix(0, i), PageMatrix(1, i), PageMatrix(2, i)
        Next i
        Debug.Print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        Debug.Print "Last page is: ", lastpage
    
    End With
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 2015-11-07
      • 1970-01-01
      • 2013-04-14
      • 2010-10-09
      相关资源
      最近更新 更多