Excel の表やグラフを Excel VBA から PowerPoint へクリップボード経由で貼り付けるマクロを、Shapes.PasteSpecial の PpPasteDataType 13 種、書式保持貼付、リンク貼付の使い分けまで一通り解説します。
本記事は Excel VBA ホストの記事です。Excel 側に標準モジュールを置き、参照設定で Microsoft PowerPoint Object Library を有効化して動かします(PowerPoint VBA 側にコードを置く構成ではありません)。
検証範囲は Office 2024 永続版 Build 19929.20172(Windows 11 Pro 25H2)、検証日は 2026-05-18 です。PowerPoint 2019 / 2021 / Microsoft 365 や Mac / Web 版での挙動は本記事の対象外です。
サンプル配布(zip)
Excel VBA のマクロ入りブック、リンク元の Excel ファイル、貼り付け先 PowerPoint テンプレートを 1 つの ZIP にまとめています。展開後の .xlsm から記事の手順をそのまま試せます。
zip を展開すると、Excel マクロブック(powerpoint-vba-clipboard-image-paste-sample.xlsm)、リンク元データ(sample-data.xlsx)、貼り付け先テンプレート(sample-template.pptx)の 3 ファイルが入っています。.xlsm をダブルクリックで開き、「コンテンツの有効化」を押せば本文の Sub を F5 で実行できます。
マクロの完成コード(最短解)
Excel のグラフを PowerPoint の新規プレゼンに、書式を保持したまま貼り付ける最短コードです。PpPasteShape(値 11)で貼ると、ChartData.IsLinked = True のリンク付きグラフとして配置されます(リンク判定の話は h2-5 で詳述します)。
Option Explicit
' 参照設定: Microsoft PowerPoint Object Library
Public Sub PasteChartToPowerPoint()
' Excel のグラフを PowerPoint に書式保持で貼り付ける最短コード
' (ChartData.IsLinked = True のリンク付き Chart になる)
Dim pptApp As PowerPoint.Application
Dim pres As PowerPoint.Presentation
Dim slide As PowerPoint.Slide
Dim co As ChartObject
' 1) コピー元のグラフ(Sheet1 の最初のグラフ)
Set co = ThisWorkbook.Worksheets("Sheet1").ChartObjects(1)
' 2) PowerPoint を新規プロセスで起動
Set pptApp = New PowerPoint.Application
pptApp.Visible = msoTrue
' 3) プレゼン新規作成 + 空白スライド 1 枚追加
Set pres = pptApp.Presentations.Add
Set slide = pres.Slides.Add(1, ppLayoutBlank)
' 4) Excel グラフをコピー → PowerPoint に貼付
co.Copy
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteShape, Link:=msoFalse
' 5) ハンドル解放
Set slide = Nothing
Set pres = Nothing
Set pptApp = Nothing
Set co = Nothing
End Subこのコードを「VBE → 挿入 → 標準モジュール」で Module1 に貼り付け、F5 で実行すると、新しい PowerPoint ウィンドウが開いて 1 枚目のスライドに Excel のグラフが書式そのままで貼り付けられます。

目的別の経路選択早見表
「グラフを貼るか / 表を貼るか」「書式を保持するか / 図に焼き付けるか」「リンクを残すか / 切るか」で、選ぶ PpPasteDataType と引数が変わります。下の表は本文 H2 のうちどこを読めばよいかの索引も兼ねています。
| 貼りたい元 | 欲しい結果 | 使う DataType | 本文の該当節 |
|---|---|---|---|
| Excel グラフ | 書式保持・リンク付き | ppPasteShape (11) | h2-1 / h2-5 |
| Excel グラフ | 図として焼き付け | ppPasteEnhancedMetafile (2) / ppPasteBitmap (1) | h2-4 応用 1・2 |
| Excel 表 (Range) | 編集可能テーブル | ppPasteHTML (8) | h2-4 応用 3 |
| Excel 表 (Range) | OLE 埋め込み(独立コピー) | ppPasteOLEObject (10) + Link:=msoFalse | h2-4 応用 4 / h2-6 |
| Excel 表 (Range) | OLE リンク貼付(元 Excel と連動) | ppPasteOLEObject (10) + Link:=msoTrue | h2-6 |
図ファイルを直接配置したい(クリップボードを使わずスライドに静的に画像を置きたい)場合は Slide.Shapes.AddPicture の系統が向いています。クリップボード経由との使い分けは h2-7 で扱います。
マクロの実行手順
配布 ZIP を展開した .xlsm を使えば、本記事のすべてのマクロが手元で再現できます。初回実行時の手順を順に追います。
- ZIP を展開:エクスプローラーで右クリック → 「すべて展開」。展開先は
.xlsmとsample-data.xlsxが同じフォルダになるようにします(リンク貼付で参照されるため)。 - Mark of the Web を解除:インターネットからダウンロードした
.xlsmは既定でマクロがブロックされます。.xlsmを右クリック → 「プロパティ」 → 「全般」タブ下部の「セキュリティ:このファイルは他のコンピューターから取得したものです」の右にある 「許可する」にチェック → 「OK」。 - .xlsm を開く:黄色いセキュリティバーが出たら「コンテンツの有効化」を押します。
- VBE を開く:
Alt + F11。左ペインのVBAProject配下にModule1〜Module7が見えます。 - 参照設定を確認:VBE → 「ツール」 → 「参照設定」で 「Microsoft PowerPoint XX.X Object Library」(X は環境依存のバージョン番号)にチェックが入っていることを確認します。配布 .xlsm は事前にチェック済みですが、別環境にコピーした場合は再度有効化が必要です。

