如何"强制"Excel正确计算分页符?

Edg*_*ard 8 excel vba excel-vba

我应该将一些大型数据范围从Excel导出到Powerpoint,每张幻灯片一页,当然我应该处理分页符以避免"孤立"行或列.

我试图通过读取HPageBreaks.Count和VPageBreaks.Count来检查具有给定缩放的垂直和水平页面数,然后手动定义每个中断的位置.我们的想法是在每个页面上具有大致相同的宽度和高度.

当我逐步调试我的代码时,它运行良好,逻辑似乎没问题,但如果我"自由"运行它,页面中断完全关闭.添加一些MsgBox指令,我可以看到当我读取HPageBreaks.Count(或垂直)时,我得到了错误的值.(如果我手动执行代码应该做什么,我可以检查正确的).

在许多论坛上搜索,我看到一些丑陋的变通方法,比如强制重置PaperSize(ws.PageSetup.PaperSize = ws.PageSetup.PaperSize).在尝试了其中一些之后,似乎工作得更好的是在更改为PageSetup之前关闭PrintCommunication,然后将其重新打开.这在我的大多数床单上运作良好,但是在非常大的(约750行×80列,几乎所有带公式的单元格)上,它根本没有.

这里是代码的摘录:

    'Reset page breaks
    .ResetAllPageBreaks

    'Set minimum acceptable zoom factor
    Application.PrintCommunication = False   'This is the ugly workaround
    .PageSetup.Zoom = 60
    Application.PrintCommunication = True

    MsgBox "Zoom = " & .PageSetup.Zoom    'Only for debugging

    'Calculate the number of pages in width
    Application.PrintCommunication = False
    NPagesWide = .VPageBreaks.Count + 1
    Application.PrintCommunication = True

    MsgBox "NPagesWide = " & NPagesWide

    'Find the higher zoom factor that can fit that number of pages
    Application.PrintCommunication = False
    .PageSetup.Zoom = 100
    Application.PrintCommunication = True
    Do While .VPageBreaks.Count > NPagesWide - 1
        Application.PrintCommunication = False
        .PageSetup.Zoom = .PageSetup.Zoom - 5
        Application.PrintCommunication = True
    Loop

    MsgBox "Zoom = " & .PageSetup.Zoom

    'Set average width per page and initialize column pointer
    If HasTitleColumns Then     'Defined earlier
        PageWidth = (PrintArea.Width + TitleColumns.Width * (NPagesWide - 1)) / NPagesWide
        j = TitleColumns.Columns(TitleColumns.Columns.Count).Column + 1
    Else
        PageWidth = PrintArea.Width / NPagesWide
        j = 1
    End If

    'Cycle vertical page breaks
    For i = 1 To NPagesWide - 1
        'Set width of TitleColumns
        If HasTitleColumns Then
            CumulWidth = TitleColumns.Width
        Else
            CumulWidth = 0
        End If
        'Cumulate columns width until the available page width
        Do While CumulWidth + .Columns(j).Width <= PageWidth
            CumulWidth = CumulWidth + .Columns(j).Width
            j = j + 1
        Loop
        'Add the break
        .VPageBreaks.Add .Columns(j + 1)
    Next i
Run Code Online (Sandbox Code Playgroud)

任何想法为什么会发生这种情况,我该如何解决?

谢谢,

Prz*_*min 2

当VBA 代码在调试模式下按 F8 时工作正常,但在按 F5 运行整个宏后不起作用时,我对这个问题提出一般建议。

提示 1.尽可能使用ThisWorkbook.ActiveSheet代替 来ActiveWorkbook.ActiveSheet引用正确的工作表。使用ThisWorkbook.Application而不是仅仅使用Application.它可能是您有另一个插件程序在后台运行,切换ActiveSheet到您可能不知道的其他东西。检查启用的其他宏并删除任何不使用的内容。因此,在代码中执行任何重要操作之前,请尝试使用 来获得工作表的焦点ThisWorkbook.Activate。请参阅该页面上的图表:http://analystcave.com/vba-tip-day-activeworkbook-vs-thisworkbook/

提示 2.强制 Excel 以不同的方式等待DoEvents

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'Place this line of code at the very top of module
Sleep 1   'This will pause execution of your program for 1 ms
Run Code Online (Sandbox Code Playgroud)

/sf/answers/272371221/ https://www.fmsinc.com/microsoftaccess/modules/examples/AvoidDoEvents.asp

或者:

Application.Calculate 
If Not Application.CalculationState = xlDone Then
    DoEvents
End If
Run Code Online (Sandbox Code Playgroud)

/sf/answers/789400671/

提示3.如果以上方法仍然无法刷新使用:

ThisWorkbook.Connections("ConectionName").Refresh
ThisWorkbook.Application.CalculateUntilAsyncQueriesDone 
Run Code Online (Sandbox Code Playgroud)

/sf/answers/1874609411/