首页 > 解决方案 > 当 HasTextFrame 不可靠时如何识别哪些形状有文本?

问题描述

我正在尝试更改 SmartArt 中的文本。特别是这种类型: 列表与图片

我可以在两台机器上复制下面的最小工作示例。

.HasText = msoTrue即使调试器这么说,这段代码也会进入分支.HasText = 0。这会导致shi.TextFrame.TextRange.Text失败。

Sub enumerate_subshapes(shi As Shape, Optional depth As Integer = 0)
    'If True Then
    If shi.HasTextFrame Then
        If shi.TextFrame.HasText Then
            Debug.Print depth & " YES: ", shi.Type, shi.HasTextFrame, shi.TextFrame.HasText, shi.TextFrame.TextRange.Text
        Else
            Debug.Print depth & " NO: ", shi.Type, shi.HasTextFrame, shi.TextFrame.HasText
        End If
    End If
    Select Case shi.Type
        Case msoSmartArt
            For i = 1 To shi.GroupItems.Count
                enumerate_subshapes shi.GroupItems.Item(i), depth + 1
            Next i
    End Select

End Sub

Sub vba_bug_mwe()
    Dim shi As Shape
    For Each shi In ActivePresentation.Slides(1).Shapes
        Debug.Print "############### " & shi.Name
        enumerate_subshapes shi
    Next
End Sub

如果您取消注释该If true then行并注释该If shi.HasTextFrame Then行,那么您会得到预期的结果,即内部测试正常工作。

TBH 对我来说它看起来像一个错误,在这种情况下它并不真正属于这里。但也许我缺少一些 VBA 的微妙之处。

标签: vbapowerpoint

解决方案


一块 SmartArt 是一组嵌套的形状。您需要深入到各个子形状以获取任何有用的信息。你还没有说明你的总体目标,但这里是如何从每个节点获取文本:

Sub GetSmartArtNodeText()
    Dim oShape As Shape
    Dim oNode As SmartArtNode
    For Each oShape In ActivePresentation.Slides(1).Shapes
        If oShape.HasSmartArt = True Then
            For Each oNode In oShape.SmartArt.Nodes
                MsgBox oNode.TextFrame2.TextRange.Text
            Next oNode
        End If
    Next oShape
End Sub

推荐阅读