VBE 「ツール → 参照設定」 ダイアログ。「Microsoft PowerPoint 16.0 Object Library」にチェックが入った状態。 - 実行:
Module1のPasteChartToPowerPointにカーソルを置いてF5。新しい PowerPoint プロセスが起動し、空白プレゼンの 1 枚目にグラフが貼り付けられます。 - マクロダイアログから実行する場合:Excel 側で
Alt + F8→ 「PasteChartToPowerPoint」を選択 → 「実行」でも同じ結果になります。VBE を毎回開きたくない場合はこちらが便利です。
2 回目以降の実行では、すでに開いている PowerPoint プロセスにスライドを追加したいことが多いでしょう。Module2 に同梱した GetPowerPointApp ヘルパー(既存プロセスがあれば GetObject で取得、なければ New で起動)に置き換えれば、PowerPoint ウィンドウを毎回新しく増やさずに済みます。

F5 で PasteChartToPowerPoint を即実行できる。Mark of the Web(MoTW)でブロックされる場合:会社 PC ではグループポリシーで「許可する」操作自体が無効化されていることがあります。その場合は IT 管理者に問い合わせるか、信頼できるフォルダ(%USERPROFILE%\Documents 以下の「信頼できる場所」設定)に置き直す必要があります。手元で素早く解除したい場合は PowerShell で Unblock-File -Path .\powerpoint-vba-clipboard-image-paste-sample.xlsm も使えます。
コードの解説 — 主要 9 行の役割
h2-1 の完成コードのうち、Excel と PowerPoint をまたぐ COM 呼び出しの肝になっている 9 行を順に見ていきます。PpPasteDataType 列挙体の 13 値と、Excel コピー元(Range / Range.CopyPicture / Chart.Copy)の組み合わせ早見表もこの節に置きます。
| 行 | 役割 |
|---|---|
Set pptApp = New PowerPoint.Application | PowerPoint を新規プロセスで起動。早期バインディング(参照設定)前提なので New で型推論が効きます。 |
pptApp.Visible = msoTrue | PowerPoint ウィンドウを画面に表示。msoFalse も指定可能ですが PowerPoint の仕様で実質的にウィンドウは表示されるため、本記事では msoTrue 固定。 |
Set pres = pptApp.Presentations.Add | 空白プレゼンを新規作成。既存テンプレを使う場合は pptApp.Presentations.Open("...\sample-template.pptx") に置き換えます。 |
pres.Slides.Add(1, ppLayoutBlank) | 1 番目の位置に空白スライドを追加。ppLayoutBlank = 12(プレースホルダー無し)。 |
co.Copy | Excel 側で ChartObject をクリップボードへコピー。Chart.Copy ではなく ChartObject.Copy で十分です(前者は新規シートとして複製する別 API)。 |
DoEvents | クリップボードへの転送が非同期で完了するまでメッセージループを 1 回回します。VBA 単一プロセス内でコピー直後に貼付に進むと、稀にクリップボードがまだ準備できていないことがあるための保険です。 |
slide.Shapes.PasteSpecial DataType:=ppPasteShape, Link:=msoFalse | クリップボードの内容を PpPasteDataType で形式指定して貼付。ppPasteShape(値 11)は Excel グラフ専用で、PowerPoint 側で書式保持・データ編集可能な Chart として配置されます。 |
Link:=msoFalse | ppPasteShape 経由でも内部的に元 Excel への参照が保持され、Chart.ChartData.IsLinked = True になります。Link 引数自体は ppPasteOLEObject のときの埋め込み/リンク切替(h2-6 で詳述)で主に効きます。 |
Set ... = Nothing | Set ... = Nothing は COM 参照を解放する処理であり、PowerPoint ウィンドウや POWERPNT.EXE プロセスを閉じる処理ではありません。マクロ終了後に PowerPoint を自動で閉じたい場合は、保存要否を決めたうえで pres.Close / pptApp.Quit を明示的に呼ぶ必要があります(このコード例ではプレゼンを残す前提なので呼んでいません)。 |
PpPasteDataType 13 値 × Excel コピー元 3 種 早見表
本記事で扱う有効な PpPasteDataType は 13 値です。実機検証では ppPasteSVG の値特定のため値 12 と値 13 を試行したため、合計 42 ケース(14 値候補 × 3 ソース)を確認しています(検証ログ result_v1_v2.json / result_v4.json)。表の ✅ / ❌ は Slide.Shapes.PasteSpecial での実機受理結果です。
| 名前 | 値 | 説明 | Range.Copy | Range.CopyPicture | Chart.Copy |
|---|---|---|---|---|---|
ppPasteDefault | 0 | クリップボード既定 | ✅ | ✅ | ✅ |
ppPasteBitmap | 1 | ビットマップ | ✅ | ✅ | ✅ |
ppPasteEnhancedMetafile | 2 | EMF | ✅ | ✅ (xlPicture) | ✅ |
ppPasteMetafilePicture | 3 | WMF | ❌ HRESULT 例外 | ❌ HRESULT 例外 | ❌ HRESULT 例外 |
ppPasteGIF | 4 | GIF | ❌ | ❌ | ✅ |
ppPasteJPG | 5 | JPG | ❌ | ❌ | ✅ |
ppPastePNG | 6 | PNG | ❌ | ❌ | ✅ |
ppPasteText | 7 | テキスト | ❌ silent fail | ❌ | ❌ |
ppPasteHTML | 8 | HTML | ✅ 編集可能テーブル | ❌ | ❌ |
ppPasteRTF | 9 | RTF | ❌ silent fail | ❌ | ❌ |
ppPasteOLEObject | 10 | OLE | ✅ Link 引数で 7/10 切替 | ❌ | ✅ |
ppPasteShape | 11 | シェイプ | ❌ | ❌ | ✅ ChartData.IsLinked=True |
ppPasteSVG | 12 | SVG (msoGraphic) | ❌ | ❌ | ✅ |

