【问题标题】:Why does the TextRange.InsertSymbol method replace the text in my TextRange?为什么 TextRange.InsertSymbol 方法会替换我的 TextRange 中的文本?
【发布时间】:2019-10-22 08:14:33
【问题描述】:

在 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

formatDifference Sub 基本上只是在文本中添加一个项目符号行(在下面的示例中,在我添加非项目符号文本之前,该程序被调用了 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

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

我对@9​​87654329@方法的理解是,它会在最后一段的末尾插入符号,但看起来不像……我的第二个例子是错误的还是我误解了description of the method


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

【问题讨论】:

  • 似乎InsertSymbol for PowerPoint 的工作方式类似于Word 的实现,如果您不想替换它,则必须在其中折叠范围。在 txt.InsertSymbol() 之前使用 Set txt = txt.Characters(txt.Characters.Count + 1) 将 TextRange 折叠到其末尾。
  • @asger 如果你能从你的评论中得到答案,我很乐意给你答案
  • @asger 仍然,我的只是一种解决方法,你的解释实际上正是我想要的哈哈

标签: vba powerpoint powerpoint-2010


【解决方案1】:

InsertSymbol 实现文档

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

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

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

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

还有 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

区分两种情况:

  • 如果最后一个字符是vbCRChr(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

【讨论】:

    【解决方案2】:

    我可以制定一个似乎工作正常的解决方法。

    Sub AppendSymbol(ByRef orig As TextRange, ByVal fontName As String, ByVal charCode As Integer, Optional ByVal position As Integer = -1)
        Dim strStart, strEnd As String
    
        If ((position < 0) Or (position >= Len(orig.text))) Then
            orig.Paragraphs(orig.Paragraphs.Count + 1).InsertSymbol fontName, charCode
            'this one just inserts the symbol at the end by forcing a new paragraph
        Else
            strStart = Left(orig.text, position)
            strEnd = Right(orig.text, Len(orig.text) - position)
    
            orig.Paragraphs(1).InsertSymbol fontName, charCode
            orig.InsertBefore strStart
            orig.InsertAfter strEnd
        End If
    End Function
    

    在那个 sub 中,我基本上是复制原始行,用符号替换它,然后在符号周围重新附加字符串。

    我现在可以这样称呼那个 Sub:

    Private Sub displayTotal(ByRef para As TextRange, ByVal prevCompare As Testing)
        Dim arrowDirection As String
        Dim tempDifference As Integer
    
        tempDifference = p_total - prevCompare.Total
        para.InsertAfter "Number of elements : " & p_total & " ("
    
        'calling the Sub
        AppendSymbol para, "Wingdings", getWingdingArrowChar(getArrowDirection(tempDifference))
    
        para.InsertAfter " " & Abs(tempDifference) & ")"
        para.IndentLevel = 2
        para.ParagraphFormat.Bullet = msoFalse
    End Sub
    

    至于解释,Asger 似乎有点意思。该方法的实现,显然类似于 Word 的,需要先折叠文本范围,然后才能添加符号。

    在上面的自定义方法中,orig.Paragraphs(orig.Paragraphs.Count + 1).InsertSymbol fontName, charCode 行基本上是通过在其后添加一个段落来强制当前段落折叠,这就是为什么InsertSybol 方法可以按预期工作的原因。

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 2020-05-29
      • 2016-09-18
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多