我正在尝试根据分配给CustomLayout.Shapes.Placeholder
对象的已知 Name属性创建一个返回特定形状的函数。我不能使用形状.Name
,因为即使从模板/布局创建幻灯片,也不会提前知道。
挑战似乎是自定义布局与实际幻灯片的关系。例如,当我迭代幻灯片的.CustomLayout.Shapes.Placeholders
时,我可以通过它的.Name
属性轻松识别特定的占位符。
但如果我返回此形状,它将是自定义布局占位符,会影响此布局上的所有幻灯片(例如,如果我将文本添加到此占位符,它使用此布局更新所有幻灯片!)。显然这是不可取的!
如果相反,我索引集合,并尝试从幻灯片的.Shapes.Placeholders
返回该索引位置的形状,看起来它们没有保持相同的索引,即.Shapes.Placeholders(i) <> .CustomLayout.Shapes.Placholders(i)
< / p>
尝试的解决方法:
我想我可以操纵自定义布局,为形状添加Tag
。我尝试了,但由于同样的原因它失败了(即,CustomLayout.Shape在某种程度上不是与Slide.Shape“相同”的形状......)。在任何情况下,如果存在这样的事情,我希望避免使用“解决方法”来支持更合适的方法。
这是我到目前为止的功能:
Function GetShapeByPlaceholderName(sName As String, sld As Slide) As Object
Dim plchldrs As Placeholders
Dim shp As Shape
Dim ret As Shape
Dim i As Long
For Each shp In sld.CustomLayout.Shapes.Placeholders
i = i + 1
If shp.Name = sName Then
'####
' This can easily identify the CustomLayout.Shapes.PLACEHOLDER
'
' But I need to return the SHAPE in the Slide.Shapes collection
'####
'###
Set ret = shp 'This will return the CustomLayout.Placeholder, which affects ALL slides
'###
'Set ret = sld.Shapes.Placeholders(i) 'the index of the Shapes.Placeholders is NOT the same
'###
'Set ret = sld.Shapes.Placeholders.FindByName(sName) 'This returns an error/specified shape name does not exist
'###
'Set ret = sld.Shapes.Placeholders.FindByName(i) 'This observes same failure that the index of the collections is not the same
Exit For
End If
Next
Set GetShapeByPlaceholderName = ret
End Function
答案 0 :(得分:9)
我有一个潜在的解决方案。
问题是幻灯片母版上的页脚,页码和日期占位符。它们包含在幻灯片母版的占位符集合中,但是当创建单个幻灯片时,它们将成为幻灯片的自己属性(在.HeaderFooter
属性下)。这会导致Master和幻灯片上的占位符数不同,并且因为这些占位符可能位于集合的中间,所以索引不会对齐。
因此,一种可能的解决方案是从Master中删除这三个占位符,方法是打开Slide Master并取消选中页脚复选框。如果这样做,您会发现Master和Slides上的占位符数相同,并且所有索引号都排成一行。您仍然无法使用SlideMaster.CustomLayouts(n).Shapes.Placeholders(m).Name
属性访问实际幻灯片上的正确占位符。但是,一旦您知道占位符的索引(&#34; m&#34;在我的示例中的最后一句),您应该能够通过SlideObj.Shapes.PlaceHolders(m)
访问幻灯片上的正确占位符。您可以先遍历SlideMaster.Shapes.PlaceHolders并存储索引供以后使用。
如果您需要页脚字段,只需将新的文本占位符添加到幻灯片母版,将它们放在幻灯片的底部,然后将页码,日期或固定文本插入其中。
要点:
取消选中您关注的所有幻灯片母版上的“页脚”复选框。不确定这是否可以以编程方式完成。
为每个幻灯片母版(自定义布局)迭代ActivePresentation.SlideMaster.CustomLayout(n).Shapes.Placeholders
,查看.Name属性以查找您感兴趣的占位符。将其存储在数组中(将使用名称)占位符作为数组名称,因此如果占位符名称为&#34; datatable&#34;我将使用CustomLayout / Master上占位符的datatable [n])= index#。执行一次并将其存储在全局变量中。
如果要访问幻灯片上的占位符,请使用SM_index = SlideObj.CustomFormat.Index获取幻灯片的SlideMaster索引。然后访问占位符&#34; datatable&#34;使用SlideObj.Shapes.Placeholders(datatable [SM_index])
如果您的所有幻灯片只有一个SlideMaster,那么您不需要一个数组,而是可以使用一个简单的变量。
如果您需要实际代码,请告诉我 - 但我希望您不要。如果这适用于您的真实世界项目,请告诉我。
答案 1 :(得分:2)
我目前的解决方法是执行以下操作:
Delcare一个模块级Dictionary
对象,它根据幻灯片的CustomLayout
和Slide.Shapes
集合中每个占位符的已知索引创建一种哈希表。 (这是我在一次性子程序中通过简单的FOr / Next迭代获得的。)
由于我正在从模板构建幻灯片,我认为这是相对安全可靠的,但不灵活(使用POTX 模板文件的整点应该是< em>易用性和灵活性......)。
Dim dictShapes As Object 'Dictionary
然后根据CustomLayout
Sub SetShapeDict(cLayout as Object)
Set dictShapes = CreateObject("Scripting.Dictionary")
Select Case cLayout.Name
Case "layout_one"
dictShapes("chart RIGHT") = 1
dictShapes("chart RIGHT title") = 2
dictShapes("chart LEFT") = 5
dictShapes("chart LEFT title") = 6
Case "layout_two"
dictShapes("chart RIGHT") = 1
dictShapes("chart RIGHT title") = 2
dictShapes("q text") = 4
dictShapes("source text") = 5
End Select
End Sub
我将此功能称为:
Dim shp as Object 'PowerPoint.Shape
Set shp = GetShapeByIndex(shp.Parent, dictShapes("chart RIGHT"))
字典初始化的方式是我可以传递一个字符串参数,它将返回形状的索引,所有应该工作。
Function GetShapeByIndex(chartSlide As Object, i As Long) As Object
Dim ret
Dim s As Long
'if slide #1, there is no "Slide Number Placeholder"
' this placeholder appears in the shapes' 3rd index for
' both Vertical Master no Background AND Horizontal Master
If chartSlide.SlideNumber = 1 Then
If i > 2 Then
s = i - 1
Else
s = i
End If
Else
s = i
End If
On Error Resume Next
Set ret = chartSlide.Shapes(s)
If Err.Number <> 0 Then Set ret = Nothing
On Error GoTo 0
Set GetShapeByIndex = ret
End Function
答案 2 :(得分:2)
我有另一种解决方法。我遍历幻灯片中的所有形状,并将它们与自定义布局中形状的某些形状属性进行比较。我采用宽度,高度和自动形状。如果它们完全相同,我在幻灯片中找到了相应的形状。
For Each sh In sl.Shapes
With sl.CustomLayout.Shapes("Name of shape in layout")
If sh.Width = .Width And _
sh.Height = .Height And _
sh.AutoShapeType = .AutoShapeType Then
bFound = True
Exit For
End If
End With
Next sh
If bFound Then
'sh is the shape you are looking for
End If