コラム:Microsoft Learn の Shapes.PasteSpecial Remarks 表は不完全です。Learn の PpPasteDataType ページでは列挙体メンバーは列挙されていますが、値 12(ppPasteSVG)の数値は記載がありません。PowerPoint 2016 以降で実装された ppPasteSVG は、Excel VBA で「Microsoft PowerPoint Object Library」を参照設定すると ppPasteSVG = 12 として裸の定数で取得可能です。実機軽確認済み(PowerPoint Object Library の型情報から取得)。本文 h2-4 応用 5 では Const ppPasteSVGLocal As Long = 12 の安全コードも併記しています。
遅延バインディング版:参照設定を入れたくない場合は Set pptApp = CreateObject("PowerPoint.Application") でも起動できますが、ppPasteShape などの 定数が解決されないため、本文のコード例(早期バインディング前提)はそのままでは動きません。遅延バインディングを使う場合は数値リテラル(Link:=False, DataType:=11 など)に書き換える必要があります。
応用マクロ — PpPasteDataType 別の貼り分け
h2-1 の ppPasteShape(11)以外にも、目的に応じて 5 つの貼り分けパターンがあります。Module1 内に応用 1〜5 として並べておけば、用途別に呼び出すだけで切り替えられます。
応用 1: EMF で図として焼き付け(ppPasteEnhancedMetafile = 2)
「貼った後に編集する必要はないが、印刷品質を保ちたい」場合の定番。ベクター形式なので拡大しても劣化しません。Range のコピーでも Chart のコピーでも受理されます。
Public Sub PasteAsEMF()
Dim pptApp As PowerPoint.Application
Dim slide As PowerPoint.Slide
Set pptApp = New PowerPoint.Application
pptApp.Visible = msoTrue
Set slide = pptApp.Presentations.Add.Slides.Add(1, ppLayoutBlank)
ThisWorkbook.Worksheets("Sheet1").ChartObjects(1).Copy
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteEnhancedMetafile
End Sub貼付後の Shape.Type は msoPicture(値 13)になります。Chart として編集はできなくなりますが、PowerPoint の図形機能で回転やトリミング、フィルター適用がそのまま使える形式です。プレゼン PDF 出力時の印字品質も ppPasteBitmap より滑らかです。
応用 2: ラスター画像として貼付(ppPasteBitmap = 1)
「画面表示優先・サイズ小さめ」の用途向け。Range.CopyPicture と組み合わせるときは Appearance:=xlScreen, Format:=xlBitmap または xlBitmap のみを選びます(xlPrinter + xlBitmap は後述の silent fail に該当)。
Public Sub PasteAsBitmap()
Dim slide As PowerPoint.Slide
Set slide = New PowerPoint.Application _
.Presentations.Add.Slides.Add(1, ppLayoutBlank)
ThisWorkbook.Worksheets("Sheet1").Range("A1:C6").CopyPicture _
Appearance:=xlScreen, Format:=xlBitmap
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteBitmap
End SubRange.CopyPicture は Appearance(画面表示優先 / 印刷品質優先)と Format(ベクター / ラスター)の 2 軸でクリップボードに送る画像形式を切り替えます。本記事の V4 検証 56 ケースでは、xlScreen + xlPicture は ppPasteDefault / ppPasteEnhancedMetafile で、xlScreen + xlBitmap は ppPasteDefault / ppPasteBitmap で、xlPrinter + xlPicture は ppPasteEnhancedMetafile で貼付できます。一方、xlPrinter + xlBitmap のみクリップボードに有効な貼付データが乗らず全 DataType で silent fail しました。

