获取Word文档中的页面数。

17

我正在使用自动化程序对Word文档进行大量更改,并运行VBA宏,其中检查文档的页数是否超过了某个特定值。 我使用ActiveDocument.Information(wdNumberOfPagesInDocument)来获取页数,但该方法返回不正确的结果。 我认为这是因为Word尚未更新文档的分页以反映我所做的更改。

ActiveDocument.ComputeStatistics(wdStatisticPages)也存在同样的问题。

我尝试添加调用ActiveDocument.Repaginate,但没有任何作用。

我曾经通过在文档末尾添加一个段落,然后再将其删除来解决这个问题,但这种方法似乎已经不起作用(我最近从Word 2003迁移到Word 2010)。

有没有办法强制Word实际重新排版,或者等待重新排版完成?


1
那么,除了引用 ActiveDocument 之外,直接引用文档对象怎么样?(你可以将其存储在变量中) - Voitcus
有第三种检查页面数量的方法,请也尝试使用这个:ActiveWindow.Panes(1).Pages.Count - Kazimierz Jawor
2
类似于在文档末尾添加一个段落,如果您选择文档的末尾(即使用ActiveDocument.Bookmarks("\EndOfDoc").Select),然后调用.Information(wdNumberOfPagesInDocument)。这对我在一个非常复杂的1,177页文档上运行良好,但需要很长时间。 - CuberChase
@CuberChase:我很兴奋地想尝试它,但是...它仍然没有任何区别。 :-( - Gary McGill
嗯,这很有趣。你能提供更多信息吗?比如页面计数有多远,如果只运行两行选择文档结尾并检查页面计数是否正确。你处于哪种视图类型? - CuberChase
显示剩余12条评论
9个回答

11

我刚刚花了好2个小时来解决这个问题,但是我还没有在任何论坛上看到这个答案,所以我想分享一下。

https://msdn.microsoft.com/en-us/vba/word-vba/articles/pages-object-word?f=255&MSPPError=-2147217396

这给了我我的解决方案,结合浏览文章找到大多数人引用的解决方案都不支持最新版本的Word。我不知道它是在哪个版本中更改的,但我的假设是2013年及更新版本可以使用此代码计算页面:

ActiveDocument.ActiveWindow.Panes(1).Pages.Count.

我认为这个方法的工作原理是:ActiveDocument选择文件,ActiveWindow确认要使用的文件是否在当前窗口中(如果文件在视图选项卡中打开了多个窗口),Panes确定如果有多个窗口/分割窗格/任何其他你想要“第一个”被评估的无聊东西,pages.count通过计算集合中项目的数量指定要被评估的页面对象。

如果有更多知识的人请随意纠正我,但这是我尝试过的任何文档上都给出正确页数计数的第一个方法!

还有,我很抱歉,但我弄不明白如何将那一行格式化为代码块。如果版主想编辑我的评论来做到这一点,那就请便。


很有趣。我无法像对其他解决方案进行压力测试那样进行压力测试(其他解决方案90%的时间都有效),但经过快速测试,它看起来很有前途。Pages集合只能在打印布局视图中访问,这表明它确实考虑了页面布局。(我也想知道当ScreenUpdating关闭和/或文档不可见时是否有效-这两个因素会降低其在自动化场景中的有用性)。 - Gary McGill

7
尝试执行 (也许在 ActiveDocument.Repaginate 之后)。
ActiveDocument.BuiltinDocumentProperties(wdPropertyPages)

这段代码:ActiveDocument.ComputeStatistics(wdStatisticPages)可以立即返回结果,但是会导致Word 2010在状态栏中显示“正在计算字数”,并耗费半秒钟的时间。

来源:https://support.microsoft.com/zh-cn/kb/185509


好主意 - 现在不能尝试(这个问题是两份工作之前的),但听起来值得一试。 - Gary McGill
@GaryMcGill 谢谢,希望其他人也能 :) - alexkovelsky
@alexkovelsky 好用极了!谢谢。 - TechGeek
我的执行时间测试表明,在调用ComputeStatistics(wdStatisticPages)之前调用Repaginate是多余的。当需要时,ComputeStatistics(wdStatisticPages)属性似乎会强制重新分页。 - pstraton
此外,我的测试是在应用程序窗口可见的情况下进行的。因此,我的一致结果可能是由于该状态的影响。Gary McGill没有说这对他是否有影响,但是任何依赖于文档图像呈现状态的功能,如果应用程序窗口不可见,则将不可靠。这可能适用于Information属性以及ComputeStatistics和BuiltinDocumentProperties属性,具体取决于所请求的操作。 - pstraton

