首页 > 解决方案 > 为什么 TextRange.InsertSymbol 方法会替换我的 TextRange 中的文本?

问题描述

在 powerpoint 中通过 VBA 生成幻灯片的过程中,我需要在生成的文本中插入一个“Wingdings 符号”,这是两个值的比较。我做了这个方法,它完全按照我的意愿工作

Sub formatDifference(header As String, old As Integer, now As Integer, txt As TextRange)
    Dim diff As Integer
    diff = old - now

    With txt
        If (diff > 0) Then
            .InsertSymbol "Wingdings", getArrowCharCode("down")
                                       ' getArrowCharCode is a custom function to get the 
                                       ' char code as an Integer
        ElseIf (diff = 0) Then
            .InsertSymbol "Wingdings", getArrowCharCode("right")
        Else
            .InsertSymbol "Wingdings", getArrowCharCode("up")
        End If

        .InsertBefore header & now & " ("    ' <-- note this line
        .InsertAfter " " & Abs(diff) & ")"
    End With
End Sub

Sub 基本上只是在formatDifference文本中添加一个项目符号行(在下面的示例中,在我添加非项目符号文本之前,该过程被调用了 4 次)。

我不明白的是,当我用一些文本启动文本然后使用该InsertSymbol方法时,文本似乎实际上被替换了,而不是在末尾附加了符号。这是不同代码的示例:

Sub formatDifference(header As String, old As Integer, now As Integer, txt As TextRange)
    Dim diff As Integer
    diff = old - now

    With txt
        .InsertAfter header & now & " (" ' <-- line moved here
                                         '     it doesn't matter if I use 
                                         '     .Text = "initial text"', 
                                         '     it will do the same thing
        If (diff > 0) Then
            .InsertSymbol "Wingdings", getArrowCharCode("down")
        ElseIf (diff = 0) Then
            .InsertSymbol "Wingdings", getArrowCharCode("right")
        Else
            .InsertSymbol "Wingdings", getArrowCharCode("up")
        End If
        .InsertAfter " " & Abs(diff) & ")"
    End With
End Sub

这是我从上面的代码中得到的两个结果的比较(以相同的顺序):

代码差异示例

我对该InsertSymbol方法的理解是它会在最后一段的末尾插入符号,但它看起来不像......我的第二个例子有问题还是我误解了方法的描述


PS注意:标题参数包含回车和换行字符,这就是为什么第二次捕获的所有点都在同一行上,因为第一部分似乎被替换了。

标签: vbapowerpointpowerpoint-2010

解决方案


InsertSymbol 实现的文档

Microsoft Word 的Range.InsertSymbolSelection.InsertSymbol实现描述为:

插入一个符号来代替指定的范围。
如果您不想替换范围,请在使用此方法之前使用 Collapse 方法。

Microsoft Publisher 的TextRange.InsertSymbol实现描述为:

返回一个 TextRange 对象,该对象代表一个插入到指定范围或选择位置的符号。
如果您不想替换范围或选择,请在使用此方法之前使用折叠方法。

然后是 Office TextRange2.InsertSymbol和 PowerPoint TextRange2.InsertSymbol方法,描述为:

将指定字体集中的符号插入到由 TextRange2 对象表示的文本范围内。

考虑到这一点,TextRange.InsertSymbol实现的 PowerPoint 文档有点不准确,包括对包含的代码示例的错误解释(“在第一句话之后”)。

在TextRange之后插入符号

如果要在提供后插入符号TextRange,我建议使用以下包装函数:

Public Function InsertSymbolAfter(newTextRange As PowerPoint.TextRange, _
                           newFontName As String, _
                           newCharNumber As Long, _
                           Optional newUnicode As MsoTriState = msoFalse) As TextRange

    If Right(newTextRange.Text, 1) = vbCr Then
        Set InsertSymbolAfter = newTextRange.Characters(newTextRange.Characters.Count) _
            .InsertSymbol(newFontName, newCharNumber, newUnicode)
        newTextRange.InsertAfter vbCr
    Else
        Set newTextRange = newTextRange.InsertAfter("#")
        Set InsertSymbolAfter = newTextRange _
            .InsertSymbol(newFontName, newCharNumber, newUnicode)
    End If

End Function

它区分了两种情况:

  • 如果最后一个字符是vbCR( Chr(13), 回车, CR),则在 CR 之前添加符号(CR 被新符号替换并在之后再次添加)。
  • 在所有其他情况下,首先添加任意字符,然后用新符号替换。

测试

可以通过以下方式测试整个文本框、段落或字符的功能:

Private Sub testit()
    Const WingDingsLeft As Long = 231
    Const WingDingsRight As Long = 232
    Const WingDingsUp As Long = 233
    Const WingDingsDown As Long = 234
        
    With ActivePresentation.Slides(1).Shapes(1).TextFrame
        InsertSymbolAfter(.TextRange, "Wingdings", WingDingsUp)
        InsertSymbolAfter(.TextRange.Paragraphs(1), "Wingdings", WingDingsDown)
        InsertSymbolAfter(.TextRange.Characters(2, 1), "Wingdings", WingDingsRight)
    End With
End Sub

推荐阅读