xlPrinter + xlBitmap 列だけ全行で「失敗」(赤強調)。クリップボードに何も置かれない silent fail のため、後続の PasteSpecial が全て失敗する。Range.CopyPicture の罠:Appearance:=xlPrinter, Format:=xlBitmap はクリップボードに何も置きません。その後の PasteSpecial がすべて silent fail(HRESULT 例外も出ない)になるため、原因が掴みづらい不具合になります。本記事の V4 検証 56 ケースで全 14 種の PpPasteDataType が失敗することを確認しています。xlScreen + xlBitmap、xlScreen + xlPicture、xlPrinter + xlPicture の 3 通りは対応する DataType(前段落の組合せ参照)であれば貼付できます。
応用 3: 編集可能テーブルとして貼付(ppPasteHTML = 8、Range 限定)
Excel の表を PowerPoint でそのままセル編集できる Table として貼り付けるパターン。Range.Copy 経由のみ受理され、Chart.Copy や CopyPicture では使えません。
Public Sub PasteAsEditableTable()
Dim slide As PowerPoint.Slide
Set slide = New PowerPoint.Application _
.Presentations.Add.Slides.Add(1, ppLayoutBlank)
ThisWorkbook.Worksheets("Sheet1").Range("A1:C6").Copy
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteHTML
End Sub貼付後の Shape タイプは msoTable(PowerPoint のテーブル)で、セルをクリックして直接編集できます。Excel の関数や条件付き書式は保持されず、値とフォント・罫線・塗りつぶしだけが移ります。表をスライド上で軽く修正したい用途に向きます。
応用 4: OLE で埋め込み(ppPasteOLEObject = 10、Link:=msoFalse)
Excel の表を「埋め込み Excel オブジェクト」として貼付し、ダブルクリックで Excel 編集モードを呼び出せる形にします。元の Excel ファイルから完全に独立したコピーです(h2-6 で linked との対比を詳述)。
Public Sub PasteAsEmbeddedOLE()
Dim slide As PowerPoint.Slide
Set slide = New PowerPoint.Application _
.Presentations.Add.Slides.Add(1, ppLayoutBlank)
ThisWorkbook.Worksheets("Sheet1").Range("A1:C6").Copy
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteOLEObject, Link:=msoFalse
End Sub貼付後の Shape タイプは msoEmbeddedOLEObject(値 7)。スライド上でダブルクリックすると Excel 編集モードが起動し、その場で数式や書式を編集できます。元の .xlsm ファイルがなくても独立して動作するため、配布用プレゼンに向いた形式です。
応用 5: SVG として貼付(ppPasteSVG = 12、Chart.Copy 限定)
PowerPoint 2016 以降で実装されたベクター形式。Chart.Copy 経由のみ受理され、貼付後の Shape タイプは msoGraphic(SVG)になります。前述のとおり Microsoft Learn では値が記載されていないため、本番コードでは Const ppPasteSVGLocal As Long = 12 を併記して環境依存を回避します。
Public Sub PasteAsSVG()
' ppPasteSVG は Microsoft Learn の列挙体表に値の記載なし
' PowerPoint Object Library から 12 として取得可能だが、安全策として併記
Const ppPasteSVGLocal As Long = 12
Dim slide As PowerPoint.Slide
Set slide = New PowerPoint.Application _
.Presentations.Add.Slides.Add(1, ppLayoutBlank)
ThisWorkbook.Worksheets("Sheet1").ChartObjects(1).Copy
DoEvents
slide.Shapes.PasteSpecial DataType:=ppPasteSVGLocal ' = 12
End Sub貼付後の Shape.Type は msoGraphic。PowerPoint 2016 以降の SVG 機能で「グラフィックの種類変更」「色変更(テーマ色との同期)」が使えるようになります。ベクター形式のため拡大しても劣化せず、印刷品質と編集自由度の両立が必要なときに向きます。Chart.Copy 経由のみ受理で、Range.Copy や CopyPicture では HRESULT 例外になります。
ExecuteMso と PasteSpecial(11) — Chart 貼付 2 つの経路
Excel のグラフを書式保持で貼付する経路は、ppPasteShape 経由(h2-1 の方法)と、Office リボンの「貼り付け:元の書式を保持」コマンドを CommandBars.ExecuteMso で呼ぶ経路の 2 つがあります。両者とも貼付後の Shape は msoChart ですが、リンク状態が異なります。判定は Chart.ChartData.IsLinked を主軸に行います。
| 項目 | PasteSpecial(ppPasteShape) | ExecuteMso("PasteExcelChartSourceFormatting") |
|---|---|---|
| 呼び出し元 | VBA + Python COM 両対応 | VBA 内部のみ(外部 COM client では HRESULT 例外) |
| 貼付後 Shape タイプ | msoChart | msoChart |
Chart.ChartData.IsLinked | True(リンクあり) | False(独立コピー) |
| 元 Excel データ変更後の挙動 | LinkFormat.Update で反映可 | 連動しない |

