【问题标题】:Word VBA replace text appearing in selection only with uppercaseWord VBA 仅用大写替换出现在选择中的文本
【发布时间】:2016-10-28 02:39:35
【问题描述】:

我的对象很简单 - 我想要一个快捷方式来用大写字符替换选择中的文本,而不应用“AllCaps”样式,原因我不会在这里讨论。

我已经成功地使用了Selection.DeleteSelection.Insert,但这似乎并没有保留段落样式所固有的字体样式。

当我尝试使用 VBA Selection.Find.Execute:=ReplaceAll 时,它会替换整个文档中的所有实例。我知道这应该是.wrap=wdFindContinue 的行为,但我设置了.wrap=wdFindStop。我最好的猜测是,因为我的.text 被设置为调用Selection 对象的变量,所以在设置.text 时它会以某种方式丢失选择(尽管在我逐步执行代码时这在视觉上并不明显 - 选择保持突出显示),导致.ReplaceAll 为整个文档执行。如果我为特定情况手动输入“find”(.text)字符串,它只会在选择时执行(即使在 .Replacement.Text 字段中调用了变量txt!),但显然不会实用。

这是我的代码:

Option Explicit
Sub ReplaceWithUppercase()

Dim pasteAutoFormatSetting As Boolean
Dim txt As String
'Save current user selection of whether to adjust spacing automatically when pasting:
pasteAutoFormatSetting = Options.PasteAdjustWordSpacing

'Turn off auto spacing adjustment:
Options.PasteAdjustWordSpacing = False

txt = Selection.Range.text


With Selection.Font
        .AllCaps = False
End With

'The next two lines work but do not seem to preserve built-in font styles
'already applied to the selected text, so I wanted to instead use find/replace:

'Selection.Range.Delete
'Selection.Range.InsertAfter (UCase(txt))


    With Selection.Range.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .text = txt
        .Replacement.text = UCase(txt)
        .Forward = True
        .Wrap = wdFindStop
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = True
        .Execute Replace:=wdReplaceAll
    End With

'Return to user preference for auto apacing adjustment:
Options.PasteAdjustWordSpacing = pasteAutoFormatSetting

End Sub

【问题讨论】:

    标签: vba ms-word


    【解决方案1】:

    @PatentWookiee,我认为你最初是在正确的轨道上,

    Selection.Range.Delete
    Selection.Range.InsertAfter (UCase(txt))
    

    问题是,一旦您删除了选定的文本,您在其位置放置的任何内容都将采用删除前第一个字符的格式。要解决此问题,您需要:

    Option Explicit
    Sub ReplaceWithUppercase()
        Selection.Text = UCase(Selection.Text)
    End Sub
    

    我们只是替换所选字符串的 case,而不是替换实际文本(以及随之而来的格式),从而使您的格式保持完整。如果我没看错你的问题,这应该可以完全解决你的问题。如果没有,请务必告诉我,我们会解决的。

    【讨论】:

    • 我喜欢单行宏,谢谢!仅当“查找”文本是选择定义的字符串变量时,您是否可以对选择执行 wdReplaceAll 仍然是个谜,但是当您可以说 Selection.Text=someString 时,您可能永远不需要使用 Selection.Find
    • PatentWookiee,不确定这是否能回应您的问题,但您当然可以使用:Selection.Text = Replace("abcdefg", "cde", "CDE") 将返回“abCDEfg”
    • 如果您可以使用正则表达式作为该 Replace 函数的参数会很好,但我猜不是在 VBA 中。我已经编写了使用正则表达式来查找和替换文本的宏,但是它们相当冗长,即:
    • For Each para In Selection.Paragraphs txt = para.Range.text 'any match? If re.Test(txt) Then 'get all matches Set allMatches = re.Execute(txt) For Each m In allMatches Debug.Print m.Value num = m.Value + 1 Set rng = para.Range rng.Collapse wdCollapseStart rng.MoveStart wdCharacter, m.FirstIndex + offset rng.MoveEnd wdCharacter, m.length rng.text = re.Replace(rng.text, num) offset = offset + Len(CStr(num)) - Len(m.Value) Next m End If Next para
    • 手动将光标移动到每个匹配的开始索引(考虑到与先前不同长度替换的任何偏移),手动将选择扩展到匹配的结尾等。在这种情况下,可以很高兴使用查找/替换来为我处理这些东西。
    【解决方案2】:

    使用数组作为选择范围的快速工作 - 和 StrConv 函数

    Sub ChangeRangeToUCase()
        Const vbUpperCase = 1 ' strConv constant
    
        Dim arrCells    As Variant
        Dim intRow      As Integer
        Dim intCol      As Integer
    
        ' Assign Range to an array
        arrCells = Selection
        For intRow = LBound(arrCells, 1) To UBound(arrCells, 1)
            For intCol = LBound(arrCells, 2) To UBound(arrCells, 2)
                arrCells(intRow, intCol) = StrConv(arrCells(intRow, intCol), vbUpperCase)
            Next intCol
        Next intRow
    
        Selection = arrCells
    
    End Sub
    

    【讨论】:

    • @Jim_Simson 的回答简单明了,但我喜欢看到多种做事方式。
    • 听起来不错 - 如果您要处理选择中的许多单元格,您会发现数组方法几乎是即时的,而不是直接使用选择
    • 谢谢 - 我会将您的宏复制到我的库中,并注意它的执行速度应该比 Selection.Text = someString 更快。
    【解决方案3】:

    在宏记录器的帮助下,我们发现:

        Sub ChangeSelectionToUCase()
            ' MsgBox Selection.Range.text
            Selection.Range.Case = wdUpperCase
            ' MsgBox Selection.Range.text
        End Sub
    

    这可以接受吗?它看起来确实容易多了。 OP 担心不使用“AllCapsStyle”。但是使用注释掉的行,我们可以说服自己文档中的文本确实被更改为大写,而不仅仅是它的视觉外观(“样式”)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 2021-10-13
      • 2018-08-24
      • 1970-01-01
      • 2019-01-31
      • 2019-05-20
      相关资源
      最近更新 更多