Mostrando las entradas con la etiqueta Excel a Word. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Excel a Word. Mostrar todas las entradas

domingo, 21 de junio de 2020

Interactuando con Microsoft Word (II): Enviar datos de Excel a Word (VBA) y darles formato.

Hace varias semanas le comenté sobre cómo comenzar a interactuar entre Excel y Word usando VBA. (Enlace). En aquella ocasión sobre todo nos centramos en enviar tablas hacia Word en diversos formatos. En esta ocasión iremos un poco más allá y enviaremos datos y modificaremos su formato en el archivo de Word creado, entonces ¡Manos a la obra!

Para el ejemplo vamos a usar una cosa muy simple de datos en Excel, así:

Ahora, lo primero, como ya saben, será activar las referencias a “Microsoft Word 16.0 Object Library”, hecho eso corresponde declarar nuestras variables, en donde la primera será la de nuestro objeto Word.

Dim MiappWord As Word.Application

Ahora vamos a crear el objeto Word y un documento nuevo en blanco.

Set MiappWord = CreateObject("Word.Application") 
MiappWord.Documents.Add 
Como ya está creado nuestro objeto y ya tenemos un archivo nuevo en él, así no lo veamos, copiaremos nuestros datos de Excel.
Hoja1.Range("A1:C11").Copy

A partir de aquí empezaremos a usar el objeto Word por lo que usaremos la instrucción With para ahorrarnos algunas líneas de código.

With MiappWord 

Luego pegaremos nuestros datos en Word pero manteniendo el formato de origen.

  .Selection.PasteExcelTable False, False, False

Como es un archivo nuevo, la tabla pegada tendrá el índice 1, por lo que para referirnos a ella usaremos dicho índice como tabla dentro del documento activo (ActiveDocument) de Word y por ende, para seguir facilitándonos escribir un poco menos, usaremos otro With, ya que los formatos a aplicar estarán dentro de celdas de dicha tabla.

With .ActiveDocument.Tables(1)

Como en la tabla tenemos objetos Cell, lo que haremos es cambiar las propiedades respectivas de cada uno de los objetos que requerimos. Voy a dejar las líneas en VBA comentadas para que se sepa qué hace cada una.

         'Fuente de color rojo
         .Cell(2, 3).Range.Font.ColorIndex = wdRed
         'Fondo de color verde obtenido con constante de Word
         .Cell(3, 3).Shading.BackgroundPatternColor = wdColorGreen
         'Fondo de color verde gris obtenido con RGB
         .Cell(4, 3).Shading.BackgroundPatternColor = RGB(184, 183, 153)
         'Fuente en negrita
         .Cell(5, 3).Range.Font.Bold = wdToggle
         'Fuente en cursiva
         .Cell(6, 3).Range.Font.Italic = wdToggle
         'Fondo en rojo para toda una fila
         .Rows(7).Shading.BackgroundPatternColor = wdColorRed
         'Escribir hola en una celda
         .Cell(Row:=8, Column:=3).Range = "Hola"
 End With 

Para seguir aprendiendo sobre este tema, también vamos a ver cómo hacer cambios a varias celdas de la tabla que son contiguas, pero están en distintas filas y columnas.  Lo primero es definir dicho rango de celdas. En este caso iniciaremos en la fila 9, columna 1 y terminaremos en la fila 11, columna 3.

With .ActiveDocument
    Set mirango = .Range(Start:=.Tables(1).Cell(9, 1).Range.Start, End:=.Tables(1).Cell(11, 3).Range.End)
End With 

Para que no se mareen con los With, tranquilos/as, al final veremos todo junto. Volviendo a lo anterior, ya definido el rango, a través de un For-Each vamos a colocar la misma palabra en dichas celdas.

For Each miCelda In mirango.Cells
     miCelda.Range = "Repetir"
Next miCelda  

Quizás si tenemos todo junto nos sea más fácil entenderlo:

Option Explicit
'Todo Sobre Excel 
'Abraham Valencia 
'https://abrahamexcel.blogspot.com/ 
'Lima, Perú 
'Junio del 2020 

EnviardatosaWord() 

Dim MiappWord As Word.Application 
Dim mirango As Word.Range, miCelda As Word.Cell 

Set MiappWord = CreateObject("Word.Application") 
MiappWord.Documents.Add Hoja1.Range("A1:C11").Copy 

With MiappWord

          .Selection.PasteExcelTable False, False, False

          With .ActiveDocument.Tables(1)
              'Fuente de color rojo
              .Cell(2, 3).Range.Font.ColorIndex = wdRed
	            'Fondo en verde con constante de Word         
              .Cell(3, 3).Shading.BackgroundPatternColor = wdColorGreen
              'Fondo en verde gris con función RGB         
              .Cell(4, 3).Shading.BackgroundPatternColor = RGB(184, 183, 153)
              'Fuente en formato negrita
              .Cell(5, 3).Range.Font.Bold = wdToggle
              'Fuente en formato cursiva
              .Cell(6, 3).Range.Font.Italic = wdToggle
              'Fondo de color rojo para toda una fila
              .Rows(7).Shading.BackgroundPatternColor = wdColorRed
              'Escibir hola en una celda
              .Cell(Row:=8, Column:=3).Range = "Hola"
           End With

           With .ActiveDocument
               Set mirango = .Range(Start:=.Tables(1).Cell(9, 1).Range.Start, End:=.Tables(1).Cell(11, 3).Range.End)
           End With

          .Visible = True 
End With 

'Escribir la palabra Repetir en todas las celdas del rango elegido
For Each miCelda In mirango.Cells
     miCelda.Range = "Repetir" 
Next miCelda 

Application.CutCopyMode = False 
Set MiappWord = Nothing 

End Sub  

Si todo salió bien, en su Word deben tener algo como esto:

Y eso es todo en esta ocasión, espero que hayan aprendido un poco más sobre interactuar con Word desde Excel. Hasta la próxima.

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí

 

lunes, 7 de octubre de 2019

Interactuando con Microsoft Word (I): Enviar datos de Excel a Word (VBA)

En innumerables ocasiones he visto que mucha gente pregunta como enviar datos de Excel a Word, he de ser sincero y lo primero que se me viene a la cabeza es “que lo hagan desde Word usando Combinar Correspondencia”, pero en muchas de esas mismas ocasiones quieren y/o necesitan hacerlo desde Excel o en todo caso no solo enviar datos por partes sino más bien enviar incluso tablas o rangos completos. ¿Cuál es la solución? Definitivamente usar macros (VBA).

Para empezar, es importante aclarar que, si bien vamos a realizar la programación desde el entorno del VBA de Excel, como vamos a interactuar con Microsoft Word, lo que haremos es hacer referencias a los objetos de dicho programa, es decir, casi como usar el VBA desde el mismo Word. Dicho eso, lo primero que haremos es suponer que tenemos los siguientes datos:

Luego, como la idea es trabajar con Word, declararemos una variable respectiva y crearemos dicho objeto Word.

Dim MiappWord As Object 
Set MiappWord = CreateObject("Word.Application") 

Luego, como ya tenemos el Word listo, lo que haremos es crear un documento nuevo en blanco.

MiappWord.Documents.Add

Una vez hecho eso vamos a copiar el rango que necesitamos enviar a Word:

Hoja1.Range("A1:E97").Copy

Como ven ahí, en esta ocasión uso el nombre del módulo de la hoja para hacer referencia al rango de dicha hoja, no estoy usando ni Sheets ni WorkSheets ¿por qué? En realidad, es una buena forma de hacer referencia a las hojas sobre todo cuando más de una persona usa el archivo ya que si cambian el nombre de la hoja, y por ejemplo dice Sheets(“Hoja1”), dicha instrucción de VBA dejaría de servir, haciendo referencia al módulo de la hoja hay mayor garantía de que no se cambie (no es que nadie sapa como hacerlo, claro). Pero mejor volvamos a lo nuestro.

Como ya tenemos los datos en el portapapeles, ahora lo que haremos es pegarlos en Word, para ello utilizaremos el método PasteExcelTable que pega celdas de Excel en Word. Más referencias aquí: Enlace. Entonces, usaremos lo siguiente:

MiappWord.Selection.PasteExcelTable False, False, False

Ahora haremos visible el Word para ver el resultado.

MiappWord.Visible = True

Si leyeron el enlace recomendado, verán que lo que hemos hecho es pegar las celdas de Excel copiadas, manteniendo el formato de origen, por lo que debemos tener lo siguiente en nuestro archivo Word:

Vamos a probar diversas opciones del método sugerido, pero en cada ocasión vamos a insertar una página nueva en Word para que se note cada vez que pegamos los datos. Al método sugerido, vamos a agregarle un par más para que prueben. Comentaré en el código que es lo que hace cada uno.

With MiappWord
     'usar estilos de destino
     .Selection.PasteExcelTable False, True, False
     .Selection.InsertNewPage
     'vincular y mantener formato de origen
     .Selection.PasteExcelTable True, False, False
     .Selection.InsertNewPage
     'vincular y usar estilos de destino
     .Selection.PasteExcelTable True, True, False
     .Selection.InsertNewPage
     'imagen
     .Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
         Placement:=wdInLine, DisplayAsIcon:=False
     .Selection.InsertNewPage
     'conservar solo texto
     .Selection.PasteAndFormat (wdFormatPlainText)
 End With 

Para que esta última parte funcione sin mayor dilema, activen la siguiente referencia a Microsoft Word:

Si deseamos también podemos guardar el archivo.

MiappWord.ActiveDocument.SaveAs Filename:=ThisWorkbook.Path & "\miarchivo.docx"

Por último, podríamos tener una macro así ya con todo ordenado:

Sub EnviardatosaWord()

Dim MiappWord As Object 

Set MiappWord = CreateObject("Word.Application") 

MiappWord.Documents.Add 
Hoja1.Range("A1:E97").Copy 

With MiappWord
     'mantener el formato de origen
     .Selection.PasteExcelTable False, False, False
     .Selection.InsertNewPage
     'usar estilos de destino
     .Selection.PasteExcelTable False, True, False
     .Selection.InsertNewPage
     'vincular y mantener formato de origen
     .Selection.PasteExcelTable True, False, False
     .Selection.InsertNewPage
     'vincular y usar estilos de destino
     .Selection.PasteExcelTable True, True, False
     .Selection.InsertNewPage
     'imagen
     .Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, _
         Placement:=wdInLine, DisplayAsIcon:=False
     .Selection.InsertNewPage
     'conservar solo texto
     .Selection.PasteAndFormat (wdFormatPlainText)
     .ActiveDocument.SaveAs Filename:=ThisWorkbook.Path & "\miarchivo.docx"
     .Visible = True
 End With 

Application.CutCopyMode = False
Set MiappWord = Nothing 
MsgBox "Todo listo" 

End Sub 
Espero les sea útil. Hasta la próxima.

Abraham Valencia
Lima, Perú

Descargue el ejemplo de aquí