我应该将一些大型数据范围从Excel导出到Powerpoint,每张幻灯片一页,当然我应该处理分页符以避免“孤立”行或列。
我试图通过读取HPageBreaks.Count和VPageBreaks.Count来检查具有给定缩放的垂直和水平页面数,然后手动定义每个中断的位置。我们的想法是在每个页面上具有大致相同的宽度和高度。
当我逐步调试我的代码时,它运行得很好,逻辑似乎没问题,但是如果我“自由地”运行它,那么分页符完全关闭。添加一些MsgBox指令,我可以看到当我读取HPageBreaks.Count(或垂直)时,我得到了错误的值。 (如果我手动执行代码应该做什么,我可以检查正确的。)
在许多论坛上搜索,我看到一些丑陋的变通办法,例如强制重置PaperSize(ws.PageSetup.PaperSize = ws.PageSetup.PaperSize)。在尝试了其中一些之后,似乎工作得更好的是在更改为PageSetup之前关闭PrintCommunication,然后将其重新打开。这在我的大多数纸张上运行良好,但在非常大的纸张上(~750行x 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
为什么会发生这种情况的任何想法,我该如何解决?
谢谢,
答案 0 :(得分:2)
当 VBA代码在调试模式下按F8时工作正常时,我建议对该问题提出一般性建议,但在点击F5运行整个宏后它不起作用。
提示1。尽可能使用ThisWorkbook.ActiveSheet
代替ActiveWorkbook.ActiveSheet
来引用正确的工作表。使用ThisWorkbook.Application
代替Application.
可能是您在后台运行了另一个Addin程序,将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
https://stackoverflow.com/a/3891017/1903793 https://www.fmsinc.com/microsoftaccess/modules/examples/AvoidDoEvents.asp
或者:
Application.Calculate
If Not Application.CalculationState = xlDone Then
DoEvents
End If
https://stackoverflow.com/a/11277152/1903793
提示3。如果上述内容仍不能用于刷新使用:
ThisWorkbook.Connections("ConectionName").Refresh
ThisWorkbook.Application.CalculateUntilAsyncQueriesDone
答案 1 :(得分:0)
我的另一个解决方法是将PrintArea设置为new(不使用.PrintCommunication = false)
wks.PageSetup.PrintArea = wks.PageSetup.PrintArea
此解决方法不会影响任何pagesetup设置(与.Zoom属性不同)
仅当PageView设置为xlPageLayoutView且运行宏时“printarea”(UsedRange大于PrintArea)之外的数据才会出现此问题。
因此,在执行变通方法之前,您可以检查工作表是否在PageLayoutView中。如果工作表在任何其他视图中,则pagebreaks.count在此处始终正常工作。