开发者

Get Layout Shape Corresponding to Slide Shape

开发者 https://www.devze.com 2022-12-16 20:54 出处:网络
In PowerPoint 2007 and using VBA, how can I get the placeholder shape on a Slide Master layout that is the \"master\" for a placeholder shape on the slide?

In PowerPoint 2007 and using VBA, how can I get the placeholder shape on a Slide Master layout that is the "master" for a placeholder shape on the slide?

I am currently using a loop to compare the position and size of the slide placeholder with the position and shape of each placeholder shape in the slide's layout, but this isn't fool-proof. For example, if the placeholder shape is moved on the slide, its position may no longer match the position of any placeholder shapes in the slide's layout. I could reap开发者_如何学Cply the slide's layout to snap placeholders back into position, but that's not what I want to do.

Something in the object model like Shape.Master would be ideal but, of course, that doesn't exist.


Seeing as there is still no answer to this here or elsewhere I might as well post my code.

For example, if the placeholder shape is moved on the slide,

Here's what I came up with to handle that:

  • store the locations of all shapes
  • reset the slide layout
  • match slide shapes and master slide shapes
  • restore the locations of all shapes.

This is the function that does that and returns a mastershapename - shapename mapping.

private Dictionary<string, string> GetShapeMasters(Powerpoint.Slide s)
{
    Dictionary<string, string> shapeMasters = new Dictionary<string, string>();
    List<ShapeLocation> shapeLocations = new List<ShapeLocation>();

    //store locations
    foreach (Powerpoint.Shape sh in s.Shapes)
    {
        shapeLocations.Add(new ShapeLocation()
        {
            Name = sh.Name,
            Location = new System.Drawing.RectangleF(sh.Left, sh.Top, sh.Width, sh.Height)
        });
    }

    //have powerpoint reset the slide
    //ISSUE: this changes the names of placeholders without content.
    s.CustomLayout = s.CustomLayout;

    //compare slide and master
    foreach (Powerpoint.Shape sh in s.Shapes)
    {
        foreach (Powerpoint.Shape msh in s.CustomLayout.Shapes)
        {
            if (IsShapeMaster(sh, msh))
            {
                shapeMasters[msh.Name] = sh.Name;
            }
        }
    }

    //restore locations
    //TODO: might be replaced by undo
    foreach (var shm in shapeLocations)
    {
        Powerpoint.Shape sh = null;
        try
        {
            sh = s.Shapes[shm.Name];
        }
        catch 
        {
            //Fails for renamed placeholder shapes.
            //Have yet to find a decent way to check if a shape name exists.
        }

        //placeholders do not need to be restored anyway.
        if (sh != null)
        {
            sh.Left = shm.Location.Left;
            sh.Top = shm.Location.Top;
            sh.Width = shm.Location.Width;
            sh.Height = shm.Location.Height;
        }
    }

    return shapeMasters;
}

With this you can do

Dictionary<string, string> shapeMasters = GetShapeMasters(theSlide);
if(shapeMasters.ContainsKey("KnownPlaceholderName"))
    Powerpoint.Shape KnownShape = theSlide[shapeMasters["KnownPlaceholderName"]];

And here is the comparison function that takes two shapes and checks if they are "equal". Could be extended to make it more precise.

private bool IsShapeMaster(Powerpoint.Shape sh, Powerpoint.Shape msh)
{
    return
        sh.Left == msh.Left
        && sh.Top == msh.Top
        && sh.Width == msh.Width
        && sh.Height == msh.Height
        && sh.Type == msh.Type
        && sh.PlaceholderFormat.Type == msh.PlaceholderFormat.Type;
}

Little class that stores original shape location

class ShapeLocation
{
    public string Name;
    public System.Drawing.RectangleF Location;
}

This is code from a C# VSTO Add-in but I suppose it is not that different from VB or other PPT automation types.


Here you go Ryan, I believe this is what you're asking for.

Sub GetLayoutShapeDetails()
Dim myPPT As Presentation
Set myPPT = ActivePresentation
Dim mySlide As Slide
Set mySlide = myPPT.Slides(6)
Dim slideShape As Shape
Dim slideLayoutShape As Shape
Set slideShape = mySlide.Shapes(1)
If slideShape.Type = msoPlaceholder Then
    Dim placeHolderType As Integer
    placeHolderType = slideShape.PlaceholderFormat.Type
    Set slideLayoutShape = mySlide.CustomLayout.Shapes.Placeholders(placeHolderType)
    Dim modifiedPlaceHolder As String
    modifiedPlaceHolder = "Shape Name: " & slideShape.Name & _
        ", Left: " & slideShape.Left & _
        ", Width: " & slideShape.Width
    Dim originalPlaceHolder As String
    originalPlaceHolder = "Shape Name: " & slideLayoutShape.Name & _
        ", Left: " & slideLayoutShape.Left & _
        ", Width: " & slideLayoutShape.Width
    Debug.Print modifiedPlaceHolder
    Debug.Print originalPlaceHolder
End If
End Sub

EDIT: JAN 16, 2010 Based off of further research, there doesn't not appear to be a way in VBA to find a shape's corresponding exact match in its slide's layout.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号