Chart.ChartData.IsLinked。 True なら PasteSpecial 由来、False なら ExecuteMso 由来。本記事の V10-A 実機検証では、PasteSpecial(ppPasteShape) で貼付した Chart に対し、コピー元の Excel データを更新して上書き保存 → PowerPoint 側で Shape.LinkFormat.Update を呼んだ結果、SeriesCollection(1).Values が [1200, 850, 1400, 600, 450] から [9999, 8888, 1400, 600, 450] に変化したことを確認しています。

Shape.LinkFormat.Update で Chart の SeriesValues が新値に切り替わった。' リンク付きで貼付して、後でデータ更新を反映するパターン
Public Sub PasteShapeWithLink(ByVal pptSlide As PowerPoint.Slide, _
ByVal xlChart As Excel.ChartObject)
xlChart.Copy
DoEvents
pptSlide.Shapes.PasteSpecial DataType:=ppPasteShape, Link:=msoFalse
' リンク判定(msoChart かつ ChartData.IsLinked = True で「リンク付き Chart」)
Dim shp As PowerPoint.Shape
Set shp = pptSlide.Shapes(pptSlide.Shapes.Count)
If shp.HasChart Then
If shp.Chart.ChartData.IsLinked Then
' 後でリンク先 Excel を更新したら shp.LinkFormat.Update で反映できる
End If
End If
End Sub一方、ExecuteMso("PasteExcelChartSourceFormatting") は VBA 内部から呼ぶ前提のリボンコマンドです。Excel VBA から PowerPoint の CommandBars.ExecuteMso を呼ぶことも可能ですが、本記事の V6 検証 20 ケースでは、Python COM 経由では HRESULT 0x80020009 で全て失敗しました。VBA から呼ぶ場合のラッパーは Module4 に同梱しています。
Public Sub ExecuteMsoSourceFormatting(ByVal pptApp As PowerPoint.Application, _
ByVal xlChart As Excel.ChartObject)
xlChart.Copy
DoEvents
pptApp.CommandBars.ExecuteMso "PasteExcelChartSourceFormatting"
End Sub「リンクを残してデータ連動させたい」なら PasteSpecial(ppPasteShape)、「貼った瞬間の見た目で凍結したい」なら ExecuteMso という使い分けが定石です。判定は ChartData.IsLinked を主軸に、Shape.LinkFormat.SourceFullName は読むと例外を投げる場合があるため On Error Resume Next 必須です。
OLE オブジェクトの埋め込み vs リンク貼付
Excel の表を ppPasteOLEObject(値 10)で貼ると、Link 引数で Shape タイプが切り替わります。判定は Shape.Type を主軸にします(V9 検証 4 ケース、result_v8_v9.json)。
| Link 引数 | Shape タイプ | 値 | 元 Excel ファイル削除時 | 用途 |
|---|---|---|---|---|
msoFalse(既定) | msoEmbeddedOLEObject | 7 | PPT 側で独立して動作 | 「貼った瞬間で凍結、後で Excel が変わっても影響しない」 |
msoTrue | msoLinkedOLEObject | 10 | リンク切れ警告 | 「元 Excel と連動、開くたび最新値を反映」 |

