COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES

Hola a todos!

El post de hoy va a ser distinto a los que acostumbro a subir a la web, sobre todo porque está programado en WORD.

Hace ya tiempo que escribí un post relacionado con Combinar Correspondencia, en concreto para intentar dar solución a un problema muy común cuando se realiza esta funcionalidad con WORD, es decir, el obtener de manera individual todos los documentos generados.

Si no estáis familiarizados con Combinar Correspondencia, en este enlace podéis leer en profundidad de qué se trata. Si bien, en resumen, combinamos los campos de un archivo de Excel con una plantilla en WORD y generamos tantos documentos como datos tengamos en Excel. Podemos enviar por correo electrónico cada documento a su destinatario o generar los documentos todos a la vez, de uno en uno o por tramos.

Pero entonces, ¿cuál es el problema?, pues que si tenemos que generar 500 cartas (individuales), sería bastante tedioso el tener que generar y guardar cada documento de uno en uno manualmente.

Ante esta necesidad, en un primer avance lo he realizado con Excel directamente, y el proceso funciona correctamente, pero tiene sus limitaciones (fundamentalmente los formatos). Para solucionarlo me he decidido a hacerlo en Word. Me documenté con algunos procesos que se proponen en Internet, pero no me acababan de convencer, eran demasiado manuales y poco intuitivos. Así que he creado un proceso bastante más automatizado para facilitar la experiencia del usuario.

El primer paso que debemos realizar es obtener el archivo de WORD con los documentos ya generados, todos en el mismo archivo. Importante, el proceso está programado para documentos que ocupen un folio (una hoja de Word).

Pues bien, vamos a hacerlo paso a paso:

  • Generamos los documentos con Combinar correspondencia. Vamos a partir del siguiente listado en Excel (100 líneas)

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES

  • Combinamos correspondencia con el siguiente texto:

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES1

Una vez que hemos combinado y generado todos los documentos obtendremos un archivo de 100 hojas (una por empleado de la base de Excel).

A continuación, ese documento lo vamos a guardar, pero lo haremos o bien como .Doc o como .Docm (para macros), pero no .Docx. El motivo es que vamos a incluir una macro en el documento y con extensión .Docx no permite guardar con macros. Para este ejemplo lo denominaré como “DOCUMENTOS GENERADOS”

Hasta este punto ya tenemos el archivo de Word que queremos trocear en 100 archivos. Ahora debemos crear una carpeta o saber en cuál vamos a importar todos estos archivos, en mi ejemplo la crearé y la denominaré: “DESTINO”.

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES3

Y ya tenemos todo lo necesario para abrir DOCUMENTOS GENERADOS, crear un módulo estándar y pegar nuestra macro:

Option Explicit
Sub COMBINAR()
'DECLARAMOS VARIABLES
Dim mArchivo As Variant, fdocument As Document
Dim miExcel As String, target As Variant, obSQL As String
Dim cnn As Object, dataread As Object, filas As Long
Dim i As Long, iname As Variant, midoc As Document
Dim mi_archivo As String, campo As String, miCarpeta As Variant
Dim texto As Variant, target_a As Variant
'Capturamos documento actual
Set fdocument = ThisDocument
'Abrimos ventana de diálogo para seleccionar el archivo Excel
'que hemos combinado
Set mArchivo = Application.FileDialog(msoFileDialogOpen)
If mArchivo.Show = 0 Then Exit Sub
miExcel = mArchivo.SelectedItems(1)
'Abrimos ventana de diálogo para seleccionar la carpeta en la que
'guardaremos todos los archivos independientes
Set miCarpeta = Application.FileDialog(msoFileDialogFolderPicker)
If miCarpeta.Show = 0 Then Exit Sub
miCarpeta = Application.FileDialog(msoFileDialogFolderPicker).SelectedItems(1) & "\"
'Generamos documento nuevo
Set target = Documents.Add
'Con instrucción SQL seleccionamos el nombre de la hoja
'y el campo con el que queremos identificar cada documento de word
obSQL = "SELECT [BBDD$].[NOMBRE COMPLETO] FROM [BBDD$]"
'Iniciamos conexión ADO para pasar una tabla con los items
'del campo seleccionado
Set cnn = New ADODB.Connection
With cnn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Connectionstring = "DATA SOURCE=" & miExcel
.Properties("Extended Properties") = "Excel 8.0"
.Open
End With
Set dataread = New ADODB.Recordset
With dataread
.Source = obSQL
.ActiveConnection = cnn
.CursorLocation = adUseClient
.CursorType = adOpenForwardOnly
.LockType = adLockReadOnly
.Open
End With
'Grabamos los datos en el documento Word generado (target)
dataread.MoveFirst
filas = dataread.RecordCount
Selection.InsertAfter dataread.Fields(0)
Do Until dataread.EOF
dataread.MoveNext
If dataread.EOF = "Verdadero" Then Exit Do
campo = Replace(dataread.Fields(0), "-", " ")
Selection.InsertAfter Chr(11) & campo
Loop
'Formateamos los datos grabados como una tabla
Selection.ConvertToTable Separator:=wdSeparateByDefaultListSeparator, _
numcolumns:=1, Numrows:=filas, AutoFitBehavior:=wdAutoFitFixed
Set midoc = ActiveDocument
'Recorremos la tabla
For i = 1 To midoc.Tables(1).Rows.Count
Set iname = midoc.Tables(1).Cell(i, 1).Range
'Eliminamos de cada dato el retorno de carro, Chr(13).
'Eliminamos el último caracter de la cadena de texto
mi_archivo = Mid(Replace(miCarpeta & iname.Text, Chr(13), ""), 1, Len(Replace(miCarpeta & iname.Text, Chr(13), "")) - 1)
'Recorremos todas las hojas del documento word actual
'Creamos un nuevo documento y pasamos el contenido de cada combinación.
Set texto = fdocument.Sections(i).Range
texto.End = texto.End - 1
Set target_a = Documents.Add
target_a.Range.FormattedText = texto
'Nombramos cada documento con el nombre
'de la hoja que contiene los datos extraidos de Excel
target_a.SaveAs FileName:=mi_archivo
'Cerramos cada documento
target_a.Close
Next i
'cerramos el documento con los datos de Excel
ActiveDocument.Close SaveChanges:=False
End Sub

