如何在word中用vba实现InlineShape和Shape对象的转换?

在word vba中 shape对象表示位于文字上方的位于图层的图片,InlineShape对象表示位于一段文字中间的,就像是字符一样的图片,但是有个特别要注意的就是 An inline shape can only be a picture, an OLE object, or an ActiveX control  InlineShape对象 只能是图片、OLE对象或者 ActiveX控件

如果要把shape对象转换为InlineShape对象,可以使用ConvertToInlineShape方法,并且返回InlineShape对象。【注:经过测验,这个方法仅仅是把shape对象的环绕方式改为嵌入式,并不能完全转成InlineShape对象

如果要把InlineShape对象转换为shape对象,可以使用 ConvertToShape方法,并且返回shape对象。

凡是打开旧版本的word,所有的图形对象都会转换为InlineShape对象。

另外一个shape对象要转换为InlineShape对象,还可以直接设置shape对象的文字环绕方式为“嵌入型”,就可以转化为InlineShape对象。

【PS:设置shape对象的文字环绕方式为“嵌入型”,并不能把Shape对象都转换为InlineShape对象,因为有些Shape对象是不能转换为InlineShape对象的,比如在word中插入的形状就不能转换为InlineShape对象。An inline shape can only be a picture, an OLE object, or an ActiveX control 】

基于上述的知识,可以使用如下的vba代码将word文档中的所有Shape对象转成InlineShape对象:

Sub QQ1722187970()
    Dim oSP As Shape
    Dim oISP As InlineShape
    Dim oDoc As Document
    Set oDoc = Word.ActiveDocument
    For Each oSP In oDoc.Shapes
        Debug.Print oSP.Type
        oSP.ConvertToInlineShape
    Next
End Sub

但是在实际的应用过程中发现,用上述代码转换后还是有很多Shape对象没有转成InlineShape对象,这个是word vba的bug。

为了解决这个问题,需要每次将要转换的Shape对象的名称都存入数组中,然后再逐个进行转换,代码如下:

Sub QQ1722187970()
    Dim oSP As Shape
    Dim oISP As InlineShape
    Dim oDoc As Document
    Set oDoc = Word.ActiveDocument
    Dim arr()
    Dim k
    k = 0
    With oDoc
        Debug.Print .Shapes.Count
        Debug.Print .InlineShapes.Count
        For Each oSP In .Shapes
'            oSP.Select
'            oSP.ConvertToInlineShape
            ReDim Preserve arr(k)
            arr(k) = oSP.Name
            k = k + 1
        Next
        For i = 0 To UBound(arr)
            sName = arr(i)
            Set oSP = .Shapes(sName)
'            oSP.Select
            oSP.ConvertToInlineShape
        Next i
    End With
End Sub

而对于InlineShape对象转成Shape对象可以直接使用如下的vba代码实现:

Sub QQ1722187970()
    Dim oSP As Shape
    Dim oISP As InlineShape
    Dim oDoc As Document
    Set oDoc = Word.ActiveDocument
    For Each oISP In oDoc.InlineShapes
       oISP.ConvertToShape
    Next
End Sub

基于上述的分析,有时候我们需要的是批量将所有图形在“嵌入式”和其它文字环绕方式中转换,而不是将对象在InlineShape和Shape之间转换,这时候可以使用Shape对象的WrapFormat属性修改。

这时候可以使用如下的vba代码:

Sub QQ1722187970()
    Dim oSP As Shape
    Dim oISP As InlineShape
    Dim oDoc As Document
    Set oDoc = Word.ActiveDocument
    Dim arr()
    Dim k
    k = 0
    With oDoc
        Debug.Print .Shapes.Count
        Debug.Print .InlineShapes.Count
        '以下代码将所有图形的环绕方式都转为嵌入式
        For Each oSP In .Shapes
            ReDim Preserve arr(k)
            arr(k) = oSP.Name
            k = k + 1
        Next
        For i = 0 To UBound(arr)
            sName = arr(i)
            Set oSP = .Shapes(sName)
            oSP.ConvertToInlineShape
        Next i
        
        '以下代码将所有嵌入式的图形都转换为其它形式
        
        For Each oSP In .Shapes
            ReDim Preserve arr(k)
            arr(k) = oSP.Name
            k = k + 1
        Next
        For i = 0 To UBound(arr)
            sName = arr(i)
            Set oSP = .Shapes(sName)
            With oSP
                If .WrapFormat.Type = wdWrapInline Then
                    '环绕方式转为四周型
                    .WrapFormat.Type = wdWrapSquare
                End If
            End With
        Next i
        
        For Each oISP In .InlineShapes
            oISP.ConvertToShape
        Next
        
    End With
End Sub

有时候我们希望只对选中的区域执行图片环绕方式的转换,可以使用如下的vba代码:

Sub QQ1722187970()
    Dim oSP As Shape
    Dim oISP As InlineShape
    Dim oDoc As Document
    Set oDoc = Word.ActiveDocument
    Dim oRng As Range
    If Word.Selection.Start = Word.Selection.End Then
    Dim arr()
    Dim k
    k = 0
    With oDoc
        Debug.Print .Shapes.Count
        Debug.Print .InlineShapes.Count
        '以下代码将所有图形的环绕方式都转为嵌入式
        For Each oSP In .Shapes
            ReDim Preserve arr(k)
            arr(k) = oSP.Name
            k = k + 1
        Next
        For i = 0 To UBound(arr)
            sName = arr(i)
            Set oSP = .Shapes(sName)
            oSP.ConvertToInlineShape
        Next i
        
    
        
    End With
    Else
        
        iStart = Word.Selection.Start
        iEnd = Word.Selection.End
        
    With oDoc
        Debug.Print .Shapes.Count
        Debug.Print .InlineShapes.Count
        '以下代码将所有图形的环绕方式都转为嵌入式
        For Each oSP In .Shapes
            ReDim Preserve arr(k)
            arr(k) = oSP.Name
            k = k + 1
        Next
        For i = 0 To UBound(arr)
            sName = arr(i)
            Set oSP = .Shapes(sName)
            If oSP.Anchor.Start >= iStart And oSP.Anchor.End <= iEnd Then
                oSP.ConvertToInlineShape
            End If
        Next i
    End With
    End If
End Sub

 

       

仅有1条评论 发表评论

  1. 匿名 /

    03版doc类型的文件,无法运行

  2. 匿名 /

    大师级成果,牛

  3. 匿名 /

    发现不能运行。
    运行到
    oSP.converttoinlineshapes提示:参数无效。

发表评论