Macro para imprimir todos los registros desde word con combinar correspondencia

De nuevo Prozac:

Otra vez recurro a tí con la esperanza de que me puedas dar una respuesta a la siguiente cuestión.

Tengo una carta en Word que está combinada con una tabla de excel utilizando el sistema de "combinar correspondencia" . He generado una macro con la que desde un botón en el libro de excel me abre la carta de Word, la imprime y la cierra. La macro funciona correctamente, con la salvedad de que sólo me imprime el primero de los registros de la tabla. Mi intención es que me imprima todos los registros, es decir, una carta para cada uno de los registros, pero no sé qué instrucción poner para que lo haga así. También me interesaría que en el momento de cerrarse el documento se cerrase sin guardar cambios ni hacerme la pregunta (aunque lo cierto es que ahora tampoco me pregunta nada ni creo que me guarde los cambios).

El código que tengo escrito en la macro es el siguiente:

   Sub abre_Word()
    Dim MiHoja As Object
    Dim txt
    txt = "C:\Users\MANOLO\Desktop\Documentos Nuevos\Doc1.docx"
    Set MiHoja = CreateObject("Word.Application")
    MiHoja.Visible = True
    MiHoja. Documents. Open (txt)
    MiHoja. ActiveDocument. PrintOut
    MiHoja. ActiveDocument. Close
    MiHoja. Quit
End Sub

Gracias por adelantado, aunque sólo sea por aguantarme el rollo.

2 Respuestas

Respuesta
1

Hasta donde yo sé la combinación de correspondencia se realiza desde Word, no desde Excel. Word te da ya las herramientas para imprimir, enviar o editar todos los ficheros que te salen de la combinación.

Creo que no tiene sentido hacerlo desde Excel si Word ya te facilita las cosas. De todos modos si estás interesado por algún extraño motivo en hacerlo desde Excel, lo que tienes que hacer en tu código es localizar los campos del documento maestro e irlos sustituyendo por los datos del Excel. La colección de campos del documento está en

ActiveDocument. Fields por si insistes en seguir por ahí.

Si utilizas el método estándar, es decir desde Word te recomiendo este tutorial:

http://hojas-de-calculo-en-excel.blogspot.com/2009/03/combinar-correspondencia-excel-word.html

Aunque es sobre una versión de Excel xp, creo que es bastante claro. Incluso puedes descargar los ficheros de ejemplo para que veas como funciona.

Gracias por tu respuesta Prozac.

Te aclaro un poco mis intenciones. El sistema de combinar correspondencia desde Word ya lo vengo usando desde hace tiempo y sé perfectamente cómo se utilizan todas sus opciones de impresión y configuración desde Word, lo que pasa es que estoy creando un nuevo registro en Excel y quería poder imprimir directamente desde él con una macro asignada a un botón de comando por los siguientes motivos:

Una vez que concluyo el registro tengo que imprimir más de 20 modelos distintos de cartas. Cada una de las cartas tiene unos campos determinados del registro de Excel, y a su vez están configuradas cada una de ellas con distintos parámetros (localizar los registros con fecha actual, que sólo se impriman cada una de ellas según qué campos estén o no cubiertos, etc.), con lo cual cada modelo de carta se imprime para unos registros sí y para otros no, con unos campos o con otros distintos.

Por supuesto podría abrir cada uno de los documentos (cartas de Word) y combinar al imprimir, seleccionando todos los registros (ya que me va a imprimir sólo aquellos que cumplan los criterios de configuración de la propia carta), lo que pasa es que hacer esto a diario con cada uno de los documentos se hace bastante tedioso.

Mi intención era (si es que existe la posibilidad) crear en Excel una macro asignada a un botón en la que se diese la orden de abrir un determinado documento de Word (la carta correspondiente) y que una vez dentro del documento de word la propia macro ordenase que se seleccionara la opción de combinar al imprimir y la de imprimir todos los documentos (una carta por cada uno de los registros que cumplan las condiciones) y, por último,  cerrar el documento de word sin guardar cambios.

Con ello conseguiría que configurando una macro para cada uno de los documentos, una vez concluido el registro, se hiciese todo el proceso completo para cada carta con solo clicar sobre el botón que tuviese la macro correspondiente asignada.

