【问题标题】:Visual Basic in Word: compare selection within rangeWord 中的 Visual Basic:比较范围内的选择
【发布时间】:2018-10-27 13:08:29
【问题描述】:

更新:按照下面 Cindy 的建议,我使用了 InRange 函数。我的函数通过 Find 操作进行了很好的迭代。 But the function is failing to return FALSE when the selection is outside the named range.请参阅下面的“在这里失败”。谢谢。

使用 Visual Basic,我需要验证 Word 文档中的选择位置是否在指定范围内。许多年前,我使用这段代码来做到这一点:

ActiveDocument.Bookmarks("typdef").Select

While ((WordBasic.CmpBookmarks("\Sel", "typedef") = 8 _
Or WordBasic.CmpBookmarks("\Sel", "typedef") = 6 _
Or WordBasic.CmpBookmarks("\Sel", "typedef") = 10) _
And leaveloop <> 1
...
If WordBasic.CmpBookmarks("\Sel", "\EndOfDoc") = 0 Then
    leaveloop = 1
End If
Wend

这是我写的更新函数:

Function FormatSpecHeadReturn(strStyle)

Dim rngBookmark As Word.Range
Dim rngSelection As Word.Range

Set rngBookmark = ActiveDocument.Bookmarks("SpecBodyPairRange").Range
Set rngSelection = Selection.Range

var = rngSelection.InRange(rngBookmark)
Debug.Print var

Do While rngSelection.InRange(rngBookmark) = True

Selection.Find.Style = ActiveDocument.Styles(strStyle)
Selection.Find.Replacement.ClearFormatting
With Selection.Find
    .Text = "^p"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindAsk
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute
Selection.HomeKey

' FAILING HERE: Returns TRUE when selection point 
' is outside SpecBodyPairRange
var = rngSelection.InRange(rngBookmark)
Debug.Print var

Selection.HomeKey Unit:=wdLine, Extend:=wdMove
Selection.InsertBefore Chr(182)
Selection.EndKey
Selection.InsertAfter vbTab
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove

    If rngSelection.InRange(rngBookmark) <> True Then Exit Do
  Loop
End Function

我在当前项目中使用了 CmpBookmarks,但它不能可靠地返回当前位置的值。 When the selection point is within the named range, it returns 8 for two loops, and then returns 6. When the selection point is outside the named range, CmpBookmarks returns 6.

显然,CmpBookmarks 已被弃用。我找不到 CmpBookmarks 生成的返回值,也找不到现代等效函数。

我承认我不明白命名的“SpecBodyPairRange”范围和分配给 r 的范围之间的区别,这里:

按范围调暗

我可以看到这个例子中的“r”似乎包含了整个文档。我在 Microsoft.Office.Interop.Word 上研究了 Range Interface 和 Selection Interface,我还没有完全理解。我不是程序员,只是一个在某些编码方面自学成才的半技术作家,他的任务是自动化文档转换。

必须有更好的方法来比较选择点以验证它是否在命名范围内,但我找不到它。任何您能给我的指点都非常感谢!

【问题讨论】:

    标签: vba ms-word named-ranges


    【解决方案1】:

    不是一个大字 VBA 的人,但你能比较一下 StartEnd 属性吗?

    Dim bm As Bookmark
    
    Set bm = ActiveDocument.Bookmarks("tester")
    Debug.Print "Bookmark", bm.Start, bm.End
    Debug.Print "Selection", Selection.Start, Selection.End
    

    【讨论】:

      【解决方案2】:

      为了确定一个Range 是否在另一个内部,请使用InRange 方法:

      Dim rngBookmark as Word.Range
      Dim rngSelection as Word.Range
      
      Set rngBookmark = ActiveDocument.Bookmarks("typeDef").Range
      Set rngSelection = Selection.Range
      If rngSelection.InRange(rngBookmark) = True Then
        'Do something
      End If
      

      【讨论】:

      • 谢谢,这有助于我更好地理解范围!
      • 感谢您的意见和想法。我已经实施了你的建议。但是,由于未知原因,它失败了。发生的一件奇怪的事情是范围 SpecBodyPairRange 在函数执行时被任意更改,显然折叠到插入点。
      • @montereyredfox 好吧,我确实回答了你原来的问题。但是您的 real 问题似乎是另外一回事:如何仅搜索带书签的范围?那是完全不同的事情,正确地应该是一个不同的问题。在 Stack Overflow 上,以一种人们必须重新开始回答的方式更改问题被认为是“糟糕的形式”——当您使用答案中的内容更改代码然后说“我有一个新问题”时,就会发生这种情况。
      • 但是 FWIW @montereyredfox 这是因为您永远不会在循环内重新分配 rngSelection。运行 Find 而不是 Selection
      • 感谢 StackOverflow 良好行为的输入和更新。
      【解决方案3】:

      您可以使用 VBA 的 InRange 方法。例如:

      Function FormatSpecHeadReturn(strStyle)
      Dim Rng As Range
      With ActiveDocument
        Set Rng = .Bookmarks("SpecBodyPairRange").Range
        With .Bookmarks("SpecBodyPairRange").Range
          With .Find
            .ClearFormatting
            .Replacement.ClearFormatting
            .Text = "^p"
            .Replacement.Text = ""
            .Style = strStyle
            .Format = True
            .Forward = True
            .Wrap = wdFindStop
            .MatchWildcards = False
            .Execute
          End With
          Do While .Find.Found
            If .InRange(Rng) = False Then Exit Do
            .Style = "SpecHead"
            .Paragraphs.First.InsertBefore Chr(182)
            .InsertAfter vbTab
            .Collapse wdCollapseEnd
            .Find.Execute
          Loop
        End With
      End With
      End Function
      

      【讨论】:

      • 这很棒,它极大地简化了我正在尝试做的事情。但是,它不会遍历整个范围。
      • @montereyredfox 代码确实遍历了“SpecBodyPairRange”书签跨越的整个范围;我建议您重新检查该范围的范围以及其中使用了哪些样式。
      猜你喜欢
      • 2016-07-10
      • 2013-06-12
      • 1970-01-01
      • 2019-08-01
      • 2016-08-17
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      相关资源
      最近更新 更多