Обработка фигуры по имени заполнителя в PowerPoint
Я пытаюсь создать функцию, которая вернет определенную форму, основанную на известный свойство Name, присвоенное . Я не могу использовать форму .Name
потому что это не известно заранее, еще при создании слайдов из шаблона/макета.
проблема заключается в том, как пользовательский макет связан с фактическим слайдом. Например, когда я повторяю слайд .CustomLayout.Shapes.Placeholders
, Я могу легко определить конкретный заполнитель .Name
собственность.
если я вернусь этой shape, это будет пользовательский заполнитель макета, который влияет на все слайды на этом макете (например, если я добавляю текст в этот заполнитель, он обновляет все слайды с помощью этого макета!). Очевидно, что это нежелательно!
если вместо этого я индексирую коллекцию и пытаюсь вернуть фигуру в этом положении индекса из.Shapes.Placeholders
, похоже, что они не поддерживают тот же индекс, т. е. .Shapes.Placeholders(i) <> .CustomLayout.Shapes.Placholders(i)
попытка обойти:
думал, что я мог бы манипулировать пользовательским макетом, чтобы добавить Tag
для фигуры. Я пробовал, и это не удается по тем же причинам (т. е. CustomLayout.Форма как-то не "такая же" форма, как слайд.Форма...). В любом случае, я надеюсь избежать "обходного пути" в пользу более правильного способа сделать это, если такая вещь существует.
это функция, которую я так далеко:
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
3 ответов
у меня есть потенциальное решение для вас.
проблема заключается в нижнем колонтитуле, номере страницы и заполнителях даты на мастере слайдов. Они включены в коллекцию заполнителей на мастере слайдов, но при создании отдельного слайда они становятся своими собственными свойствами слайда (под .HeaderFooter
свойства). Это приводит к различному количеству заполнителей на ведущем устройстве и на слайдах, и поскольку эти заполнители могут находиться в середине коллекции, индексы не совпадают.
Итак, одним из возможных решений является удаление этих трех заполнителей из вашего мастера, что делается путем открытия мастера слайдов и снятия флажка нижнего колонтитула. Если вы сделаете это, вы обнаружите, что количество заполнителей на главном и на слайдах одинаковое, и все номера индексов выстраиваются в линию. Вы все еще не можете использовать SlideMaster.CustomLayouts(n).Shapes.Placeholders(m).Name
свойство для доступа к правильному заполнителю на фактическом слайде. Однако, как только вы знаете индекс заполнителя ("m" в моем примере в последнем предложении), вы должны иметь доступ к правильному заполнителю на слайде через SlideObj.Shapes.PlaceHolders(m)
. Вы можете повторить через SlideMaster.Формы.Сначала заполнители и сохраните индекс для последующего использования.
Если вам нужны поля нижнего колонтитула, просто добавьте новые текстовые заполнители в мастер слайдов, поместите их в нижней части слайда, а затем вставьте в них номер страницы, дату или фиксированный текст.
резюме:
снимите флажок нижние колонтитулы на всех мастерах слайдов, о которых вы заботитесь. Не уверен, что это можно сделать программно.
перебираем
ActivePresentation.SlideMaster.CustomLayout(n).Shapes.Placeholders
для каждого из ваших мастеров слайдов (пользовательские макеты), глядя на .Name свойство, чтобы найти заполнитель(Ы), который вас интересует. Сохраните это в массиве (будет использовать имя заполнителя в качестве имени массива, поэтому, если имя заполнителя было "datatable", я бы использовал datatable[n])=индекс # заполнителя на CustomLayout/Master. Сделать это один раз и сохранить его в глобальной переменной.если вы хотите получить доступ к заполнителю на слайде, получите индекс SlideMaster для слайда с SM_index=SlideObj.CustomFormat.Индекс. Затем откройте заполнитель "datatable" с помощью SlideObj.Формы.Заполнители (datatable[SM_index])
если у вас есть только один SlideMaster для всех ваших слайдов, то вам не нужен массив и вместо этого можно использовать простую переменную.
если вам нужен настоящий код, дайте мне знать , но я ожидаю, что вы этого не сделаете. Дайте мне знать, если это сработает в вашем проекте реального мира.
мой текущий обходной путь должен сделать следующее:
Delcare модульного уровня Dictionary
объект, который создает своего рода хэш-таблицы на основе слайда CustomLayout
и известный индекс каждого заполнителя в Slide.Shapes
коллекция. (Это я получаю через простую for / Next итерацию в подпрограмме throwaway).
так как я строю слайды из шаблона, я думаю, что это относительно безопасно и надежно, но не гибкий (весь пункт работы с файлы potx шаблон файлы простота использования и гибкости...).
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
У меня есть другое решение. Я перебираю все фигуры на слайде и сравниваю их с некоторыми свойствами фигуры в пользовательском макете. Я взял ширину, высоту и autoshapetype. Если они точно такие же, я нашел соответствующую форму на слайде.
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