El caso es que consigo hacerlo, pero sólo me imprime el primer registro de cada documento (o sea la carta correspondiente al primer registro que cumple los criterios que previamente establecí con el método de combinar correspondencia para ese modelo de carta).

Espero haberme explicado con claridad.

Estoy intentando responderte pero no puedo pegar el código aquí, no sé que pasa. Incluso solo con Chrome puedo llegar hasta la caja para enviar la respuesta.

Te adelanto no obstante. La clave está en instrucciones como ésta, después de abrir el documento.

MiDoc.ActiveDocument.fields(j).Result.Text=Cells(i,j).value

He pouesto esto dentro de dos bucles for, uno para cada carta y otro para los campos de la carta. Además los campos de cada carta van por filas, cada campo en una columna de la misma fila, si pertenecen a la misma carta.

Si consigo copiar el código lo haré. No es que sea mucho, pero no quiero hacerlo a mano para evitar errores.

Muchas gracias.

No te preocupes, no corre prisa.

Una vez abierto el documento con campos combinados, puse la grabadora de macros (mis conocimientos de vba no dan para más que elaborar el código con la grabadora de macros o para buscar en los foros con copiar y pegar) e introduje en el código que posteé al principio la parte de código que me generó ahora la grabación de la macro, pero, como era de esperar, no funciona. Por si te vale de algo inserto a continuación el código que elaboré completo.

Sub abre_Word()
    Dim MiHoja As Object
    Dim txt
    txt = "C:\Users\MANOLO\Desktop\Documentos Nuevos\Doc1.docx"
    Set MiHoja = CreateObject("Word.Application")
    MiHoja.Visible = True
    MiHoja.Documents.Open (txt)
    ActivePrinter = "\\DESPACHO\HP Photosmart C3100 series"
        With ActiveDocument.MailMerge
        .Destination = wdSendToPrinter
        .SuppressBlankLines = True
            With .DataSource
            .FirstRecord = wdDefaultFirstRecord
            .LastRecord = wdDefaultLastRecord
            End With
        .Execute Pause:=False
        End With
    ActiveWindow.Close
    Application.Quit
End Sub

Saludos y gracias por tu desinteresado esfuerzo.

A ver si funciona ahora.

Hola. Te pongo un ejemplo basado en tu código que hace lo que creo quieres. Tendrás que adaptarlo. Para el ejemplo supongo que el documento tiene tres campos y el Excel por fila tiene los datos de esos tres campos. Además también hay tres filas, es decir tres cartas a imprimir.
Sub abre_Word()
Dim MiDoc As Object
Dim txt
Dim j As Integer
Dim maxcampos As Integer
Dim maxcartas As Integer
txt = "C:\Excel\combinar_correspondencia\Doc1.doc" 'Pon tu directorio y nombre de doc
Set MiDoc = CreateObject("Word.Application")
MiDoc.Visible = True
MiDoc.Documents.Open (txt)
maxcampos = 3 'o los que tenga
Maxcartas = 3 ' o se calcula por el número de filas del Excel
'rellena los campos con celdas excel
For i = 1 To maxcartas
For j = 0 To maxcampos
MiDoc.ActiveDocument.fields(j).Result.Text = Cells(i, j + 1).Value
Next j
MiDoc.ActiveDocument.PrintOut
Next i
MiDoc. Quit
MiDoc. ActiveDocument. Close
End Sub

Parece que se acerca la solución, aunque algo falla.

Al ejecutar el código me dio un mensaje de error, por lo que le añadí la instrucción Option Explicit para que me depurase el código. En primer lugar me dio un fallo en la línea:

For i= To maxcartas

Ya que no se había definido la variable, por lo que le añadí la variable:

Dim i As Integer.

Después de eso vuelvo a ejecutar el código y el depurador me da un fallo en la línea:

MiDoc.ActiveDocument.fields(j).Result.Text = Cells(i, j + 1).Value

"Se ha producido el error '5941' en tiempo de ejecución: El elemento del conjunto solicitado no existe".

Aquí sí que ya me pierdo.

Te posteo a continuación el código modificado por mí con un par de aclaraciones:

Como puedes ver le introduje 67 campos que son los que tiene la 'tabla' en el valor "maxcampos" (el registro lo tengo creado en una tabla, cuyo primer campo está en la columna B). En cuanto al valor (me parece que no se llama así en Vba) "maxcartas" no entiendo muy bien lo que dices que debería de poner; puse 1000, aunque actualmente la tabla sólo tiene 10 filas para hacer las pruebas, pero una vez funcione en un año alcanzará los mil y pico.