Link 引数で Shape.Type が 7 (msoEmbeddedOLEObject) と 10 (msoLinkedOLEObject) に切り替わる。判定の主軸は Shape.Type。本記事の V10-B 実機検証では、PasteSpecial(10, Link:=msoTrue) で貼付した linked OLE に対し、リンク元 Excel の値を 9999 から 77777 に変更して上書き保存 → PowerPoint で Shape.LinkFormat.Update を実行した結果、Shape.Type が msoLinkedOLEObject(値 10)を保持したまま、LinkFormat.SourceFullName も sample-data.xlsx!Sheet1!R1C1:R6C3 を維持し、Slide.Export で出力した PNG のバイナリサイズが 2618 → 2603 へ変化(表示が更新された)を確認しています。
' 埋め込み(リンクなし、独立コピー)
Public Sub PasteOLEEmbedded(ByVal pptSlide As PowerPoint.Slide, _
ByVal xlRange As Excel.Range)
xlRange.Copy
DoEvents
pptSlide.Shapes.PasteSpecial DataType:=ppPasteOLEObject, Link:=msoFalse
End Sub' リンク貼付(コピー元のブックが保存済みである必要)
Public Sub PasteOLELinked(ByVal pptSlide As PowerPoint.Slide, _
ByVal xlRange As Excel.Range)
' リンク貼付は「コピー元の Range が属するブック」がリンク元になる
' そのブックがまだ保存されていない(Path が空)なら、リンク貼付できない
If xlRange.Worksheet.Parent.Path = "" Then
MsgBox "リンク貼付には、コピー元の Excel ブックを先に保存してください。", vbExclamation
Exit Sub
End If
xlRange.Copy
DoEvents
pptSlide.Shapes.PasteSpecial DataType:=ppPasteOLEObject, Link:=msoTrue
End Subヒント:Link:=msoTrue で OLE 貼り付けすると、リンク元は「コピーしたときの Range が入っていたブック」になります。配布 ZIP の sample-data.xlsx をリンク元にしたい場合は、マクロブック(.xlsm)自身のワークシートではなく、Workbooks.Open で開いた sample-data.xlsx のワークシートからコピーしてください。.xlsm 内の Range をコピーすると、リンク元が .xlsm 自身になってしまいます。
配布先環境でリンク元 Excel のパスが変わった(フォルダごと移動した等)場合の修復用に RelinkSampleData を Module7 に用意しています。ThisWorkbook.Path を起点に sample-data.xlsx を動的参照する設計です。
Public Sub RelinkSampleData(ByVal pptSlide As PowerPoint.Slide)
' 配布先で sample-data.xlsx へのリンクが切れた場合の修復用
Dim shp As PowerPoint.Shape
Dim sourcePath As String
sourcePath = ThisWorkbook.Path & "\sample-data.xlsx"
If Dir(sourcePath) = "" Then
MsgBox "sample-data.xlsx が見つかりません。" & vbCrLf & _
"ZIP を展開した同じフォルダに置いてください。" & vbCrLf & _
"想定パス: " & sourcePath, _
vbExclamation, "RelinkSampleData"
Exit Sub
End If
For Each shp In pptSlide.Shapes
If shp.Type = msoLinkedOLEObject Then
On Error Resume Next
shp.LinkFormat.SourceFullName = sourcePath & "!Sheet1!R1C1:R6C3"
On Error GoTo 0
End If
Next shp
End SubAddPicture との使い分け — クリップボード vs ファイル直接
本記事のクリップボード経由貼付(Shapes.PasteSpecial)に対し、Slide.Shapes.AddPicture はファイルパスから直接画像を配置する API です。読み込ませる画像が既に PNG/JPG ファイルとして存在するなら、AddPicture のほうがクリップボード状態に依存せず安定します。
| 軸 | クリップボード経由(PasteSpecial) | AddPicture |
|---|---|---|
| 入力 | Excel の Range / Chart / 任意の元 | ファイルパス(PNG/JPG/SVG など) |
| 書式保持 | ppPasteShape なら Chart として保持、編集可能 | 常に静的画像 |
| リンク | Link:=msoTrue で linked OLE / linked chart | LinkToFile:=msoTrue でファイルリンク可 |
| クリップボード依存 | あり(並列マクロや他アプリの操作で破綻可能性) | なし |
クリップボード経由が向くのは「Excel 側で動的に作成した Chart や Range を、その場で PowerPoint に渡したい」ケース。AddPicture 系で大量画像を一括配置するパターンは別記事「PowerPoint VBA で複数スライドに同じロゴ画像を一括配置するマクロ」を参照してください。
たとえば月次の売上ダッシュボードを毎月更新する用途では、Excel 側で当月分のグラフを再生成しつつ、PowerPoint テンプレに PasteSpecial(ppPasteShape) で書式保持貼付する組み合わせが定番です。一方、「事前に画像化した PNG/SVG を複数スライドに同じ位置で配置したい」用途では、ファイルからの読み込み回数とパス管理が重要になるため AddPicture が向きます。両 API は対立ではなく、入力種別(動的データか静的画像か)で住み分けるイメージです。
' AddPicture でファイルから直接配置するパターン(参考、本記事の主軸ではない)
Public Sub AddPictureFromFile(ByVal pptSlide As PowerPoint.Slide, _
ByVal filePath As String)
pptSlide.Shapes.AddPicture FileName:=filePath, _
LinkToFile:=msoFalse, _
SaveWithDocument:=msoTrue, _
Left:=72, Top:=72, _
Width:=480, Height:=300
End Subうまく動かないときの確認ポイント
本記事のマクロが期待通り動かないときの原因切り分けです。エラーメッセージ別の早見表 → タイミング罠 → MoTW 詳細 → DPI コラムの順に並べています(各症状は V1-V10 検証 375 ケースの結果に基づく)。
| 症状 | 原因 | 対処 |
|---|---|---|
| 「ユーザー定義型は定義されていません」 | 参照設定で Microsoft PowerPoint Object Library が無効 | VBE → ツール → 参照設定で有効化 |
PasteSpecial が HRESULT 0x80020009 | クリップボードに対応する形式がない(ppPasteHTML を Chart.Copy 後に呼ぶ等) | 早見表で受理組み合わせを確認 |
PasteSpecial が成功するが何も貼られない | Range.CopyPicture(xlPrinter, xlBitmap) の silent fail | xlScreen + xlBitmap または xlPicture に変更 |
LinkFormat.SourceFullName で例外 | 埋め込み OLE(リンクなし)に対する参照 | Shape.Type = msoLinkedOLEObject を先に判定、または On Error Resume Next でラップ |
VBA 単一プロセスでコピー直後の PasteSpecial が稀に失敗 | クリップボード転送の非同期完了待ち | DoEvents を Copy と PasteSpecial の間に挿入 |
| マクロが「Mark of the Web」でブロック | インターネット由来 .xlsm の既定ポリシー | プロパティ → 「許可する」、または PowerShell の Unblock-File |
VBA 単一プロセスでの非同期タイミング罠:Excel VBA から PowerPoint COM を呼んでクリップボードを共有する構造では、稀に Copy → PasteSpecial 間でクリップボードの転送が間に合わず、貼付が失敗することがあります。外部出典では「DoEvents を間に入れる」「短い Application.Wait を挿入する」が定番の回避策として知られています。本記事の検証(Python COM 経由 V3 = 250 ケース、result_v3_partial.json)では再現できませんでしたが、配布 .xlsm の Module5 TimingTrapDemo に「DoEvents なし版 vs あり版」を同梱しているので、手元の VBA 単一プロセスで再現確認できます。
Mark of the Web / マクロブロックの詳細:Microsoft は 2022 年以降、インターネット由来の Office ファイル(Zone.Identifier ADS に ZoneId=3 が付いているもの)に含まれる VBA マクロを既定でブロックする方向へ挙動を変更しています。ユーザー操作で解除する場合の手順は h2-2 の手順 2 を参照。会社環境ではグループポリシー「Office マクロの動作」が「ブロック」に固定されている場合があり、その場合は信頼できる場所への配置や Trust Center 設定での個別許可が必要です。

