粘贴的形状不被视为“最新”形状

Sat*_*in2 2 excel powerpoint vba shapes

我正在从 Excel 电子表格自动生成 PowerPoint 报告。在我粘贴表格之前,我已经完成了这个过程。

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

要引用我使用的新形状,Set pShape = Slide2.Shapes(Slide2.Shapes.Count)但现在当我粘贴时,pShape分配了“形状 2”(而不是“形状 3”)。在粘贴和分配对象之间有什么需要做的吗?

下面的代码,评论了问题发生的地方。(已删除完整代码;可在此处查看)

'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
Run Code Online (Sandbox Code Playgroud)

ash*_*awg 5

'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
Run Code Online (Sandbox Code Playgroud)

注意: 用于Excel替代代码在这个岗位的底部!

为了演示,我们可以向新文档添加形状

  • 首先,通过单击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 ????????

请注意,索引不是此对象的属性,但它按照 Excel 在内存中存储形状的顺序进行计数(与For Each..Next语句返回的顺序相同。

另一种了解 Excel 如何存储形状的方法是使用Watch Window。添加特征线或Stop在循环中间,然后突出显示ws.Shapes,右键单击它,选择Add Watch...并单击确定。浏览树以发现文档中形状的各种属性/属性。


  • 接下来,如果我们删除“中间矩形”并再次运行上述程序,我们将得到:

    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剩下的形状没有改变,但指数被重新编号,以反映新的“秩序”。

...从而返回Rectangle 5我们现在需要使用的名称:

Debug.Print ActivePresentation.Slides(1).Shapes(4).Name  
Run Code Online (Sandbox Code Playgroud)

参考形状(包括控件

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

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

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


检索“最后创建的形状”

如果使用索引号的唯一原因是检索“最后创建的形状”,那么您可以使用这样的函数来获取索引号:

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
Run Code Online (Sandbox Code Playgroud)

示例用法:

Debug.Print idxLastShape(1) 'Returns index of last shape on slide#1
Run Code Online (Sandbox Code Playgroud)

注意: 用于Excel交替代码在这个岗位的底部!


或者,您可以让函数返回对实际形状对象的引用,而不是数字,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

...所以你可以得到“最后一个形状”的名称:

Debug.Print LastShape(1).Name
Run Code Online (Sandbox Code Playgroud)

删除最近创建的形状

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

LastShape(1).Delete
Run Code Online (Sandbox Code Playgroud)

警告 警告!

帖子中的示例(包括删除示例!)不分青红皂白地返回/编辑/删除什么类型的形状!

几十种类型的形状,从图形到声音/视频和控制。您可以使用对象的.Type属性Shape以及其他方法过滤这些过程枚举的形状。有一个部分列表这里,然后在下面的链接了解更多信息。


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
Run Code Online (Sandbox Code Playgroud)

返回“最后一个形状”的索引号(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
Run Code Online (Sandbox Code Playgroud)

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


返回对“最后一个形状”对象的引用(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
Run Code Online (Sandbox Code Playgroud)

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


更多信息:

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