0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ExcelVBAを使ってグラフや図表をPowerPointにペーストする

Posted at

筆者の職場のリーダーさんからの依頼で、彼らが日々Excelで作成している図表やグラフをマクロでPowerPointに貼り付け⇒報告書作成の手間を軽減してほしいとのこと。
例によって、ネット情報をもとにいろいろ試行錯誤して得られたTipsなどを記します。

実際にはOracleや外部ファイルからAccessにデータ引き込んで加工・集計し、それをExcelで取り込んで・・・という仰々しい?仕組みの一環なんですが、分かりやすさと守秘義務の関係で簡潔な内容に編集しております


1. 下準備

1) 表のテーブル化&名前付け

Excelでは、Accessのテーブルなど外部データの内容をワークシートに展開すると、おのずと表はテーブルとして定義されます。
ただ、それ以外に作成した表についても、あらかじめテーブル形式に変換しておくとデザイン的にも統一感があるし、何より後々扱いが楽です。
image.png

2) グラフへの名前付け

こちらも後々扱いが楽になるよう、グラフにも名前を定義しておきます。
こちらは、グラフエリアを選択した状態で画面左上の欄に名前を指定すればOKです。
image.png

3) PowerPointを参照設定

ExcelのVisual Basic Editorの参照設定で
"Microsoft PowerPoint xx.xx Object Library"
にチェックを入れます。

・Excel-PowerPoint間のAPIがないそうで、下記コーディング例の通り、ひたすらコピー&ペースト・・・という泥臭い処理内容になっております・・・
・ExcelからPowerPointに図表を貼り付ける処理自体がかなり重いので、ここではアーリーバインディングを使います。


2. 実際の処理

ここでは、あらかじめ用意しておいたPowerPointのひな形ファイルの所定の位置に、Excelの表やグラフをコピー⇒貼り付けして別名保存する例です。

1) 初期設定

    ' ひな形のPowerPointファイルを指定するダイアログを表示
    Dim スライドパス As String
    スライドパス = Application.GetSaveAsFilename( _
        InitialFileName:=CurDir(), _
        filefilter:="PowerPointスライドファイル (*.pptx), *pptx", _
        Title:="ひな形スライドファイルを選択してください", _
        buttontext:="指定")
    If スライドパス = "False" Then Exit Sub
    
    ' PowerPoint関連のオブジェクト定義-pPtが上記で指定したPowerPointファイルを指す
    Dim pAp As New PowerPoint.Application
    Dim pPt As Presentation
    Dim pSl As Slide
    Dim pSp As PowerPoint.Shape
    Set pPt = pAp.Presentations.Open(スライドパス)
    
    ' ExcelVBAを実行する際のお約束
    Application.Visible = True
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual

2) よくあるパターンの処理

グラフや図表貼り付けの具体例です。

    ' スライド1枚目に対する処理    Set pSl = pPt.Slides(1)
    ' PowerPointのテキストラベル(「作成年月日」で名前定義済)の内容更新
    qSl.Shapes("作成年月日").TextFlame.TextRange.Text = Format$(Date, "yyyy年mm月dd日")
    
    ' スライド3枚目に対する処理
    Set pSl = pPt.Slides(3)
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("作業_グラフ")
    
    ' Excel「作業_グラフ」シート上のグラフ「作業_月別対応件数_グラフ」をコピー、ひな形の所定の位置に貼り付け
    ws.ChartObjects("作業_月別対応件数_グラフ").Chart.CopyPicture xlScreen, xlPicture
    pSl.Shapes.Paste
    Set pSp = pSl.Shapes(pSl.Shapes.Count)
    With pSp                            ' 以下、Top/Left/Widthの値はcm/0.035(pt)の値を指定
        .Top = 48.57                    ' 縦位置
        .Left = 7.43                    ' 横位置
        .LockAspectRatio = msoTrue      ' 縦横比を固定
        .Width = 714.29                 ' 幅
    End With
    
    ' 固定票(レイアウトが固定)「作業_月別対応件数_表」をコピー⇒貼り付け
    ws.Range("作業_月別対応件数_表").Copy
    pSl.Shapes.PasteSpecial DataType:=PoPasteEnhanceMetafile, Link:=msoFalse
    Set pSp = pSl.Shapes(pSl.Shapes.Count)
    With pSp
        .Top = 409.43
        .Left = 0
        .LockAspectRatio = msoTrue
        .Width = 714.29
    End With
    
    Set pSl = pPt.Slides(4)
    Set ws = ThisWorkbook.Worksheets("作業内容_詳細")
    ' 可変表(データによって行数が変わる)「作業_時間外案件_表」をコピー⇒貼り付け
    ' ("CurrentRegion.Copy"で、定義済テーブルを丸ごとコピーしています)
    ws.Range("作業_時間外案件_表").CurrentRegion.Copy
    pSl.Shapes.PasteSpecial DataType:=ppPasteEnhancedMetafile, Link:=msoFalse
    Set pSp = pSl.Shapes(pSl.Shapes.Count)
    With pSp
        .Top = 124.86
        .Left = 0
        .LockAspectRatio = msoTrue
        .Width = 714.29
    End With
    
    Application.CutCopyMode = False
    
    ' コピー先PowerPointファイルに名前を付けて保存
    pPt.SaveAs CurDir & "\月次報告書_" & Format$(Now(), "yyyymmd") & ".pptx"
    pAp.Quit
    Set pSl = Nothing
    Set pPt = Nothing
    Set pAp = Nothing
    
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.Calculation = xlCalculationAutomatic
    MsgBox "月次報告書への図表の貼り付けが完了しました", vbInformation + vbOKOnly, "お知らせ"

3) ちょっと凝った制御

例えばデータによって行数が変わる可変表のとき、データがない場合は該当の表をコピーせずにその旨メッセージ表示する・・・などの制御が必要になる場合があります。

①まず、該当表の行の増減に影響のないセルに、次のようにCOUNTA関数を埋め込みます。
 表の中で必ずデータが入るカラムを対象にカウントし、このセルにも名前を付けます。
image.png
②VBAでは、まず①で定義した表の件数を参照して、行があった時は表をコピーします。 行がなかったときは、その旨を記したテキストラベルを新規に作成します。

    If Not IsEmpty(ws.Range("作業_時間外件数")) And _
       IsNumeric(ws.Range("作業_時間外件数").Value) And _
       ws.Range("作業_時間外件数").Value > 0 Then
        ' 可変表をコピー
        ws.Range("作業_時間外件数_表").CurrentRegion.Copy
        pSl.ShapesPasteSpecial DataType:=ppPasteDefault, Link:=msoFalse
        Set pSp = pSl.Shapes(pSl.Shapes.Count)
        With pSp
            .Top = 87.43
            .Left = 0
            .LockAspectRatio = msoTrue
            .Width = 714.29
        End With
    Else
        ' テキストラベルを追加する
        With pSl.Shapes.AddTextbox(OrientationHorizontal, Left:=285.71, Top:=138, Width:=600, Height:=200)
            .TextFrame.TextRange.Text = "該当案件なし"
            .TextFrame.TextRange.Font.Size = 20
        End With
    End If
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?