粘贴的形状未被视为 "Latest" 形状

Pasted Shape not seen as "Latest" Shape

我正在使用 Excel 电子表格自动生成 PowerPoint 报告。在粘贴 table.

之前,我已经完成了整个过程

我正在使用 PPApp.CommandBars.ExecuteMso ("PasteSourceFormatting") 将 table 粘贴到 PowerPoint,并且 table 在我的幻灯片上显示为一个形状(第三个形状)。

为了引用我使用 Set pShape = Slide2.Shapes(Slide2.Shapes.Count) 的新形状,但现在当我粘贴时,pShape 被指定为 "Shape 2"(而不是 "Shape 3")。对象的粘贴和赋值之间有什么需要做的吗?

下面的代码,在出现问题的地方进行了注释。 (已删除完整代码;可见 here

'Copy tables from Excel
Set rng = ws.Range("A:A")
rng.ColumnWidth = 22.75
Set rng = ws.Range("A4:C27")

'Copy the table range
Application.CutCopyMode = False
rng.Copy
Application.Wait (Now + TimeValue("0:00:02"))

'The issue occurs here!!! '-------------------------------------
'Paste the table in to the slide
Slide2.Select
PPApp.CommandBars.ExecuteMso ("PasteSourceFormatting")

'Name the new shape object
Set pShape = Slide2.Shapes(Slide2.Shapes.Count)
pShape.Name = "Slide_2_Table_1"
pShape.LockAspectRatio = False

'Shapes.Count' ≠ 形状索引# !

.Count与当前形状上限.Index个数不一样

通过列出文档中的所有形状,编号系统更容易理解:

Sub ListShapes()
    'hit CTRL+G to view output in Immediate Window
    Dim sh As Shape, sld As Slide, idx As Long
    Set sld = ActivePresentation.Slides(1) '<-- change to your slide number
    For Each sh In sld.Shapes
        idx = idx + 1
        Debug.Print "Shape ID#" & sh.Id, "Index #" & idx, "Name: " & sh.Name
    Next sh
    Debug.Print "Count of shapes: " & sld.Shapes.Count
End Sub

NOTE: There is alternative code for Excel at the bottom of this post!

为了演示,我们可以add shapes新建一个文件:

  • 首先,通过单击 Insert(在功能区上)手动添加一个矩形
  • [如果使用 Excel,单击 Illustrations],然后单击 Shapes,然后单击矩形符号。
  • 画出形状,然后按Ctrl+C复制,按Ctrl+C四次粘贴4份。
  • 运行 上述程序,输出为:

    Shape ID#2 Index #1 Name: Rectangle 1
    Shape ID#3 Index #2 Name: Rectangle 2
    Shape ID#4 Index #3 Name: Rectangle 3
    Shape ID#5 Index #4 Name: Rectangle 4
    Shape ID#6 Index #5 Name: Rectangle 5
    Count of shapes: 5         

请注意,索引 不是此 object 的 属性,但它是为了 Excel 存储内存中的形状(与 return 由 For Each..Next 语句编辑的顺序相同。

  • 你可以通过运行ning来证明这一点:

    Debug.Print ActivePresentation.Slides(1).Shapes(5).Name  
    

    ...在这种情况下 return Rectangle 5.

了解 Excel 如何存储形状的另一种方法是使用 Watch Window。在循环中间添加断线或Stop,然后突出显示ws.Shapes、right-click,选择Add Watch...并单击确定。浏览树以发现文档中形状的变化 properties/attributes。


  • 接下来,如果我们再次删除"middle rectangle"和运行上述程序,我们将得到:

    Shape ID#2 Index #1 Name: Rectangle 1
    Shape ID#3 Index #2 Name: Rectangle 2
    Shape ID#5 Index #3 Name: Rectangle 4
    Shape ID#6 Index #4 Name: Rectangle 5
    Count of shapes: 4         

其余形状的IDName不变,但索引重新编号为反映新 "order".

...因此 return 名称 Rectangle 5 我们现在需要使用:

Debug.Print ActivePresentation.Slides(1).Shapes(4).Name  

参考形状(包括controls)

当您按数字引用形状时,例如 .Shapes(),您指的是形状 索引号 ,而不是 ID 号码。 索引号是根据需要动态分配的,因此不是一种稳定的方法来引用形状。

  • 因此,.Count与形状无关索引号

理想情况下,您应该通过 .Name.ID 数字来引用形状。如果动态生成形状,最好将形状列表存储在数组或 collection 中,这样您就可以根据需要查看列表。


检索"Last Shape Created"

如果使用索引号的唯一原因是检索"last shape created",那么您可以使用这样的函数来获取索引号:

Function idxLastShape(slideNum As Long) As Long
    Dim sh As Shape
    For Each sh In ActivePresentation.Slides(slideNum).Shapes
        idxLastShape = idxLastShape + 1
    Next sh
End Function

用法示例:

Debug.Print idxLastShape(1) 'Returns index of last shape on slide#1

NOTE: There is alternate code for Excel at the bottom of this post!


或者,您可以让函数 return 引用实际的 形状 object,而不是比数字,像这样:

Function LastShape(slideNum As Long) As Shape
    Dim sh As Shape
    For Each sh In ActivePresentation.Slides(slideNum).Shapes
        Set LastShape = sh
    Next sh
End Function

...因此您可以获得 "last shape" 的名称:

Debug.Print LastShape(1).Name

删除最近创建的形状

使用上面的函数,您可以使用通常用于形状的任何方法。例如,您可以删除在幻灯片 #1:

上创建的 "last shape"
LastShape(1).Delete

CAUTION!

The examples in the post (including the deletion example!) are indiscriminate of what type of shape they're returning/editing/deleting!

There are dozens of types of shapes, from graphics to sound/video and controls. You can filter the shapes being enumerated by these procedures using the .Type property of the Shape object, as well as other methods. There is a partial list here, and more information in the links below.


Excel的替代代码:

列出工作表上的所有形状 (Excel)

Sub ListShapes()
    'hit CTRL+G to view output in Immediate Window
    Dim sh As Shape, ws As Worksheet, idx As Long
    Set ws = Sheets("Sheet1") '<-- change to your worksheet name
    For Each sh In ws.Shapes
        idx = idx + 1
        Debug.Print "Shape ID#" & sh.ID, "Index #" & idx, "Name: " & sh.Name
    Next sh
    Debug.Print "Count of shapes: " & Sheets("Sheet1").Shapes.Count
End Sub

Return "last shape" (Excel)

的索引号
Function idxLastShape(shtName As String) As Long
    Dim sh As Shape
    For Each sh In Sheets(shtName).Shapes
        idxLastShape = idxLastShape + 1
    Next sh
End Function

用法示例: Debug.Print idxLastShape("Sheet1")


Return 参考 "last shape" object (Excel)

Function LastShape(shtName As String) As Shape
    Dim sh As Shape
    For Each sh In Sheets(shtName).Shapes
        Set LastShape = sh
    Next sh
End Function

用法示例: Debug.Print LastShape("Sheet1").Name


更多信息:

从 Excel 复制到 Powerpoint 的其他方法: