TL;DR — Desde Excel, PowerPoint es otro programa que manejas a través de su modelo de objetos:
Application > Presentations > Slides > Shapes. No hay celdas. Una diapositiva es un lienzo de formas colocadas en puntos, así que Excel prepara los números y los gráficos y PowerPoint solo los coloca. La trampa es que PowerPoint ejecuta una sola copia:CreateObject("PowerPoint.Application")te entrega el PowerPoint que el usuario ya tiene abierto, con sus presentaciones dentro. Cierra solo la presentación que creaste y llama a.Quitsolo si PowerPoint no se estaba ejecutando antes de que arrancara tu macro. Pega los gráficos como imágenes, reintenta el pegado cuando el portapapeles va lento y parte de una plantilla en lugar de dibujar diseños con código.
Sub ChartToNewSlide()
Dim ppt As Object, pres As Object, sld As Object
Set ppt = CreateObject("PowerPoint.Application") ' el PowerPoint en ejecucion, si lo hay
Set pres = ppt.Presentations.Add ' una presentacion nueva, con ventana
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
Este es el primero de una serie de tres artículos sobre cómo manejar otras apps de Office desde Excel. Aquí, PowerPoint: una presentación hecha de formas. La guía de Word trata el documento, que es una larga tira de texto. La guía de referencias trata el vínculo que le dice a VBA qué significan las palabras del otro programa, y qué pasa cuando ese vínculo falta en el PC de otra persona. Una regla recorre los tres: cada objeto pertenece a una aplicación, así que di a cuál.
Lo que aprenderás
- El modelo mental: una presentación son diapositivas llenas de formas, medidas en puntos, sin celdas
- Por qué la instancia única de PowerPoint hace peligroso
.Quit, y cómo arrancar y terminar con seguridad - Cómo añadir diapositivas, escribir títulos y usar números de diseño sin referencia
- Cómo pegar un gráfico o un rango como imagen, y por qué el pegado falla a veces
- Cómo colocar y dimensionar una forma pegada en la diapositiva
- Por qué una plantilla de presentación es mejor que construir diseños con código
El modelo mental: sin celdas, solo formas sobre un lienzo
Excel piensa en cuadrícula. PowerPoint no tiene cuadrícula. Su modelo de objetos es una cadena corta:
| Objeto | Qué es | Equivalente en Excel |
|---|---|---|
Application |
el programa PowerPoint | Application |
Presentations / Presentation |
presentaciones abiertas / una presentación | Workbooks / Workbook |
Slides / Slide |
las páginas de la presentación | Worksheets / Worksheet |
Shapes / Shape |
todo lo que hay en una diapositiva: títulos, cuadros de texto, imágenes, gráficos | (sin equivalente real) |
El texto vive dentro de una forma: Shape.TextFrame.TextRange.Text. La posición vive en la forma: .Left,
.Top, .Width, .Height, todo en puntos (72 puntos por pulgada). La diapositiva en sí mide
pres.PageSetup.SlideWidth por SlideHeight, que en una presentación estándar 16:9 son 960 por 540 puntos.
Por eso el reparto sensato del trabajo es: Excel calcula, PowerPoint coloca. Monta la tabla o el gráfico en una hoja, donde tienes fórmulas y formato, y luego lleva una imagen terminada a la diapositiva. Intentar construir tablas celda a celda dentro de PowerPoint es lento y frágil.
La trampa: PowerPoint solo ejecuta una copia
Excel y Word pueden ejecutar varias copias a la vez. PowerPoint no. Cuando tu macro llama a
CreateObject("PowerPoint.Application"), Windows no arranca un PowerPoint nuevo y privado, como describe la
guía de CreateObject para la mayoría de los programas. Te entrega el PowerPoint
que ya se está ejecutando, el que tiene abierta la presentación a medio terminar del usuario.
De ahí salen dos cosas:
ppt.Quitlo cierra todo. Se cierran todas las presentaciones que el usuario tenga abiertas, y los cambios sin guardar disparan avisos para guardar, o se pierden si tu código los ha suprimido.- No puedes ocultarlo.
ppt.Visible = Falselanza un error en tiempo de ejecución que termina en Hiding the application window is not allowed (no se permite ocultar la ventana de la aplicación). Si necesitas trabajar sin que se vea, abre o añade la presentación sin ventana (WithWindow:=0) en lugar de ocultar el programa.
El patrón seguro consiste en recordar si PowerPoint ya se estaba ejecutando, cerrar solo lo que abriste y salir solo de lo que arrancaste:
Sub BuildDeck()
Dim ppt As Object, pres As Object
Dim wasRunning As Boolean
On Error Resume Next
Set ppt = GetObject(, "PowerPoint.Application") ' ya se esta ejecutando?
On Error GoTo 0
wasRunning = Not ppt Is Nothing
If Not wasRunning Then Set ppt = CreateObject("PowerPoint.Application")
Set pres = ppt.Presentations.Add
' ... aqui se anaden diapositivas y contenido ...
pres.SaveAs ThisWorkbook.Path & "\Report.pptx"
pres.Close ' cierra solo NUESTRA presentacion
If Not wasRunning Then
If ppt.Presentations.Count = 0 Then ppt.Quit ' sale solo de lo que arrancamos
End If
Set pres = Nothing
Set ppt = Nothing
End Sub
GetObject con el primer argumento vacío se engancha a una copia en ejecución y falla si no hay ninguna, que
es justo la prueba que necesitas. Liberar las variables con Set ... = Nothing al final sigue la
guía de Nothing.
Añadir diapositivas y texto sin referencia
pres.Slides.Add(Index, Layout) inserta una diapositiva en una posición con uno de los diseños integrados de
PowerPoint. Sin una referencia a la biblioteca de PowerPoint, los nombres de diseño como ppLayoutTitleOnly
no significan nada para el compilador de Excel, así que usas sus números. Decláralos una vez como constantes y
el código sigue siendo legible:
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 = texto horizontal
.TextFrame.TextRange.Text = "Notes for the board"
.TextFrame.TextRange.Font.Size = 24
End With
End Sub
pres.Slides.Count + 1 añade al final. Si prefieres IntelliSense y los nombres reales, marca una referencia a
la biblioteca de objetos de PowerPoint; la guía de referencias lo explica, junto
con lo que cuesta hacerlo cuando el archivo viaja a otros equipos.
Pegar un gráfico o un rango: como imagen, y con reintento
La forma fiable de llevar contenido de Excel a una diapositiva es como imagen. Un gráfico:
ws.ChartObjects("chtSales").Chart.CopyPicture ' una imagen del grafico
Set shp = sld.Shapes.PasteSpecial(DataType:=ppPasteEnhancedMetafile)
Un rango, con su formato tal y como se ve en la hoja:
ws.Range("A1:E12").CopyPicture Appearance:=1, Format:=-4147 ' xlScreen, xlPicture
Set shp = sld.Shapes.PasteSpecial(DataType:=ppPasteEnhancedMetafile)
Un metarchivo mejorado se mantiene nítido cuando se redimensiona la diapositiva. ppPastePNG da una imagen de
resolución fija que se ve idéntica en cualquier PC. Las dos son instantáneas: no cambian cuando cambia el
libro, que es lo que suele querer un informe.
Ahora el fallo con el que se topa todo el mundo. La macro funciona nueve de cada diez veces y de repente se para en el pegado con un error que dice que el portapapeles está vacío o que contiene datos que no se pueden pegar aquí. El código no tiene nada mal. La copia todavía se está volcando al portapapeles de Windows cuando PowerPoint la pide. La solución es darle tiempo y volver a intentarlo, no sembrar un Wait fijo por todas partes:
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 ' deja que el portapapeles termine
Application.Wait Now + TimeSerial(0, 0, 1)
Next attempt
Err.Raise vbObjectError + 513, , "Paste into PowerPoint failed after 5 tries"
End Function
La guía de DoEvents explica por qué ceder el control ayuda aquí. Copia y luego llama
a PasteWithRetry, un elemento cada vez; nunca copies cinco gráficos para luego pegar cinco veces.
Colocar la forma pegada
PasteSpecial devuelve la forma nueva (como un rango de formas), así que puedes colocarla en el acto. Usa el
tamaño de la diapositiva, no números fijos, para que el mismo código funcione en presentaciones 4:3 y 16:9:
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 ' la proporcion mantiene el ancho a la par
shp.Left = (pres.PageSetup.SlideWidth - shp.Width) / 2
shp.Top = topMargin
End Sub
Con la proporción bloqueada, cambiar el ancho cambia también el alto, así que la imagen nunca se deforma. Centrarla es simplemente el ancho de la diapositiva menos el ancho de la forma, dividido entre dos.
La decisión de criterio: rellena una plantilla, no dibujes diapositivas con código
Cada píxel que colocas con VBA es un píxel que alguien te pedirá mover el mes que viene. Mi regla: el diseño
de la presentación pertenece a una plantilla de PowerPoint, y la macro solo la rellena. Monta una
presentación a mano con las fuentes, los colores y el logotipo bien puestos. Pon nombre a las formas que el
código debe rellenar en el Panel de selección (Selection Pane, Alt+F10), por ejemplo txtTitle y
picChart. Después la macro abre una copia y rellena las formas por su nombre:
Set pres = ppt.Presentations.Open(FileName:=ThisWorkbook.Path & "\Monthly.potx", _
ReadOnly:=-1, Untitled:=-1) ' una copia sin titulo
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
Cuando marketing cambia los colores de marca, edita la plantilla y el código no cambia. La misma lógica dice que pegues imágenes en lugar de gráficos vinculados: un vínculo al libro se rompe en cuanto la presentación se envía por correo, y le pide al destinatario actualizar vínculos a los que no puede llegar. Si la presentación tiene que mantenerse viva, deja los datos en Excel y vuelve a ejecutar la macro. Si solo necesitas un PDF, puede que la guía de guardar como PDF sea todo lo que te hace falta, sin PowerPoint de por medio.
Cómo ayuda ExcelMaster
La automatización de PowerPoint falla de maneras difíciles de ver en el código: un pegado que falla una de cada diez ejecuciones, una macro que cierra las demás presentaciones del usuario, un diseño que solo se ve bien en la pantalla de quien lo hizo.
ExcelMaster te deja describir la presentación que quieres, por ejemplo «una diapositiva por región con su gráfico y el total en el título». Escribe la macro con el arranque y el cierre seguros, pega con reintento, dimensiona las formas a partir del tamaño de la diapositiva y rellena tu propia plantilla en lugar de codificar un diseño a fuego.
Preguntas frecuentes
¿Cómo abro PowerPoint desde Excel VBA?
Usa CreateObject("PowerPoint.Application") y después Presentations.Add para una presentación nueva o
Presentations.Open para un archivo existente. Como PowerPoint solo ejecuta una copia, comprueba antes con
GetObject(, "PowerPoint.Application") si ya se estaba ejecutando, para saber si puedes cerrarlo al final.
¿Cómo copio un gráfico de Excel a PowerPoint con VBA?
Llama a Chart.CopyPicture sobre el gráfico y luego a Slide.Shapes.PasteSpecial con DataType:=2
(ppPasteEnhancedMetafile) o 6 (ppPastePNG). Pega justo después de cada copia y reintenta el pegado
unas cuantas veces con DoEvents entre medias, porque a veces el portapapeles no está listo.
¿Por qué mi pegado en PowerPoint con VBA falla al azar?
La copia todavía no ha terminado de llegar al portapapeles de Windows cuando PowerPoint intenta pegarla.
Reintenta el pegado en un bucle corto con DoEvents y una espera de un segundo, y pega cada elemento
inmediatamente después de copiarlo.
¿Por qué mi macro cierra las demás presentaciones del usuario?
PowerPoint es un programa de instancia única, así que tu macro lo comparte con todas las presentaciones que
el usuario tenga abiertas, y Application.Quit las cierra todas. Cierra solo la presentación que creó tu
código, y sal de PowerPoint solo si no se estaba ejecutando cuando arrancó la macro y no queda ninguna
presentación abierta.
¿Puedo ejecutar PowerPoint de forma invisible desde VBA?
No ocultando el programa: poner Visible a False lanza un error. En su lugar, añade o abre la presentación
sin ventana, con WithWindow:=0, y la ventana de PowerPoint del usuario se queda como estaba.
Probado en
Probado en: Excel 365 y PowerPoint 365 (Windows 11), VBA 7.1 — última verificación el 02/10/2026.
Guías relacionadas: VBA Word · VBA References · VBA CreateObject · VBA Outlook · VBA Chart · VBA Save as PDF · VBA DoEvents · VBA Nothing
