hiroshi akutsuの日記

主にプログラミング関係のこと

vba【図としてコピーした画像をpower pointへ貼り付け時に変数に代入】

大量のグラフをパワーポイントに貼り付ける作業をやることがあると思います。
位置の調整とかサイズの調整とか面倒なんで、マクロでやることにしたんですが、その際発見したパワポに貼り付けた画像をスマートに変数に代入する方法をメモ。


要はエクセル上で「図としてコピー」した画像を、パワーポイントに貼り付けたステートメントでshapeオブジェクトへ代入したいんです。
パワポのPasteメソッドがShapeオブジェクトを返せば話は早いのですが、そうは簡単にはいきませんでした。

開発環境:officeは2013で64bitのwindows7です。

エクセルVBEの参照設定で「Microsoft PowerPoint 15.0 Object Library」にチェックを入れ、PowerPointをエクセルから操作します。

Sub PPTtest()

    Dim ppt As PowerPoint.Application
    Set ppt = New PowerPoint.Application

    Dim pst As Presentation

    'パワポファイルパスを適宜変更
    Set pst = ppt.Presentations.Open("C:\your\ppt\file.pptx")

    Dim pic As PowerPoint.Shape
    
    '以下でA1:G5の範囲を図としてコピー(用紙に合わせる)
    Range("A1:G5").CopyPicture appearance:=xlPrinter

    '以下で貼り付けた画像をshape型の変数に代入
    Set pic = pst.Slides(1).Shapes.Paste.PlaceholderFormat.Parent
    
    '以下は大きさや貼り付け位置などの調整(ご自由に)
    pic.Name = "エクセルの画像"
    pic.Top = 20
    pic.Left = 20
    pic.Width = 300

End Sub

PasteがShapeRangeを返すのをMicrosoft Officeのヘルプサイトで知って、「なんか直接変数に代入できそうだな」と思ってローカルウィンドウでPasteしたオブジェクトを丁寧に追っかけてみると、PlaceholderFormatのParentにありました。

ネットで検索しても「貼り付けたときにselectになっているのでselectionを使う」とか、「Pasteの後にShapes(1)などインデックス指定する」とかあったのですが、私のケースではこれらの方法を使いたくなかったので、上記の方法で問題なく取得できました。



_______________以下追記2015-03-24

後日再度shaperangeオブジェクトについて調べたところ、.item(index)を指定すると、shapeオブジェクトを返すことが分かりました。

つまり上記のpasteメソッドステートメントはこんな風にも書けます。

Set pic = pst.Slides(1).Shapes.Paste()(1)
'または
'Set pic = pst.Slides(1).Shapes.Paste.Item(1)

エクセルからpasteすると、pasteメソッドが返すshaperangeオブジェクトのcountは2になります。
そのため、複数のshapeオブジェクトを持つshaperangeオブジェクトだとtopやleftを操作することができません。
なので、itemのインデックスで1を指定して、shapeオブジェクトを取ってきます。


でもなぜ2つのitemを持っているのかは分かりませんでした。
2つとも同じshapeオブジェクトを指しているようでしたが、これはまた後日調べます。