【问题标题】:Word 2016 VBA loop until end of documentWord 2016 VBA 循环直到文档结束
【发布时间】:2018-10-01 16:58:58
【问题描述】:

我在网上查看了许多不同的答案,但未能找到适合我的代码的解决方案。这是我第一次在 Word 中编写 VBA(对 Excel 有一定的经验)。

我认为this post 可能是我需要的,但它并没有为我停止文档末尾的循环。

我正在尝试在新部分的开始之前插入一个连续的分节符,我将其指定为格式为标题 1 的文本。我完全愿意以另一种方式这样做,并感谢您见解!

Sub InsertSectionBreak()
    ' Go to start of document
    Selection.HomeKey Unit:=wdStory

    ' Find next section based on header formatting, insert continuous section break just before
    '
    Selection.Find.ClearFormatting
    Selection.Find.Style = ActiveDocument.Styles("Heading 1")
    With Selection.Find
        .Text = ""
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindStop
        .Format = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With

    Do While Selection.Find.Execute = True
        Selection.Find.Execute
        Selection.MoveLeft Unit:=wdCharacter, Count:=1
        Selection.InsertBreak Type:=wdSectionBreakContinuous
    Loop
End Sub

【问题讨论】:

  • 你能和我们分享一下为什么你需要插入分节符吗?
  • 当我阅读您的代码时,我希望它会在文档中的第一个标题 1 之前插入“无限”个分节符。这不是正在发生的事情吗?
  • 感谢@FreeMan。那可能行得通!我也许可以添加一些预先确定的文本来说明文档的结尾。
  • @CindyMeister,最终我将需要选择文档的整个部分以复制并粘贴到另一个文档,具体取决于该部分中找到的特定关键字。我确信有一种更优雅的方式来选择该部分,但这是我在谷歌搜索中提出的想法。我当前的代码在文档的最后一部分(不是第一部分)之前添加了无限分节符。
  • 我尝试使用 F8 单步执行宏,而不是运行宏,因为我不希望它永远运行。在我的测试文档中,我有 3 个部分,并且在第 2 部分之前添加了中断,然后是第 3 部分,然后是第 3 部分......

标签: vba ms-word word-2016


【解决方案1】:

问题中的代码还不错,但有一个主要问题:Selection 被移到文档的前面,以便插入分节符。这意味着下次Find 再次运行时会找到相同的标题 1,因此会在相同的位置重复插入分节符。

另一个问题是代码正在执行 Find 作为 Do While 标准的一部分(这就是为什么它没有在文档中找到标题 1 的第一个实例)。

以下代码示例使用Range 对象而不是Selection。您可以将 Range 视为一个不可见的选择,但有一个非常重要的区别:可以有多个 Range;只能选择一个。

建议的代码使用两个范围:一个用于查找,另一个用于插入分节符。查找范围设置为整个文档。 Find 是否成功存储在一个布尔变量 (bFound) 中。

如果查找成功,则将找到的范围复制到分节符的范围。 Duplicate 制作原始范围的独立“副本”,以便可以彼此独立地操作它们。然后将分节符的范围折叠到其起点(将其想象为按左箭头),然后插入分节符。

然而,查找范围被折叠到它的结束点,以便将其移动到使用标题 1 格式化的文本之外,以便可以定位下一个标题 1。然后再次执行 Find 并重复循环,直到找不到更多的 Heading 1 实例。

Sub InsertSectionBreak()
    Dim rngFind As Word.Range, rngSection As Word.Range
    Dim bFound As Boolean

    Set rngFind = ActiveDocument.content

    ' Find next section based on header formatting, insert continuous section break just before
    '
    rngFind.Find.ClearFormatting
    rngFind.Find.style = ActiveDocument.styles("Heading 1")
    With rngFind.Find
        .text = ""
        .Replacement.text = ""
        .Forward = True
        .wrap = wdFindStop
        .Format = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        bFound = .Execute
    End With

    Do While bFound
        Set rngSection = rngFind.Duplicate
        rngSection.Collapse wdCollapseStart
        rngSection.InsertBreak Type:=wdSectionBreakContinuous
        rngFind.Collapse wdCollapseEnd
        bFound = rngFind.Find.Execute
    Loop
End Sub

【讨论】:

  • 非常感谢@CindyMeister!我真的很感谢你周到的解释。我还将探讨您使用书签而不是分节符的建议。
【解决方案2】:

如果您感兴趣的内容与某个标题相关,则无需分节符即可获取该标题下的所有内容。例如:

Sub GetHeadingSpanText()
Application.ScreenUpdating = False
Dim Rng As Range
With ActiveDocument.Range
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Text = InputBox("What is the text to find?")
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindStop
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
    .Execute
  End With
  If .Find.Found = True Then
    Set Rng = .Paragraphs(1).Range
    Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
    MsgBox Rng.Text
  End If
End With
Set Rng = Nothing
Application.ScreenUpdating = True
End Sub

请注意,此方法获取与最近标题相关的所有内容,无论其级别如何;可以使用更复杂的方法来获取与特定标题级别关联的所有内容,这样,如果在子标题下找到匹配项,则使用先前的主标题来确定跨越的范围。

【讨论】:

  • 谢谢,@macropod!我发现您的代码仅选择当前标题级别中的文本,而不是标题 1 下的整个部分。因此,如果我有格式化为标题 1 和标题 2 的文本,并且文本出现在标题 2 下文本,仅选择标题 2 小节。知道如何让它抓住部分中的所有内容(包括部分标题标题 1)?
  • 这表明:无论您发现什么都在标题 2 样式下。正如我所说,需要更复杂的代码才能使代码跨越相​​应的标题 1 内容。根据所采用的方法,该代码可能会返回一个跨越整个关联标题 1 范围或仅从当前标题 2 范围返回到前一个标题 1 的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
相关资源
最近更新 更多