Después de pegar la macro, debemos activar las referencias para trabajar con ADO: Microsoft ActiveX Data Object 2.8 Library (en caso de no tener esta librería podéis probar con otra de la lista).

Este paso debéis hacerlo, de lo contrario se mostrará un error y no podréis continuar.

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES4

Otro paso que debemos realizar manualmente es determinar el campo del archivo Excel a incluir en el documento de Word.

Debemos especificarlo en la siguiente línea de código:

obSQL = "SELECT [BBDD$].[NOMBRE COMPLETO] FROM [BBDD$]"

Donde la hoja de nuestro archivo Excel se denomina BBDD, debemos especificarlo en la sentencia SQL y siempre con el dólar al final. El campo que vamos a incluir será NOMBRE COMPLETO y también lo especificamos en el SQL. Este paso es importante, si el nombre de la hoja o del campo no es correcto, se mostrará un error y no podremos continuar. Si se muestra el error, debéis reiniciar la macro para volver a ejecutarla y eliminar el documento en blanco que se creó antes de llegar al error.

Pero sigamos, suponiendo que ya tenemos la macro totalmente preparada, cuando la ejecutemos se mostrará un cuadro de diálogo para seleccionar el archivo Excel:

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES6

A continuación se volverá a abrir otro cuadro de diálogo para seleccionar la carpeta en la que dejaremos todos los 100 documentos creados:

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES7

Después dejaremos que se vayan generando los documentos hasta que finalice la macro, el resultado será este:

COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES5

Como podéis observar hemos generado 100 documentos y los hemos identificado con su nombre (podría ser con otro campo cualquiera que sea un identificados único).

Y eso es todo!. Espero que el post sea lo bastante claro y no os queden dudas, pero en cualquier caso, os dejaré los dos archivos para que realicéis pruebas.

Descarga el archivo de ejemplo pulsando en: DOCUMENTOS GENERADOS

Descarga el archivo de ejemplo pulsando en: BASE EXCEL PARA COMBINAR

¿Te ha resultado de interés?, puedes apoyar a Excel Signum con una pequeña donación.

Donate Button with Credit Cards

¡¡Muchas gracias!!

Mediante la suscripción al blog, la realización comentarios o el uso del formulario de contacto estás dando tu consentimiento expreso al tratamiento de los datos personales proporcionados según lo dispuesto en la ley vigente (LOPD). Tienes más información al respecto en esta página del blog: Política de Privacidad y Cookies

Anuncios

