3

PowerPoint アドインで、スライド上の図形にアクセスしたいと考えています。形状は、スライドマスターのカスタム レイアウトで定義されたプレースホルダーです。

カスタム レイアウトに基づいてスライドを追加すると、図形には「プレースホルダー 1」、「プレースホルダー 2」、...という名前が付けられます。

マスターに指定された名前でプレースホルダーを取得する方法はありますか?

現在、私はこのコードで形状を検索しています:

public static Shape GetShape(string stringToSearch, Shapes shapes) {

        foreach (Shape shape in shapes) {

            if (shape.Name == stringToSearch) {
                return shape;
            }

            // Search Groups
            if (shape.Type == MsoShapeType.msoGroup) {
                foreach (Shape childshape in shape.GroupItems) {
                    if (childshape.Name == stringToSearch) {
                        return childshape;
                    }
                }
            }
        }

        throw new KeyNotFoundException("No Shape found");
}

更新: わかりやすくするために、これは PowerPoint プレゼンテーションの構造です。

プレースホルダーに名前が定義されたマスター: マスターのスクリーンショット

マスターで定義された名前が失われるプレゼンテーション: プレゼンテーションのスクリーンショット

問題: マスターで定義された名前でプレゼンテーションの要素を取得する方法は?

4

1 に答える 1

0

さて..これがスティーブの「アグリー!」です。解決。

私のプロジェクトでは、形状の作成を制御したり制御したりしたくないため、それらに「タグ付け」することはできません。そのため、それらを識別するためのカスタム プレースホルダー名を使用しています。そのため、形状の名前は実際には [PlaceholderType] ## になります。

手順:

  • すべての形状の位置を保存する
  • スライド レイアウトをリセットする
  • スライドの形状とマスター スライドの形状を一致させる
  • すべての形状の位置を復元します。

注: シェイプ グループは使用しません。この手法は、グループ内をチェックする必要がある場合、さらに複雑になります。

これはそれを行い、mastershapename - shapename マッピングを返す関数です。

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;
}

これでできること

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

そして、これは 2 つの形状を取り、それらが「等しい」かどうかをチェックする比較関数です。より正確にするために拡張することができます。

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;
}

元の形状の場所を格納する小さなクラス

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

私もこれが好きではないので、提案を受け付けています。シェイプとプレースホルダーをリンクする方法は他にないようです。shape.MasterShape私たちが見逃しているものは本当にありませんよね?

于 2014-01-18T19:24:16.130 に答える