🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA PowerPoint from Excel — Build Slides, Paste Charts, and Never Quit the User's Deck

|

VBA PowerPoint from Excel — Build Slides, Paste Charts, and Never Quit the User's Deck

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 .Quit only 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 .Quit dangerous, 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.Quit closes 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 = False raises 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