ZoneId=3) 付き .xlsm を開くと、Excel 上部に「保護ビュー — インターネットから入手したファイルは、ウイルスに感染している可能性があります」黄色バーと「編集を有効にする」ボタンが表示される。コラム:PowerPoint の DPI とスライド寸法:貼り付けた Chart や OLE Object のサイズは PowerPoint のスライド寸法に依存します。標準 16:9 スライド(960 × 540 pt)にフルサイズで貼った Chart が想定よりぼやけて見える場合は、スライド寸法と画像の DPI 設定(既定 96 dpi)の関係が原因のことが多いです。詳しくは別記事「PowerPoint VBA で画像をスライドからエクスポートする際の画質と DPI」を参照してください。
まとめ — 検証範囲と次の一歩
Excel VBA から PowerPoint へクリップボード経由で表・グラフを貼り付けるマクロを、PpPasteDataType 13 値、Excel コピー元 3 種、リンク判定(ChartData.IsLinked / Shape.Type)、リンク更新(LinkFormat.Update)まで一通り見てきました。
- 最短解:
ppPasteShape(値 11)でグラフを書式保持・リンク付きで貼付(h2-1) - 応用 5 種:EMF / Bitmap / HTML / OLE Embedded / SVG を
PpPasteDataTypeで切替(h2-4) - リンク判定の正本:Chart は
Chart.ChartData.IsLinked、OLE はShape.Type(h2-5 / h2-6) - リンク更新:linked chart / linked OLE とも
Shape.LinkFormat.Updateで元 Excel の変更を反映(V10 実機検証result_v10_link_update.json) - OLE リンク元の正本:「コピーした時の Range が属するブック」がリンク元(h2-6 ヒント、Codex 実機プローブ
v5_link_source_probe.json) - silent fail に注意:
Range.CopyPicture(xlPrinter, xlBitmap)はクリップボードに何も置かないため、後続貼付が全失敗(V4 検証 56 ケース、result_v4.json) - VBA で外部 COM を使えない API:
CommandBars.ExecuteMso("PasteExcelChartSourceFormatting")は Python COM 経由ではHRESULT 0x80020009で全失敗(V6 検証 20 ケース、result_v6.json)、VBA 内部からのみ動作
本記事のマクロは配布 ZIP の .xlsm をそのまま実行することで再現できます。Module1 の PasteChartToPowerPoint が最短解、Module4 の ExecuteMsoSourceFormatting が「貼った瞬間の見た目で凍結したい」場合の VBA ラッパー、Module6 の PasteShapeWithLink がリンク判定込みの実用パターン、Module7 の PasteOLEEmbedded / PasteOLELinked / RelinkSampleData / DemoOLELinkVariants が OLE 系の完全実装です。読者の用途に近い Module から手を入れて、業務マクロのベースにしてください。
本記事の検証範囲:Office 2024 永続版 Build 19929.20172、Windows 11 Pro 25H2、検証日 2026-05-18。PowerPoint 2019 / 2021 / Microsoft 365 や Mac / Web 版での PpPasteDataType 値配置・Link 引数挙動は本記事のスコープ外のため、参考程度に留めてください。
関連記事:PowerPoint VBA で全スライドのフォントを一括置換 / PowerPoint VBA でノート(発表者ノート)を一括削除 / Excel の表を Markdown 形式でクリップボードにコピーする VBA。