TL;DR — From Excel, PowerPoint is another program you drive through its object model:
Application > Presentations > Slides > Shapes. There are no cells. A slide is a canvas of shapes placed in points, so Excel prepares the numbers and charts and PowerPoint only places them. The trap is that PowerPoint runs one copy only:CreateObject("PowerPoint.Application")hands you the PowerPoint the user already has open, with their decks in it. Close only the presentation you created, and call.Quitonly if PowerPoint was not running before your macro started. Paste charts as pictures, retry the paste when the clipboard is slow, and build from a template instead of drawing layouts in code.
Sub ChartToNewSlide()
Dim ppt As Object, pres As Object, sld As Object
Set ppt = CreateObject("PowerPoint.Application") ' the running PowerPoint, if any
Set pres = ppt.Presentations.Add ' a new deck, in a window
Set sld = pres.Slides.Add(1, 11) ' 11 = ppLayoutTitleOnly
sld.Shapes.Title.TextFrame.TextRange.Text = "Q3 revenue"
ActiveSheet.ChartObjects(1).Chart.CopyPicture
sld.Shapes.PasteSpecial DataType:=2 ' 2 = ppPasteEnhancedMetafile
End Sub
This is the first of a three-part cluster on driving other Office apps from Excel. Here, PowerPoint: a deck of shapes. The Word guide covers a document, which is one long run of text. The References guide covers the link that tells VBA what the other program's words mean, and what happens when that link is missing on someone else's PC. One rule runs through all three: every object belongs to one application, so say which one.
What you'll learn
- The mental model: a deck is slides of shapes, measured in points, with no cells
- Why PowerPoint's single instance makes
.Quitdangerous, and the safe start and finish - How to add slides, write titles and use layout numbers without a reference
- How to paste a chart or a range as a picture, and why the paste sometimes fails
- How to place and size a pasted shape on the slide
- Why a template deck beats building layouts in code
The mental model: no cells, only shapes on a canvas
Excel thinks in a grid. PowerPoint does not have one. Its object model is a short chain:
| Object | What it is | Excel counterpart |
|---|---|---|
Application |
the PowerPoint program | Application |
Presentations / Presentation |
open decks / one deck | Workbooks / Workbook |
Slides / Slide |
the pages of a deck | Worksheets / Worksheet |
Shapes / Shape |
everything on a slide: titles, text boxes, pictures, charts | (no real counterpart) |
Text lives inside a shape: Shape.TextFrame.TextRange.Text. Position lives on the shape: .Left, .Top,
.Width, .Height, all in points (72 points per inch). The slide itself is
pres.PageSetup.SlideWidth by SlideHeight, which is 960 by 540 points for a standard 16:9 deck.
That is why the sensible split of work is: Excel calculates, PowerPoint places. Build the table or chart on a sheet, where you have formulas and formatting, then move a finished picture of it onto a slide. Trying to construct tables cell by cell inside PowerPoint is slow and fragile.
The trap: PowerPoint runs only one copy
Excel and Word can run several copies at once. PowerPoint cannot. When your macro calls
CreateObject("PowerPoint.Application"), Windows does not start a fresh, private PowerPoint, as the
CreateObject guide describes for most programs. It gives you the PowerPoint that is
already running, the one holding the user's half-finished presentation.
Two things follow:
ppt.Quitcloses everything. Every deck the user has open closes, and unsaved changes trigger save prompts, or are lost if your code has suppressed them.- You cannot hide it.
ppt.Visible = Falseraises a run-time error ending in Hiding the application window is not allowed. If you need to work out of sight, open or add the presentation without a window (WithWindow:=0) instead of hiding the program.
The safe pattern is to remember whether PowerPoint was already running, close only what you opened, and quit only what you started:
Sub BuildDeck()
Dim ppt As Object, pres As Object
Dim wasRunning As Boolean
On Error Resume Next
Set ppt = GetObject(, "PowerPoint.Application") ' is it already running?
On Error GoTo 0
wasRunning = Not ppt Is Nothing
If Not wasRunning Then Set ppt = CreateObject("PowerPoint.Application")
Set pres = ppt.Presentations.Add
' ... add slides and content here ...
pres.SaveAs ThisWorkbook.Path & "\Report.pptx"
pres.Close ' close OUR deck only
If Not wasRunning Then
If ppt.Presentations.Count = 0 Then ppt.Quit ' quit only what we started
End If
Set pres = Nothing
Set ppt = Nothing
End Sub
GetObject with an empty first argument attaches to a running copy and fails if there is none, which is
exactly the test you need. Releasing the variables with Set ... = Nothing at the end follows the
Nothing guide.
Adding slides and text without a reference
pres.Slides.Add(Index, Layout) inserts a slide at a position with one of PowerPoint's built-in layouts.
Without a reference to the PowerPoint library, the layout names such as ppLayoutTitleOnly mean nothing to
Excel's compiler, so you use their numbers. Declare them once as constants and the code stays readable:
Const ppLayoutTitle As Long = 1
Const ppLayoutTitleOnly As Long = 11
Const ppLayoutBlank As Long = 12
Const ppPasteEnhancedMetafile As Long = 2
Const ppPastePNG As Long = 6
Sub AddSlides(pres As Object)
Dim sld As Object
Set sld = pres.Slides.Add(pres.Slides.Count + 1, ppLayoutTitleOnly)
sld.Shapes.Title.TextFrame.TextRange.Text = "Sales by region"
Set sld = pres.Slides.Add(pres.Slides.Count + 1, ppLayoutBlank)
With sld.Shapes.AddTextbox(1, 40, 40, 600, 50) ' 1 = horizontal text
.TextFrame.TextRange.Text = "Notes for the board"
.TextFrame.TextRange.Font.Size = 24
End With
End Sub
pres.Slides.Count + 1 appends at the end. If you prefer IntelliSense and the real names, set a reference
to the PowerPoint object library, which the References guide explains along with the
cost of doing so when the file travels.
Pasting a chart or a range: picture, then retry
The reliable way to move Excel content to a slide is as a picture. A chart:
ws.ChartObjects("chtSales").Chart.CopyPicture ' a picture of the chart
Set shp = sld.Shapes.PasteSpecial(DataType:=ppPasteEnhancedMetafile)
A range, with its formatting exactly as it looks on the sheet:
ws.Range("A1:E12").CopyPicture Appearance:=1, Format:=-4147 ' xlScreen, xlPicture
Set shp = sld.Shapes.PasteSpecial(DataType:=ppPasteEnhancedMetafile)
An enhanced metafile stays sharp when the slide is resized. ppPastePNG gives a fixed-resolution image that
looks identical on every PC. Both are snapshots: they do not change when the workbook does, which is usually
what a report wants.
Now the failure everybody meets. The macro works nine times out of ten, then stops on the paste with an error saying the clipboard is empty or contains data which may not be pasted here. Nothing is wrong with the code. The copy is still being rendered onto the Windows clipboard when PowerPoint asks for it. The fix is to give it time and try again, not to add a fixed Wait everywhere:
Function PasteWithRetry(sld As Object, ByVal dataType As Long) As Object
Dim attempt As Long
For attempt = 1 To 5
On Error Resume Next
Set PasteWithRetry = sld.Shapes.PasteSpecial(DataType:=dataType)
If Err.Number = 0 Then
On Error GoTo 0
Exit Function
End If
On Error GoTo 0
DoEvents ' let the clipboard finish
Application.Wait Now + TimeSerial(0, 0, 1)
Next attempt
Err.Raise vbObjectError + 513, , "Paste into PowerPoint failed after 5 tries"
End Function
The DoEvents guide explains why yielding helps here. Copy, then call
PasteWithRetry, one item at a time; never copy five charts and then paste five times.
Placing the pasted shape
PasteSpecial returns the new shape (as a shape range), so you can position it at once. Use the slide size,
not fixed numbers, so the same code works on 4:3 and 16:9 decks:
Sub FitToSlide(pres As Object, shp As Object, ByVal topMargin As Single)
Dim maxW As Single, maxH As Single
maxW = pres.PageSetup.SlideWidth - 80
maxH = pres.PageSetup.SlideHeight - topMargin - 40
shp.LockAspectRatio = -1 ' msoTrue
shp.Width = maxW
If shp.Height > maxH Then shp.Height = maxH ' aspect ratio keeps width in step
shp.Left = (pres.PageSetup.SlideWidth - shp.Width) / 2
shp.Top = topMargin
End Sub
With the aspect ratio locked, changing the width also changes the height, so the picture never stretches. Centering is just the slide width minus the shape width, halved.
The judgment call: fill a template, do not draw slides in code
Every pixel you position in VBA is a pixel someone will ask you to move next month. My rule: the deck's
design belongs in a PowerPoint template, and the macro only fills it. Build one deck by hand with the
fonts, colours and logo right. Name the shapes the code must fill in the Selection Pane (Alt+F10), for
example txtTitle and picChart. Then the macro opens a copy and fills shapes by name:
Set pres = ppt.Presentations.Open(FileName:=ThisWorkbook.Path & "\Monthly.potx", _
ReadOnly:=-1, Untitled:=-1) ' an untitled copy
With pres.Slides(1)
.Shapes("txtTitle").TextFrame.TextRange.Text = "Sales - " & Format(Date, "mmmm yyyy")
.Shapes("txtTotal").TextFrame.TextRange.Text = Format(ws.Range("F2").Value, "#,##0")
End With
When marketing changes the brand colours, they edit the template, and the code does not change. The same logic says to paste pictures rather than linked charts: a link to the workbook breaks the moment the deck is emailed, and asks the recipient to update links they cannot reach. If the deck must stay live, keep the data in Excel and re-run the macro. If you only need a PDF, the Save as PDF guide may be all you need, without PowerPoint at all.
How ExcelMaster helps
PowerPoint automation fails in ways that are hard to see from the code: a paste that fails one run in ten, a macro that closes the user's other presentations, a layout that looks right only on the author's screen.
ExcelMaster lets you describe the deck you want, such as "one slide per region with its chart and the total in the title". It writes the macro with the safe start and finish, pastes with a retry, sizes shapes from the slide dimensions, and fills your own template instead of hard-coding a design.
Frequently asked questions
How do I open PowerPoint from Excel VBA?
Use CreateObject("PowerPoint.Application") and then Presentations.Add for a new deck or
Presentations.Open for an existing file. Because PowerPoint runs only one copy, check first with
GetObject(, "PowerPoint.Application") whether it was already running, so you know whether you may quit it
at the end.
How do I copy an Excel chart to PowerPoint with VBA?
Call Chart.CopyPicture on the chart, then Slide.Shapes.PasteSpecial with DataType:=2
(ppPasteEnhancedMetafile) or 6 (ppPastePNG). Paste right after each copy and retry the paste a few
times with DoEvents in between, because the clipboard is sometimes not ready.
Why does my VBA paste into PowerPoint fail randomly?
The copy has not finished reaching the Windows clipboard when PowerPoint tries to paste. Retry the paste in a
short loop with DoEvents and a one-second wait, and paste each item immediately after copying it.
Why does my macro close the user's other presentations?
PowerPoint is a single-instance program, so your macro shares it with every deck the user has open, and
Application.Quit closes all of them. Close only the presentation your code created, and quit only if
PowerPoint was not running when the macro started and no presentations remain.
Can I run PowerPoint invisibly from VBA?
Not by hiding the program: setting Visible to False raises an error. Instead, add or open the presentation
without a window, with WithWindow:=0, and the user's PowerPoint window stays as it was.
Tested in
Tested in: Excel 365 and PowerPoint 365 (Windows 11), VBA 7.1 — last verified 2026-10-02.
Related guides: VBA Word · VBA References · VBA CreateObject · VBA Outlook · VBA Chart · VBA Save as PDF · VBA DoEvents · VBA Nothing
