【问题标题】:Range not staying within selection范围不在选择范围内
【发布时间】:2021-03-10 04:11:20
【问题描述】:

我正在开发一个在选定范围内突出标点符号的宏。

图片中的第一个示例显示了荧光笔在第一行文本上运行时的外观。 When a normally sized area is selected, it works as intended and highlights the punctuation within the selection.

图像中的第二个示例显示了未选择范围时荧光笔的作用,但光标位于第二行文本开头的“a”之前的右侧。请注意,范围是失控的,并选择了光标之后的所有内容。

图像中的第三个示例显示了当范围为 ONE SPACE 时荧光笔的作用。在这个例子中,我选择了第二行开头的“a”之后的右括号;换句话说,所选范围是从括号的开头到结尾。请注意,该范围是失控的,但在第二行上方和下方的两个方向上:它已在整个文档上运行。

示例

Sub Review_Highlighter()

''Initialize variables
Dim strKey As Variant
Dim d As Object

'Instantiate Dictionary object "d" for punctuation to highlight
Set d = CreateObject("Scripting.Dictionary")

' Clear existing formatting and settings in Find and Replace fields
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Application.ScreenUpdating = False

'Add dictionary values
'd.Add "[Text To Replace]", "[Replacement Text]"
d.Add "(", "("
d.Add ")", ")"
d.Add "[", "["
d.Add "]", "]"
d.Add "{", "{"
d.Add "}", "}"
d.Add ".", "."
d.Add ",", ","
d.Add ";", ";"
d.Add ":", ":"
d.Add "-", "-"
d.Add "+", "+"
d.Add "_", "_"
d.Add "%", "%"
d.Add "#", "#"
d.Add "$", "$"
d.Add ">", ">"
d.Add "<", "<"
d.Add Chr(39), Chr(39)
d.Add Chr(173), Chr(173)
d.Add """", """"
d.Add "?", "?"
d.Add "!", "!"
d.Add "/", "/"
d.Add "\", "\"
d.Add "=", "="
d.Add "*", "*"
d.Add "<d", "d"
d.Add "<cl", "cl"
d.Add Chr(183), Chr(183)
d.Add "  ", "  "
d.Add "   ", "   "

'Get selection in the selection range
With Selection.range.Find
    .Format = True
    .MatchWholeWord = True
    .MatchAllWordForms = False
    .MatchWildcards = False
    .Wrap = wdFindStop
    .Forward = True
  
    'For each index number in each dictionary, replace text with same text highlighted,
    ' red for period, pink for comma, yellow for colon or semicolon,
    ' green for all other punctuation, and red for special words.
    'For each key in d, replace text with key value
    For Each strKey In d.Keys()
        .MatchWildcards = False
        .Text = strKey
        If .Text = "." Then
            Options.DefaultHighlightColorIndex = wdDarkRed
        ElseIf .Text = "," Then
            Options.DefaultHighlightColorIndex = wdPink
        ElseIf .Text = ";" Or .Text = ":" Then
            Options.DefaultHighlightColorIndex = wdYellow
        Else
            Options.DefaultHighlightColorIndex = wdBrightGreen
        End If
        If .Text = "<d" Or .Text = "<cl" Or .Text = "   " Or .Text = "  " Then
            Options.DefaultHighlightColorIndex = wdGray25
            .MatchWildcards = True
        End If
        .Replacement.Text = d(strKey)
        .Replacement.Highlight = True
        .Execute Replace:=wdReplaceAll
        .MatchWildcards = False
    Next
    
End With

'Deallocate memory
Set d = Nothing
Set strKey = Nothing

Application.ScreenUpdating = True

End Sub

我尝试用

启动一个范围对象
Dim RngSel As range
Set RngSel = Selection.range

并设置选择

'Get selection in the selection range
With ActiveDocument.range
    .Start = RngSel.Start
    .End = RngSel.End
    With .Find
        .Format = True
        .MatchWholeWord = True
        .MatchAllWordForms = False
        .MatchWildcards = False
        .Wrap = wdFindStop
        .Forward = True

它导致相同的情况,除了第二种和第三种情况,它选择整个文档。

我听说过 Word 中挑剔的动态选择范围,想知道我做错了什么,是否有任何解决方法可以缓解这个问题。

【问题讨论】:

  • 您需要的缓解措施是阅读 range.find 对象及其方法,以便了解其正确用法。
  • @freeflow 你能推荐一些东西给 benlli 阅读吗?
  • 在 VBA IDE 中将光标放在 .find 语句的查找处,然后按 F1。这将打开查找对象的 MS 帮助页面。如果 OP 足够聪明和坚定,这将是一个足够的开始。
  • 范围比选择更具动态性,其设计或预期不会与选择保持同步。当然,Selection 是 Range,因为它在文档中具有指定的开始和结束地址,但这并不是说 Ranges 仅由 Selection 创建。无论当前选择范围位于何处,您都可以通过编程方式将范围分配给文档中的任何位置。必须初始化与选择无关的范围。你不能只声明一个 Range 变量,然后给它一个开始和结束地址......要继续。
  • 在声明 Range 后,您必须使用文档内容分配对其进行初始化,例如 ... 设置 rng = ActiveDocument.Content 或 ActiveDocument.Tables(1).Range。完成后,您可以重新分配 Range 的起点和终点。底线是 Ranges 的运行方式没有错误。不幸的是,您对如何尝试使用它们存在误解。

标签: vba ms-word


【解决方案1】:

试试:

Sub Demo()
Application.ScreenUpdating = False
Dim StrFnd As String, i As Long
StrFnd = "[\!-/\:-\?\[-`\{-\}‘-”·­]|[\:\;]|.|,|[ ]{2,}|<d|<cl"
With Selection
  If .Type = wdSelectionIP Then Exit Sub
  If InStr(Trim(.Text), " ") = 0 Then Exit Sub
  With .Range.Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Forward = True
    .Wrap = wdFindStop
    .MatchWildcards = True
    .Replacement.Text = "^&"
    .Replacement.Highlight = True
    For i = 0 To UBound(Split(StrFnd, "|"))
      Select Case i
        Case 0: Options.DefaultHighlightColorIndex = wdBrightGreen
        Case 1: Options.DefaultHighlightColorIndex = wdYellow
        Case 2: Options.DefaultHighlightColorIndex = wdDarkRed
        Case 3: Options.DefaultHighlightColorIndex = wdPink
        Case 4 - 6: Options.DefaultHighlightColorIndex = wdGray25
      End Select
      .Text = Split(StrFnd, "|")(i)
      .Execute Replace:=wdReplaceAll
    Next
  End With
End With
Application.ScreenUpdating = True
End Sub

【讨论】:

  • 这简化了事情并修复了第二个问题(未选择范围时光标之后的所有内容)。它仍然存在第三个问题(选择一个空格/一个字符时在整个文档上运行)。我确实注意到它仅在选择列表中的字符时发生,而不是在它是未突出显示的字符时发生。 When a highlighted character (a semicolon) is selected, it highlights all the to-be-highlighted characters in the document.选择双空间时,它突出显示了文档中的所有双空间。
  • 对代码添加了额外的检查: If InStr(Trim(.Text), " ") = 0 Then Exit Sub.这确实意味着代码不会执行任何操作,除非您选择至少由一个或多个空格分隔的两个单词的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
  • 2018-03-08
  • 1970-01-01
  • 2018-01-14
相关资源
最近更新 更多