vba 循环页面或分页符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19947063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 00:24:14  来源:igfitidea点击:

Loop through pages OR page breaks?

vbams-wordword-vba

提问by Jazcash

I'm basically trying to create a cumulative word count for documents that will put the number of words on each page into its footer and add it to the total words each page. After a lot of looking around, I found that Word doesn't really handle pages the same for everybody and so doesn't have any interface to access the individual pages through.

我基本上是在尝试为文档创建一个累积字数,将每页上的字数放入其页脚并将其添加到每页的总字数中。环顾四周后,我发现 Word 并没有真正为每个人处理相同的页面,因此没有任何界面来访问各个页面。

Now I'm trying to separate each page with page breaks so there's a clear delimiter between pages, but I still can't find how to loop through these. Any clues?

现在我试图用分页符分隔每个页面,因此页面之间有一个明确的分隔符,但我仍然找不到如何循环这些。有什么线索吗?

I'm going to post the code I have, but it's only for getting the word count currently. No proper attempts at cycling through page breaks because I don't know how.

我将发布我拥有的代码,但它仅用于获取当前的字数。没有适当的尝试通过分页符循环,因为我不知道如何。

Sub getPageWordCount()

Dim iPgNum As Integer
Dim sPgNum As String
Dim ascChar As Integer
Dim rngPage As Range
Dim iBeginPage As Integer
Dim iEndPage As Integer
' Go to start of document and make sure its paginated correctly.
Selection.HomeKey Unit:=wdStory, Extend:=wdMove
ActiveDocument.Repaginate

' Loop through the number of pages in the document.
For iPgNum = 2 To Selection.Information(wdNumberOfPagesInDocument)
sPgNum = CStr(iPgNum)
iBeginPage = Selection.Start
' Go to next page
Selection.GoTo wdGoToPage, wdGoToAbsolute, sPgNum
' and to the last character of the previous page...
Selection.MoveLeft wdCharacter, 1, wdMove
iEndPage = Selection.Start
' Retrieve the character code at insertion point.
Set rngPage = ActiveDocument.Range(iBeginPage, iEndPage)
MsgBox rngPage.ComputeStatistics(wdStatisticWords)
'rngPage.Footers(wdHeaderFooterPrimary).Range.Text = rngPage.ComputeStatistics(wdStatisticWords)
'ActiveDocument.Sections(2).Footers
' Check the character code for hard page break or text.
Next

' ActiveDocument.Sections(2).Footers(wdHeaderFooterPrimary).Range.Text = "bob" 'Testing

End Sub

回答by Jazcash

Finally got it, managed to guess my way through it a bit, taking assorted bits from dark corners of the internet:

终于明白了,设法猜到了我的方式,从互联网的黑暗角落里提取了各种各样的东西:

Sub getPageWordCount()

    'Replace all page breaks with section breaks
    Dim myrange1 As Range, myrangedup As Range
    Selection.HomeKey wdStory
    Selection.Find.ClearFormatting
    With Selection.Find
        Do While .Execute(findText:="^m", Forward:=True, _
            MatchWildcards:=False, Wrap:=wdFindStop) = True
            Set myrange = Selection.Range
            Set myrangedup = Selection.Range.Duplicate
            myrange.Collapse wdCollapseEnd
            myrange.InsertBreak wdSectionBreakNextPage
            myrangedup.Delete
        Loop
    End With

    'Unlink all footers and insert word count for each section
    Dim sectionCount, sectionNumber, i, sectionWordCount, cumulativeWordCount As Integer
    sectionCount = ActiveDocument.Sections.Count
    For sectionNumber = 1 To sectionCount
        With ActiveDocument.Sections(sectionNumber)
            sectionWordCount = .Range.ComputeStatistics(wdStatisticWords)
            cumulativeWordCount = cumulativeWordCount + sectionWordCount
            With .Footers.Item(1)
                .LinkToPrevious = False
                .Range.Text = "This page's word count: " + CStr(sectionWordCount) + "  |  Cumulative word count: " + CStr(cumulativeWordCount)
                .Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
            End With
        End With
    Next

End Sub

And now I've just discovered that if I want to port this macro to an add-in for ease of use for non-techy users I have to write it in VB 2010 in Visual Studio where the API is different. Good luck me!

现在我刚刚发现,如果我想将此宏移植到加载项以方便非技术用户使用,我必须在 API 不同的 Visual Studio 中的 VB 2010 中编写它。祝我好运!

回答by Jazcash

It sounds as if you have what you need, but I was working on an alternative that I may as well post because it does not require you to add page breaks or section breaks. But you would have to add the same nested field in each footer that appears in the document (I haven't done that part here, but it's not completely trivial because there may be multiple sections and multiple footers per section).

听起来好像你有你需要的东西,但我正在研究一个替代方案,我也可以发布它,因为它不需要你添加分页符或分节符。但是您必须在出现在文档中的每个页脚中添加相同的嵌套字段(我没有在此处完成该部分,但这并非完全微不足道,因为每个部分可能有多个部分和多个页脚)。

The field code you need to add (in addition to your 'This page's word count: ' text) is

您需要添加的域代码(除了您的“此页面的字数:”文本)是

{ DOCVARIABLE "s{ SECTION }p{ PAGE \*arabic }" }

As written, the method may break in some circumstances, e.g. if there are continuous section breaks. I haven't checked.

正如所写的那样,该方法在某些情况下可能会中断,例如,如果有连续的分节符。我没查过。

Sub createWordCounts()
Dim i As Integer
Dim rng As Word.Range
With ActiveDocument
  For i = 1 To .Range.Information(wdActiveEndPageNumber)
    Set rng = .GoTo(wdGoToPage, wdGoToAbsolute, i).Bookmarks("\page").Range
    .Variables("s" & CStr(rng.Information(wdActiveEndSectionNumber)) & "p" & CStr(rng.Information(wdActiveEndAdjustedPageNumber))).Value = rng.ComputeStatistics(wdStatisticWords)
    Set rng = Nothing
  Next
End With

End Sub