.
  • Declaraciones y referencias
  • Métodos de trabajo
  • Acciones
  • Crear una presentación
  • Abrir una presentación
  • Añadir una diapositiva
  • Posicionarnos en una diapositiva
  • Recorrer las diapositivas
  • Shapes
  • Crear Shape genérico
  • Crear Shape específico
  • Propiedades Shape
  • Añadir imagen
  • Tablas
  • Creación tablas
  • Modificar alto de las filas
  • Modificar ancho de las columnas
  • Modificar propiedades de las celdas
  • Modificar una presentación existente
  • Recorrer los distintos Shapes de una diapositiva
  • Cambiar parte del texto de un TextFrame
  • Eliminar diapositivas
  • Guardar datos
  • Nota con las plantillas
  • Constantes
  • .

    ACCESS vs PowerPoint      26-sep-2020

    No es que sea habitual … pero puede ocurrir que haya que obtener datos en una presentación PowerPoint (nota: para no repetir mucho PowerPoint usaré Ppt en su lugar). La verdad es que para presentaciones de empresa se usan mucho, pero hasta ahora nunca me habían pedido obtenerlo desde Access.

    Pero no hay que asustarse, es una herramienta de la familia Office, lo cual significa que por automatización podemos hacer con ello lo que queramos, desde el mismo pptx usando ‘macros’ como si fuera Excel o en nuestro caso desde Access con VBA.

    Como ‘queja’ decir que Ppt no tiene una grabadora de macros como tiene Excel, que te ayude a encontrar el camino a recorrer. Dejó de estar operativa en la versión 2.003 de Office. Y por otro lado muchas de las acciones que se realizan no las ‘graba’ con lo que no es de mucha ayuda, por decirlo de una manera suave.



    Declaraciones y referencias

    Para poder desarrollar lo ‘más fácilmente’ posible, tener acceso a la ayuda de Ppt y que el Intellisense te ayude, lo mejor es referenciar la librería de PowerPoint correspondiente, referenciar los tipos de objeto a PowerPoint y abrir la automatización con:

         New PowerPoint.Application

    y una vez hecho el proceso, cambiar la definición de todos los objetos a Object, abrir la automatización con:

         CreateObject("PowerPoint.Application")

    y eliminar la referencia de Ppt.

    Decir que hago lo mismo cuando uso Excel, Word o Outllook.

    Otros compañeros tienen otras formas de atacar este problema, por ejemplo Access de Xavi



    Para desarrollo:

    Dim oPpt As PowerPoint.Application
    Dim Presentacion As PowerPoint.Presentation
    Dim Diapositiva As PowerPoint.Slide
    Dim Shape As PowerPoint.Shape
    Dim TextLoc As PowerPoint.TextRange

    Set oPpt = New PowerPoint.Application
    oPpt.Visible = True



    Para producción:

    Dim oPpt As Objet          ‘PowerPoint.Application
    Dim Presentacion As Object ‘PowerPoint.Presentation
    Dim Diapositiva As Object  ‘PowerPoint.Slide
    Dim Shape As Object        ‘PowerPoint.Shape
    Dim TextLoc As Object      ‘PowerPoint.TextRange

    Set oPpt = CreateObject("PowerPoint.Application")
    oPpt.Visible = True


    Nota: el Ppt hay que ponerlo visible si o si para poder trabajar con él, no vale lo de Excel o Word de mantenerlo oculto y sólo mostrarlo al terminar.



    Métodos de trabajo

    He realizado el trabajo de dos maneras distintas:

    - creando un Ppt desde ‘la nada’, añadiendo diapositivas, textos, tablas, etc

    - modificando un Ppt aportado por el cliente, dónde ya está diseñada la presentación, creados los textos, tablas, imágenes, … dónde sólo tenemos que incluir los datos necesarios

    Mejor la segunda, crear el diseño desde VBA no es difícil, pero si muy tedioso y ‘largo’. Además el Ppt es ‘lento’ a la hora de seguir las órdenes que se le dan, a mí por lo menos se me hace mucho más largo que obtener un Excel.


    Acciones Ya hemos visto las declaraciones de variables, la apertura de la app y hacerla visible, vamos con el detalle de las distintas acciones que podemos realizar con el Ppt:

    Crear una presentación:

         Set Presentacion = oPpt.Presentations.Add
         oPpt.ActiveWindow.ViewType = ppViewSlide


    Abrir una presentación ya existente:

         Set Presentacion = oPpt.Presentations.Open(RutaCompletaPowerPoint)


    Añadir una diapositiva:

         Set Diapositiva = Presentacion.Slides.Add(3, ppLayoutBlank)

        (*) siendo 3 la posición en la que queremos insertarla


    Posicionarnos en una diapositiva:

         Set Diapositiva = Presentacion.Slides(3)
         Diapositiva.Select

        (*) indispensable hacer el Select para las siguientes acciones a realizar en la misma, sino queremos estar referenciando todo incluyendo la diapositiva y el orden de la misma


    Recorrer las diapositivas de una presentación:

         For i = 1 to Presentacion.Slides.Count
             Set Diapositiva = Presentacion.Slides(i)
             Diapositiva.Select
             Debug.print Diapositiva.Name
         Next

       otro método:

         For Each Diapositiva In Presentacion.Slides
             Debug.print Diapositiva.Name
         Next


    Shapes. Formas. Todo en Ppt es una Shape (forma), un texto, una linea, un conector, una imagen, una tabla … así que lo que hay que hacer es crear una y con sus propiedades situarla, darla grosor, color, alineación, texto, asignarle imagen, …

    Crear Shape:

         Diapositiva.Shapes.Add (Tipo, Left, Top, Width, Heigh).Name = “Nombre”
         Diapositiva.Select

        (*) siendo Tipo (MsoAutoShapeType) el tipo de objeto que necesitemos, por ejemplo msoShapeRectangle = 1.


    También podemos crear directamente el Shape que necesitemos:

         Diapositiva.shapes.AddLine …
         Diapositiva.shapes.AddLabel …
         Diapositiva.shapes.AddPicture …
         Diapositiva.shapes.AddTable …
         Diapositiva.shapes.AddTextBox …
         Diapositiva.shapes.AddTittle …


    Una vez que lo tenemos creado es solo cuestión de personalizar las propiedades del Shape:

         With Diapositiva.Shapes(Nombre)
             .Fill.ForeColor.RGB = RellenoColor
             .Line.ForeColor.RGB = LineaColor
             With .TextFrame.TextRange
                 .ParagraphFormat.Alignment = Justificacion
                 .Text = Texto
                 .Font.Name = FontName
                 .Font.Color.RGB = FontColor
                 .Font.Size = FontSize
                 .Font.Bold = FontBold
                 .Font.Underline = FontUnderline
             End With
         End With


    En la opción de crearme un Ppt de la nada, con el fin de teclear lo menos posible, me creé un par de funciones para realizar este trabajo (no están nada optimizadas):

    Function PW_Shape(ByRef Diapo As Object, ByVal Nombre As String, ByVal Texto As String, _
         ByVal Left As Integer, ByVal Top As Integer, ByVal Width As Integer, _
         ByVal Height As Integer, Optional ByVal FontColor As Long = vbBlack, _
         Optional ByVal FontSize As Long = 12, Optional ByVal FontBold As Long = False, _
         Optional ByVal FontName As String = "Arial", Optional ByVal Justificacion = ppAlignLeft, _
         Optional ByVal RellenoColor = vbWhite, Optional ByVal LineaColor = vbWhite, _
         Optional ByVal FontUnderline As Long = False)

         Diapo.Shapes.AddShape(Type:=msoShapeRectangle, Left:=Left, Top:=Top, Width:=Width, _
             Height:=Height).Name = Nombre
         With Diapo.Shapes(Nombre)
             .Fill.ForeColor.RGB = RellenoColor
             .Line.ForeColor.RGB = LineaColor
             With .TextFrame.TextRange
                 .ParagraphFormat.Alignment = Justificacion
                 .Text = Texto
                 .Font.Name = FontName
                 .Font.Color.RGB = FontColor
                 .Font.Size = FontSize
                 .Font.Bold = FontBold
                 .Font.Underline = FontUnderline
             End With
         End With
    End Function

    Function PW_Linea(ByRef Diapo As Object, ByVal Nombre As String, ByVal BeginX As Integer, _
         ByVal BeginY As Integer, ByVal EndX As Integer, ByVal EndY As Integer, _
         Optional ByVal ColorLinea As Long = vbBlack, Optional ByVal GrosorLinea As Long = 1)

         Diapo.Shapes.AddLine(BeginX:=BeginX, BeginY:=BeginY, EndX:=EndX, EndY:=EndY).Name = Nombre
         Diapo.Shapes(Nombre).Line.ForeColor.RGB = ColorLinea
         Diapo.Shapes(Nombre).Line.Weight = GrosorLinea
    End Function


    Asi que para crear Shapes basta con:

         PW_Shape Diapositiva, "Tit1", "TITULO", 20, 30, 630, 20, 12632256, 28, True, , ppAlignRight
         PW_Shape Diapositiva, "Tit2", Format(Date, "mmmm \de yyyy"), 20, 68, 680, 10, 0, 10, False, _
             "Calibri", ppAlignRight
         PW_Linea Diapositiva, "Lin1", 20, 80, 695, 80, 13408512, 2
         PW_Shape Diapositiva, "Tit3", "Gestión social de la vivienda", 20, 85, 630, 20, 13408512, 16, False, _
             "Arial", ppAlignLeft
         PW_Shape Diapositiva, "Tit4", "Situación en España", 20, 105, 630, 20, 13408512, 12, False, _
             "Arial", ppAlignLeft


    Para añadir directamente una imagen:

         Diapositiva.Shapes.AddPicture (”C:\Temp\Imagen.jpg", True, True, 20, 50, 665, 450).Name = "Imagen"



    Tablas

    Uno de los objetos que más vamos a usar. No tiene mucho misterio su creación, una vez hecho el tratamiento es simple y la modificación de sus propiedades también, se hace sobre todo a través de los objetos TextFrame.TextRange que ya hemos visto anteriormente.


    Creación de una tabla:

         Diapositiva.Shapes.AddTable(NumRows:=19, NumColumns:=4, Left:=40, Top:=100, Width:=260, _
             Height:=100).Name = "Tabla1"

    Como veis, le decimos el número de filas y columnas que queremos que tenga. Distinto es modificar su formato, no nos deja hacer directamente un tamaño 'normal', en su lugar hay que crear la tabla y después reducir su tamaño modificando la escala de la misma, con esto logramos la altura de las filas. Una vez hecho esto, ya podemos modificar la anchura de las columnas.


    Modificar alto de las filas de una tabla:

         Diapositiva.Shapes(“Tabla1”).Table.ScaleProportionally (0.6)


    Modificar ancho de las columnas de una tabla:

         Diapositiva.Shapes(“Tabla1”).Table.Columns(1).Width = 140
         Diapositiva.Shapes(“Tabla1”).Table.Columns(2).Width = 60


    Modificar las propiedades de las celdas:

         With Diapositiva.Shapes(“Tabla1”).Table.Cell(Fila, Columna).Shape.TextFrame.TextRange
             .ParagraphFormat.Alignment = ppAlignCenter
             .Font.Name = “Calibri”
             .Font.Size = 10
             .Font.Italic = True
             .Font.Color.RGB = vbRed
             .Characters.Text = “Texto”
         End With

         Está claro que lo suyo es un bucle anidado fila / columna y mucho With para evitar grandes chorizos …. :-P

         A la hora de realizar los ajustes, hay que hacerlo con paciencia benedictina, modificando directamente la propiedad del Shape que estemos tratando, para ello ponemos un Stop justo después de haber creado el Shape y en la ventana inmediato ajustamos el valor que necesitemos:

         Diapositiva.Shapes("xxxx").Left = 360



    Modificar una presentación existente

    La segunda opción de trabajo, modificar un Ppt ya existente sólo cambiando los datos, es más simple de implementar (y mucho más rápida). Para poder trabajar cómodamente necesitaremos renombrar los objetos que tengamos que utilizar. Para ello recorreremos la colección de diapostivas (ya hemos visto como hacerlo) y en cada una de ellas analizaremos los Shapes existentes, modificando el "name" de aquellos que nos interese tratar.

    Para recorrer los distintos Shapes de una diapositiva yo he utilizado el siguiente bucle:

         For Each Shape In Diapositiva.Shapes
             Shape.Select
             Debug.Print Shape.Name
             Stop ' Shape.Name = "xxxxxx"
         Next

    que me muestra en el diseño de la diapositiva seleccionada el Shape seleccionado y en la ventana inmediato su nombre, en el caso de que vaya a tratarlo le pongo un nombre significativo con la instrucción:

         Shape.Name = "NuevoNombre"

    Una vez ‘personalizada’ la plantilla Ppt (y debidamente guardada) es cuando desde nuestro proceso Access accederemos a la misma y ‘actualizaremos’ los datos correspondientes:

         Set Diapositiva = Presentacion.Slides(1)
         Diapositiva.Select
         Diapositiva.Shapes("NombreEntidad").TextFrame.TextRange.Text = “NombreEntidad”
         Diapositiva.Shapes("FechaLarga").TextFrame.TextRange.Text = Format(Date, "mmmm \de yyyy")

    Para dar valores a una tabla usaremos el formato que ya vimos anteriormente:

         Diapositiva.Shapes(“Tabla1”).Table.Cell(fila, columna).Shape.TextFrame.TextRange.Characters.Text = "--"

    Un caso especial es cuando solo queramos cambiar parte del texto de un TextFrame.

    Por ejemplo, tenemos un Shape cuyo texto es:

         "La localidad de MARCA1 tiene MARCA2 habitantes.”

    Podríamos hacerlo todo por VBA (siendo Xs String):

         Xs = “La localidad de “ & Me.NombreLocalidad & “ tiene “ & Me.Habitantes & “ habitantes.”
         Diapositiva.Shapes("DatosLoc").TextFrame.TextRange.Text = Xs

    o:

         Xs = Diapositiva.Shapes("DatosLoc").TextFrame.TextRange.Text
         Xs = Replace(Xs, “MARCA1”, Me.NombreLocalidad)
         Xs = Replace(Xs, “MARCA2”, Me.Habitantes)
         Diapositiva.Shapes("DatosLoc").TextFrame.TextRange.Text = Xs

    Y obtendríamos:

         "La localidad de VillaRiba tiene 1.200 habitantes.”

    La pega que tiene cualquiera de estas dos formas de hacerlo, es que unifican el formato de todo el texto (al mismo tipo, tamaño, color, etc) y perdemos ‘riqueza’ en el mensaje puesto que puede estar el nombre de la localidad en negrita y fuente color rojo, una parte subrayada, etc.

    Para que esto no nos ocurra lo que tenemos que hacer es trabajar justo con la parte de la cadena a sustituir usando para ello un objeto TextRange.

    El ejemplo anterior quedaría así:

         Set TextLoc = Diapositiva.Shapes("DatosLoc ").TextFrame.TextRange.Find("MARCA1")
         TextLoc.Text = Me.NombreLocalidad
         Set TextLoc = Diapositiva.Shapes("DatosLoc ").TextFrame.TextRange.Find("MARCA2")
         TextLoc.Text = Me.Habitantes

    y el resultado que obtendríamos sería:

         "La localidad de VillaRiba tiene 1.200 habitantes.”

    Si necesitamos eliminar diapositivas de la presentación basta con:

         Presentacion.Slides(6).Delete
         Presentacion.Slides(5).Delete

       (*) a recordar que como en cualquier colección si tenemos que eliminar varias hay que hacerlo desde el final hacia
            el principio, si no queremos encontrarnos con sorpresas no deseadas.


    Para guardar datos :

         Presentacion.Save
         Presentacion.Quit      (si necesitamos cerrarla)


    Nota con las plantillas :

    - Con Ppt las plantillas no funcionan como en Word, que abres un dotx y crea un documento nuevo al que el usuario tiene que dar nombre.
    - En Ppt hay que duplicar la plantilla con el nombre que queramos usar (con FileSystem por ejemplo).
    - La plantilla de Pptx lo que hace es introducir un modelo de diapositiva en la presentación que tengamos abierta.


    Valores Constantes PPt :

    Al eliminar la referencia a la libreria Ppt necesitaremos tener definidos los valores de las constantes usadas. En mi caso han sido:

         '*** Constantes PowerPoint
         Global Const msoShapeRectangle = 1
         Global Const ppViewSlide = 1
         Global Const ppLayoutBlank = 12
         Global Const ppAlignLeft = 1
         Global Const ppAlignRight = 3
         Global Const ppAlignCenter = 2
         Global Const ppAlignJustify = 4
         Global Const ppAlignDistribute = 5
         Global Const ppAlignJustifylow = 7 ' justificar abajo
         Global Const msoAnchortop = 1      ' justificar vertical arriba
         Global Const msoAnchorMiddle = 3
         Global Const msoAnchorBottom = 4



    Tecsys Proyectos Informaticos, S.L.