10 pensamientos en “COMBINAR CORRESPONDENCIA Y GUARDAR DOCUMENTOS INDEPENDIENTES

  1. COMBINAR CORRESPONDENCIA me genera un ERROR Estoy seguro que se debe al paso manual: obSQL = “SELECT [BBDD$].[NOMBRE COMPLETO] FROM [BBDD$]” este paso hay que hacerlo en el Nombre del archivo en Word ? Remito archivo completo COMPRIMIDO Favor colaborarme Gracias

    Me gusta

    • Hola Emiro:

      No me ha llegado ningún archivo. El paso manual hace referencia al archivo EXCEL, en el post indico cómo deben incluirse los parámetros:

      BBDD es el nombre de la hoja, Nombre completo es el nombre del campo. Revisa el ejemplo del post, verás como en el segundo archivo (el Excel estos son los campos usados.

      Intenta reproducir mi ejemplo, paso por paso comprendiendo cómo funciona el código. En resumen, el SQL hace referencia al Excel no al Word.

      Saludos.

      Me gusta

  2. Excelente solución! esto debería estar incorporado en Word! sólo para reforzar el tutorial… en la línea

    “SELECT [BBDD$].[NOMBRE COMPLETO] FROM [BBDD$]”

    BBDD es el nombre de la Hoja de Excel, no el archivo Excel! cuando uno crea un archivo excel, por defecto se crea “Hoja1”
    NOMBRE COMPLETO: Es el nombre del campo! es decir, en los títulos de la tabla hay que elegir el que necesitas para generar en base a ese los nombres de los archivos.

    Recordar también que la primera ventana que aparece es para elegir el archivo y la segunda es para elegir la carpeta.

    Yo copié y pegue y modifique. Simple.

    Felicitaciones!

    Me gusta

  3. La función está excelente, sin embargo, es posible realizar también el copiado del encabezado? y que pasaría si esto tiene una imagen.

    Me gusta

    • Hola Francisco,

      Lo de la imagen no tiene ningún tipo de problema porque hacer antes el combinar correspondencia bajo el modelo que estimes oportuno, incluida la imagen.

      Lo de copiar los encabezados, francamente no veo la necesidad, en el combinar correspondencia no se admite, y aunque con ADO se puede copiar el encabezado, a la hora de trozear el archivo solo utilizas el campo que te interesa para distinguir los archivos, normalmente un nombre o un ID.

      Saludos.

      Me gusta

  4. Me ha sido de mucha ayuda. Te agradecería que me ayudaras por que no obstante me genera un error: campo = Replace (dataread.Fields (0), “-“, ” “)
    y cuando la ejecuto se abre una única hoja de word con una fila con todos los nombres de USUARIO, que es el nombre del que he elegido para el SQL.
    Por qué no genera todos los documentos?, por qué me da ese error si he copiado tu macro tal y como la tienes?.
    Muchas gracias por tu respuesta… urgente si puede ser. Te lo agradezco muchísimo. Amaia

    Me gusta

  5. Hola de nuevo!. Ahora me da un nuevo error:
    Iniciamos conexión ADO para pasar una tabla con los items
    del campo seleccionado
    LockType = adLockReadOnly
    Open
    Me pone error en el nombre, y me subraya fosforito este último Open
    Te agradezco mucho tu ayuda.
    Un saludo

    Me gusta

  6. ‘Iniciamos conexión ADO para pasar una tabla con los items
    ‘del campo seleccionado
    Set cnn = New ADODB.Connection
    With cnn
    .Provider = “Microsoft.ACE.OLEDB.12.0”
    .Connectionstring = “DATA SOURCE=” & miExcel
    .Properties(“Extended Properties”) = “Excel 8.0”
    .Open
    End With
    Set dataread = New ADODB.Recordset
    With dataread
    .Source = obSQL
    .ActiveConnection = cnn
    .CursorLocation = adUseClient
    .CursorType = adOpenForwardOnly
    .LockType = adLockReadOnly
    .Open

    Estos son los datos que me da error. Los he copiado exactamente para facilitar la ayuda.
    Gracias de nuevo.

    Me gusta

    • Hola Amaia:

      Ese error aparece cuando el nombre del archivo Excel o de la pestaña de Excel no es correcto:

      obSQL = “SELECT [BBDD$].[NOMBRE COMPLETO] FROM [BBDD$]”

      En el ejemplo que he subido, la pestaña o hoja Excel con los datos se llama BBDD$ siempre tienes que poner un dolar al final para indicar que se trata de una hoja. Y el campo o nombre de columna con el dato a asociar es NOMBRE COMPLETO.

      Esto debe ser exactamente como lo tengas en tu archivo excel.

      En cuanto al otro error:

      campo = Replace(dataread.Fields(0), “-“, ” “) omite el replace directamente:

      campo = dataread.Fields(0)

      Saludos.

      Me gusta

¿Te ha gustado?, Realiza un comentario.

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.