Option Explicit
Sub abre_Word()
Dim MiDoc As Object
Dim txt
Dim i As Integer
Dim j As Integer
Dim maxcampos As Integer
Dim maxcartas As Integer
txt = "C:\Users\MANOLO\Desktop\Documentos Nuevos\Nuevo SCA\Carta de Prueba.docx" 'Pon tu directorio y nombre de doc
Set MiDoc = CreateObject("Word.Application")
MiDoc.Visible = True
MiDoc.Documents.Open (txt)
maxcampos = 67 'o los que tenga
maxcartas = 1000 ' o se calcula por el número de filas del Excel
'rellena los campos con celdas excel
For i = 1 To maxcartas
For j = 0 To maxcampos
MiDoc.ActiveDocument.fields(j).Result.Text = Cells(i, j + 1).Value
Next j
MiDoc.ActiveDocument.PrintOut
Next i
MiDoc.Quit
MiDoc.ActiveDocument.Close
End Sub

Por enésima vez, gracias. Espero no agotar tu paciencia con mi ignorancia.

Vamos por partes para ver donde está el fallo. Yo lo escribí con un ejemplo sencillo, tal vez demasiado sencillo.

Me parece bien poner lo de Option Explicit. Es mas, lo suelo recomendar para evitar fallos a la hora de escribir variables.

Para los campos, si son 67, que me parecen muchos, pues habrá que considerarlos, aunque para probar puedes poner un valor menor, sabiendo que solo te sustituirá esos. Para las cartas si son 10 pues entonces pon 10.

Los campos empiezan en 0 y las celdas en A1 o lo que es lo mismo Cells(1,1). De ahí la fórmula en la sentencia que falla. Si tienes 67 campos, maxcampos debe ser 66 porque como te digo comienzan en cero. Por otro lado entiendo que no dejas filas vacías ni tus columnas tienen cabeceras (bueno si las tienen habrá una carta con esos nombres).

Puedes entrar en el depurador con F8 e ir viendo los valores que toman las cosas a medida que ejecutas paso a paso. También puedes poner puntos de parada. Todo eso está en el menú Debuger dentro del Editor VBA. Si no te apañas con el ello puedes dividir la instrucción en dos añadiendo una variable y viendo donde falla. Seria algo como:

tmp = Cells(i, j + 1).Value

MiDoc.ActiveDocument.fields(j).Result.Text = tmp

La defines previamente como Variant si quieres, y ves si el objeto que no existe es la celda o el campo. Me inclino por lo segundo si has puesto el valor 67 en tus pruebas, porque efectivamente acaba en el 66.

Respuesta

A mi me funciono esta teniendo en cuenta que es una combinación de correspondencia desde word con fuente de datos de Excel y en la ruta : ChangeFileOpenDirectory "C:\" quedan los archivos guardados

Sub Macro1()

Dim a As Integer
Dim n As Integer
Dim Texto As String
Dim NombreArchivo
n = 1
Cadena = ""
Texto = ""
NombreArchivo = ""
ActiveDocument.MailMerge.DataSource.ActiveRecord = wdFirstRecord 'posiciono el archivo en el primer registro
a = ActiveDocument.MailMerge.DataSource.RecordCount 'Conteo del numero de registros

For n = 1 To a
Texto = ActiveDocument.Fields(1).Result.Text  'Fields(1) = el campo que quiero que tome para el nombre del archivo.
ActiveDocument.MailMerge.DataSource.ActiveRecord = wdNextRecord 'posiciono el archivo en el siguiente registro
NombreArchivo = Texto & ".doc"
ChangeFileOpenDirectory "C:\"
ActiveDocument.SaveAs2 FileName:= _
NombreArchivo, _
FileFormat:=wdFormatDocument, LockComments:=False, Password:="", _
AddToRecentFiles:=True, WritePassword:="", ReadOnlyRecommended:=False, _
EmbedTrueTypeFonts:=False, SaveNativePictureFormat:=False, SaveFormsData _
:=False, SaveAsAOCELetter:=False, CompatibilityMode:=0

Next
End Sub

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas