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í

6 comentarios:

  1. Excelente explicaion y ejemplos muy claros

    ResponderBorrar
  2. Genial...!!! Esta información el valiosisima ya que no hay mucha y si la hay no es del todo claro... Gracias.

    ResponderBorrar
  3. Abraham si lo que deseo es montar en word una platilla que solo me pase una serie de cosas, como seria entonces

    ResponderBorrar
    Respuestas
    1. ¡Hola! En esos casos, mi recomendación es usar "Combinar correspondencia" desde el Word y usando como base de datos tu archivo de Excel. Si necesariamente quieres enviar datos desde Excel a ciertos partes específicas de un archivo de Word, es un poco más complicado que enviar toda una tabla, de ser ese tu dilema, casualmente esta semana escribiré al respecto.

      Borrar
    2. Exacto es eso lo que necesito para el proyecto que estoy creando y necesitaria saber como crear una plantilla en word para pasar una serie de datos desde excel.
      En concreto necesito crear una historia clínica

      Borrar