2

在您完成所有更改后,您可以使用OnTime强制延迟一段时间再读取页面统计信息。

Application.OnTime When:=Now + TimeValue("00:00:02"), _
        Name:="UpdateStats"

我会在此OnTime语句之前更新所有字段:

我也会在这个OnTime语句之前更新所有字段:

ActiveDocument.Range.Fields.Update

我不喜欢在这种情况下延迟的一件事是...多久才算够长?在某些慢速计算机上,可能需要更多时间。这很难调试 :-/ - Gertsen

0
我在获取“ComputeStatistics”返回正确的页数时遇到的一个问题是,我经常在Word中使用“Web Layout”视图。每当您启动Word时,它会恢复到上次使用的视图模式。如果Word处于“Web Layout”模式下,则脚本处理的所有文件的“ComputeStatistics”都将返回“1”页的页面计数。一旦我明确设置了“Print Layout”视图,我就得到了正确的页面计数。
例如:
$MSWord.activewindow.view.type = 3    # 3 is 'wdPrintView', 6 is 'wdWebView'
$Pages = $mydoc.ComputeStatistics(2)  # 2 is 'wdStatisticPages'

0
我在下面找到了一个可能的解决方法,虽然不是真正回答主题问题的答案。 昨天,下面第一个ComputeStatistics行返回了正确的总页数31页,但今天只返回1页。
解决方案是摆脱Content对象,这样就可以返回正确的页数。
Dim docMultiple As Document
Set docMultiple = ActiveDocument 
lPageCount = docMultiple.Content.ComputeStatistics(wdStatisticPages)  ' Returns 1
lPageCount = docMultiple.ComputeStatistics(wdStatisticPages)  ' Returns correct count, 31

我认为你看到的只是运气 - 或者说,这是一个时间问题。ComputeStatistics 最终会返回正确的结果,因此在循环中调用它,或者延迟一段时间后再调用它 - 甚至在某些情况下调用两次 - 都将产生正确的结果。问题是,它不够可预测,不能起到多大的作用。如果你再读一遍问题,你会发现我已经在使用 ActiveDocument.ComputeStatistics,但在我的情况下并不可靠。 - Gary McGill

0

我在Excel中使用了这个程序,它可靠地处理了大约20个文档,其中没有一个超过20页,但有些文档包含了图片和分页等复杂元素。

Sub GetlastPageFromInsideExcel()
Set wD = CreateObject("Word.Application")
Set myDoc = wD.Documents.Open("C:\Temp\mydocument.docx")
myDoc.Characters.Last.Select        ' move to end of document
wD.Selection.Collapse               ' collapse selection at end
lastPage = wD.Selection.Information(wdActiveEndPageNumber)
mydoc.close
wd.quit
Set wD = Nothing
End Sub

0

ActiveDocument.Range.Information(wdNumberOfPagesInDocument)

这个方法对我来说总是有效的,它返回了文档中物理页的总数。


这就是我在问题中所说的已经在做的事情。ActiveDocument.Information(wdNumberOfPagesInDocument)ActiveDocument.Range.Information(wdNumberOfPagesInDocument)是相同的,因为RangeDocument的默认属性。它在大多数情况下都有效,但在涉及许多复杂文档的自动化过程中并不可靠。 - Gary McGill

0
你可以使用Pages-Object及其属性,例如Count。它能够完美地工作😉
Dim objPages As Pages Set objPage = ActiveDocument.ActiveWindow.Panes(1).Pages
QuantityOfPages = ActiveDocument.ActiveWindow.Panes(1).Pages.Count

谢谢。这已经在得票最高的答案中建议过了:https://dev59.com/o2Qn5IYBdhLWcg3wW2H3#48531460。不幸的是,我现在没有尝试它的位置。或者说,幸运的是 :-) - Gary McGill

-1
Dim wordapp As Object
Set wordapp = CreateObject("Word.Application")
Dim doc As Object
Set doc = wordapp.Documents.Open(oFile.Path)

Dim pagesCount As Integer
pagesCount = doc.Content.Information(4) 'wdNumberOfPagesInDocument
doc.Close False
Set doc = Nothing

1
这个解决方案已经在问题中讨论过并被否决了。它在90%的情况下运行良好,但如果你通过VBA操作文档,它就无法给出反映你所做更改的最新结果。 - Gary McGill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接