Ya que las presentaciones de PowerPoint jamás pasarán de moda por temas de tradición y comodidad, nos vendría bien saber (o recordar, por si se nos había olvidado) cómo podemos mover un rango de Excel a una diapositiva sin tener que usar capturas de pantalla.
Y aunque pareciera que es más fácil hacer esto de manera manual, veremos que ya no lo es cuando tenemos una presentación con más de cincuenta imágenes de Excel, por lo que contar con un macro de VBA que se encargue del trabajo pesado nos hará la vida más fácil, pues hablamos de automatizar procesos tediosos y reducirlos a segundos.
Una de las ventajas de VBA es que podemos comandar otros programas a través de Excel, por lo que hoy vamos a ver cómo copiar un rango de celdas específico para poder pegarlo en una nueva presentación de PowerPoint.
El Código
Para empezar veremos el código de VBA y luego abordaremos algunas de sus secciones principales y más importantes para entender cómo es que funciona.
Sub ExcelRangeToPowerPoint() Dim rng As Range Dim PowerPointApp As Object Dim myPresentation As Object Dim mySlide As Object Dim myShape As Object 'Copy Range from Excel Set rng = ThisWorkbook.ActiveSheet.Range("A1:C12") 'Create an Instance of PowerPoint On Error Resume Next'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0 'Optimize Code Application.ScreenUpdating = False 'Create a New Presentation Set myPresentation = PowerPointApp.Presentations.Add 'Add a slide to the Presentation Set mySlide = myPresentation.Slides.Add(1, 11) '11 = ppLayoutTitleOnly 'Copy Excel Range rng.Copy 'Paste to PowerPoint and position mySlide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile Set myShape = mySlide.Shapes(mySlide.Shapes.Count)'Set position
myShape.Left = 66: myShape.Top = 152
'Make PowerPoint Visible and Active PowerPointApp.Visible = True PowerPointApp.Activate 'Clear The Clipboard Application.CutCopyMode = False End Sub
Para poder controlar PowerPoint desde el editor de Visual Basic en Excel primero necesitamos «enseñarle» a Excel cómo hablar en términos de PowerPoint dado que PowerPoint usa un vocabulario que contiene términos tales como «Diapositiva» y «Presentación» que no existen en el lenguaje propio de Excel. Si bien el código de arriba ya se encarga de activar la librería de objetos de PowerPoint, no estaría de más verificar.
Para saber si ya tenemos la librería de objetos de PowerPoint activada, tenemos que:
- Irnos al editor de Visual Basic y dar click en el menú de «Herramientas» y seleccionar «Referencia».
- Después nos aseguraremos que la referencia «Microsoft Office PowerPoint 16.0 Object Library» esté marcada (la versión que nos marque dependerá de la versión de Office que manejemos).
Cabe mencionar que aun con la librería de objetos de PowerPoint habilitada, Intellisense no funcionará por cada objeto de PowerPoint en el editor de Visual Basic. Esto no nos debería representar problema alguno a menos que tengamos que añadir código adicional para automatizar aun más PowerPoint con nuestro macro de VBA.
ABRIENDO POWERPOINT DESDE EXCEL
Ahora que nos hemos asegurado de que Excel se puede comunicar con PowerPoint, veamos cómo podemos pegar un rango en una nueva diapositiva. Si vemos casi al inicio de nuestro código veremos una sección que se ve algo así:
'Create an Instance of PowerPoint On Error Resume Next'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
En esta parte del código estamos determinando si PowerPoint está abierto o no. Si PowerPoint ya está abierto, podemos establecer una variable igual a todo el programa si usamos GetObject. Si por el contrario, PowerPoint no está abierto, podemos usar CreateObject para ejecutar una instancia de PowerPoint y entonces establecer una variable igual a esa instancia específica de PowerPoint.
Cuando usamos CreateObject, la aplicación que tenemos por objetivo empezará a ejecutarse pero no estará visible en pantalla, por lo que necesitamos habilitar el ajuste Visible para que esté activado (o sea, que esté como «true»). De igual forma, VBA con PowerPoint es un poco diferente con respecto a Excel ya que es mucho más dependiente de su ventana mostrándose en pantalla. Por lo tanto, vamos a necesitar escribir un segundo comando para Activar PowerPoint.
'Make PowerPoint Visible and Active PowerPointApp.Visible = True PowerPointApp.Activate
CONTROLANDO POWERPOINT DESDE EXCEL
Ahora que estamos cien por ciento seguros de que PowerPoint está siendo ejecutado, podemos empezar a controlarlo. Empezaremos por comandar PowerPoint para que cree una nueva presentación y luego cree una nueva diapositiva en donde pegará nuestro rango. Es importante establecer una variable durante cada paso de creación para cuando querramos referenciar la presentación o una nueva diapositiva, así podremos hacerlo con su variable respectiva.
'Create a New Presentation Set myPresentation = PowerPointApp.Presentations.Add 'Add a slide to the Presentation Set mySlide = myPresentation.Slides.Add(1, 11) '11 = ppLayoutTitleOnly
COPIANDO DE EXCEL A UNA DIAPOSITIVA
Ahora que tenemos una nueva presentación con una nueva diapositiva podemos comandar a Excel para que pegue nuestro rango en PowerPoint. Casi al inicio del código tenemos una línea que nos permite especificar el rango exacto que vamos a copiar. La variable rng fue usada para recordar este rango y permitirnos referenciarlo después en el código.
NOTA: Es buena idea colocar código que después debamos cambiar manualmente en algún punto futuro casi al inicio de la subrutina. Esto prevendrá que naveguemos nuestro código para encontrar el lugar exacto en donde tenemos el rango que vamos a copiar o qué hoja de cálculo es la que usaremos para extraer datos. Hacer esto nos salvará mucho tiempo y evitará confusiones.
'Copy Range from Excel Set rng = ThisWorkbook.ActiveSheet.Range("A1:D12") 'Copy Excel Range rng.Copy 'Paste to PowerPoint and position Set mySlide = myPresentation.Slides.Add(1, 11) '11 = ppLayoutTitleOnly Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
Aquí ya podemos usar PasteSpecial para determinar cómo queremos pegar nuestro rango específico. Típicamente es mejor pegar como Enhanced Metafile, pero aquí abajo tenemos los posibles tipos de pegado que podemos usar en su lugar según nos convenga.
Paste Type | Enum | VBA Code |
Bitmap | 1 | ppPasteBitmap |
Default | 0 | ppPasteDefault |
Enhanced Metafile | 2 | ppPasteEnhancedMetafile |
GIF | 4 | ppPasteGIF |
HTML | 8 | ppPasteGIF |
JPG | 5 | ppPasteJPG |
Metafile Picture | 3 | ppPasteMetafilePicture |
OLE Object | 10 | ppPasteOLEObject |
PNG | 6 | ppPastePNG |
RTF | 9 | ppPasteRTF |
Shape | 11 | ppPasteShape |
Text | 7 | ppPasteText |
Ajustando la posición de la imagen
Nótese cómo establecemos la variable igual al nuevo objeto que estamos pegando. Esto es importante ya que nos permite modificar la imágen luego de que ha sido colocada dentro de PowerPoint. En el código de ejemplo he elegido cambiar la posición de la imágen estableciendo las dimensiones Izquierda y Arriba. También podemos cambiar el tamaño de la imágen, añadir una sombra o aplicar alguna otra modificación que haríamos de manera manual ya en PowerPoint.
'Set position: myShapeRange.Left = 234 myShapeRange.Top = 186
Y con esto ya hemos llegado al fin del macro y hemos pegado de manera exitosa un rango de Excel dentro de una presentación de PowerPoint.
Cualquier duda nos leemos abajo.
Hola. ¿Alguna idea para copiar tabas de datos excel en power point en una diapositiva cuyo título sea «x»? Así la tabla excel se pegará en una diapositiva determina, independientemente de que sea la diapositiva nº1, la nº2 o la que sea. Me comentan que se puede hacer pero nadie comparte el código.
Hola Diego.
Como tal se me ocurre que puedes usar la propiedad TextRange de las Shapes.
Un ejemplo rápido sería como el de abajo, donde busco la etiqueta que diga adiós en una presentación, Espero te sirva:
Sub test()
Dim pptx As PowerPoint.Application
Dim presentation As PowerPoint.presentation
Dim layers As PowerPoint.Slides, layer As PowerPoint.Slide
Dim txBoxs As PowerPoint.Shapes, txBox As PowerPoint.Shape
Set pptx = CreateObject(«PowerPoint.Application»)
Set presentation = pptx.Presentations.Open(«C:\Users\SebastianVallejoJime\Desktop\Presentation2.pptx»)
Set layers = presentation.Slides
For Each layer In layers
Set txBoxs = layer.Shapes
For Each txBox In txBoxs
If txBox.TextFrame.TextRange.Text = «Adios» Then
Debug.Print «Aqui»
End If
Next
Next
End Sub
Creo que esta macro copia y pega los datos de excel en un power point, en la última diapositiva añadida. ¿Es así?¿Se puede indicar en el código que pegue los datos en un rango determinado del power point? Me explico. Tengo ya montado un power point y con una macro indico por ejemplo que en la diapositiva 5 debe ir la tabla de ventas y en la 6 la tabla de compras. Esto funciona correctamente. El problema viene en que a veces añado o elimino diapositivas y las ventas deben ir en otra diapositiva, por ejemplo la 7 y las compras en la 9. Esto me obliga a reajustar la macro indicándole en una tabla en que diapositiva debe pegar los datos. Lo ideal sería que pudiese en vez de indicarle el nº de diapositiva, el nombre del rango/zona del power point donde debe pegar los datos. De esta manera no tendría que reajustar la macro cada vez que añado/elimino diapositivas. ¿Se puede? ¿Podría solucionarlo de alguna manera?
Gracias.
Hola Diego!
La macro esta pensada para insertar una nueva diapositiva y pegar ahi los valores.
Según lo que me comentas no es posible una solución alterna de la que planteas, en la que en una tabla determinas en donde va cada cosa.
El principal problema es la parte programática, ya que recuerda que un punto fundamental para automatizar es la estandarización, si no hay estandarización el programa presentara estos problemas que comentas (el hecho de que puedan ser n diapositivas es no estandarizar).
Saludos!