Como generar un pdf desde un botón de un formulario de Access, para cada registro de un informe y lo envíe por correo

Por las vueltas que le he dado y no consigo lo que necesito. Me manejo muy bien con Access, pero de VBA ni idea.

Tengo un informe (I_CURSOS) que me saca todos los cursos (miles) que realizan los alumnos (cientos) y en un formulario quiero tener un botón que al pulsarlo me genere un pdf con todos los cursos que ha realizado cada alumno, me los guarde individualmente (uno para cada alumno) en una subcarpeta de Informes PDF donde tengo la BD (C:\BD\InformesPDF\) y además si fuese posible, me envíe cada pdf por correo electrónico al correo de cada alumno. La dirección del correo (CORREO_E) está en I_CURSOS.

Para sacar uno solo no tengo problema, pero para que me cree todos los PDF, no lo consigo. Con el código que indico a continuación, solo me genera el último.

El código que tengo para generar el pdf es:

Private Sub GeneraunPDF_Click()

Dim i As Byte
For i = 1 To 430  'es el total de alumnos
   DoCmd.OpenReport "I-Cursos", acPreview, , "Id=" & i & ""
   DoCmd.OutputTo acOutputReport, "I-Cursos", "PDFFormat(*.pdf)", "C:\BD\InformesPDF\" & "" & Me           .'[NOM1] & "" & ".pdf"  'va en la misma línea, aunque aquí me lo separa.

' NOM1 es el nombre del alumno

' Faltaría añadir aquí el código para que me envíe cada pdf por correo electrónico a CORREO-E de cada alumno

Next
DoCmd.Close acReport, "I-Cursos"

End Sub

Agradezco de antemano cualquier ayuda, pues se que no debe ser muy complicado, ya que he visto decenas de preguntas parecidas en el foro, pero por una cosa u otra no me sale.

2 Respuestas

Respuesta

En este post :

VBA Access-Outlook para enviar un adjunto pdf en correo con formato HTML

Hay dos métodos para interactuar con el correo electrónico, son muchos los correos por lo que si los envías de una sola vez (los correos creados se quedan en la bandeja de salida y se enviaran cuando abras la sesión de Outlook) pueden ser clasificados como SPAM, te recomendaría que lo hicieras por bloques.

Si actualmente no te funciona, es porque no lo estas haciendo de la forma correcta.

Tienes esto:

"C:\BD\InformesPDF\" & "" & Me.'[NOM1] & "" & ".pdf"

Y debería ser esto:

 "C:\BD\InformesPDF\" & Me. NOM1 & ".pdf"

Se trata de construir una ruta que Windows pueda entender, no tiene nada que ver con Access excepto el nombre del campo (Me. NOM1) que te obligara a ir presentando registro a registro (esto es visualizando por pantalla) a cada alumno o (Me. MON1) siempre será el mismo

El editor añadió un espacio por su cuenta

"C:\BD\InformesPDF\" & Me.NOM1 & ".pdf"

Buenas noches Enrique.

Muchas gracias por tú respuesta. He corregido lo que me indicas y he creado un informe con solo 2 registros para probar y solo me genera un pdf del ultimo registro; no me guarda en pdf  el primero.

Si cada registro tiene un destino diferente (un PDF + un alumno + un correo-e) no puedes crear un informe con mas de un registro (a no ser que puedas y quieras 'trocear' el PDF mas tarde), se tiene que crear un PDF por registro y si algún alumno tiene mas de un curso tendrás que decidir si se le envía un PDF por cada curso o se juntan todos sus cursos en un solo PDF.

Se puede plantear de dos formas, crear un PDF por asistente al mismo curso y generar el/su personal PDF (creo que se adapta a enviarlos al finalizar el curso) o bien crearlos por alumno y enviarle a cada uno un PDF por curso en los que participo o un único PDF con todos los cursos en que participo (esto seria útil si alguno solicita los diplomas o copias).

¿Cuál es la idea que tienes en mente?... de forma practica lo que se necesitara es la dirección de correo, el PDF (o los PDFs si fuera el caso) y el texto del mensaje y algún otro detalle que puedes decidir en cuanto generes (individualmente) un par de envíos de control y si te satisfacen crear la plantilla (esto es, añadir las variables con los datos personalizados).

Observa los datos que los diferencian y se podrá aplicar el método de crear una tabla temporal con los datos imprescindibles y alguno mas de control (si se le envío y cuando) y llenarla mediante una consulta.

Con esa tabla y los datos imprescindibles en ella, con una función se pueden generar los archivos en tiempo de ejecución, generar el correo con ellos y al finalizar borrarlos (actualizando en la tabla la fecha o marca de su envío), lo del borrado es opcional (pero dado que se pueden generar en cualquier momento, guardarlos solo ocupa espacio).

La decisión del camino a seguir esta en tu mano, lo que seria interesante es informarse que numero de envíos puedes hacer sin que los servidores lo consideren SPAM (tu proveedor te podrá aconsejar al respecto) pues en la función se le podrá planificar el envío para evitarlo.

Buenos días Enrique Feijoo.

En primer lugar, muchas gracias por tu ayuda. Es un gusto que haya personas tan generosas con los demás.
ENN segundo lugar pedirte disculpas por tardar unos días en responder, no es por falta de interés (todo lo contrario), lo que pasa es que empezamos la reforma de nuestro piso en unos días, y estamos de mudanza, viendo cocinas, baños, etc con lo que cuando llego por la noche a casa, estoy tan agotado que me es imposible ponerme con este tema.
Volviendo al problema. Te comento lo que he sacado hasta ahora con tu ayuda. Pero antes, te añado algo más de información resumida, para ponerte en situación y comprendas mejor lo que tengo montado.
De cara a tratar de resolver los errores, me he creado una tabla de cursos duplicada donde solo tengo los cursos de 3 personas, de forma que me es más fácil ver donde me falla el sistema. El primer alumno (A1) tiene 9 cursos realizados por lo que tiene 9 registros en T-CURSOS2. EL Segundo alumno (A2) tiene 91 registros/cursos realizados y un A3 con 1 solo curso/registro.
Tengo un informe (I_CURSOS) donde tengo los tres informes, uno de cada alumno. La idea es crear un PDF por cada uno de los tres alumnos, en los que se muestren todos los cursos realizados por cada uno de ellos.
Tengo un Formulario donde cuando hago click sobre un botón, me abre el informe I_CURSOS y me genera un pdf y lo envía por correo perfectamente, pero el problema es cuando hace el siguiente FOR-NEXT, que me saca los datos del segundo registro de la tabla en lugar del 2º informe. Es decir, como el Alumno1 tiene 9 registros en la tabla, me saca los datos del registro2 de la tabla y me machaca el nombre del PDF, que al ser el mismo alumno/registro, el PDF sigue conteniendo el informe con los 9 cursos
Tengo una tabla (T_CURSOS) donde tengo los miles de cursos que han realizado todos los alumnos. Cada alumno tiene tantos registros en la tabla como cursos haya finalizado.
Tengo un informa que me genera todos los cursos finalizado por cada alumno.
Tengo un formulario con un botón que me abre el informe y en teoría tendría que leer el primer informe, generar un pdf con el mismo y enviarlo por correo. Esto lo hace bien con el primero, Pero con el segundo falla, porque en vez de generar el 2º informe, me saca los datos del 2º registro de la tabla (que hasta el 9 pertenecen al mismo alumno) y ya da error el código.
Lo que necesito, por tanto, es ver cómo una vez que lee el primer informe lo guarde y lo envíe, pase al siguiente ¿registro? del informe.
Lo de la tabla temporal que me dices, no lo entiendo muy bien, pero igual no es necesario recurrir a ello, si se solventa el problema plantado.
Mil gracias anticipadas. Ya te leo y comento en cuanto tenga un momento libre.

Centrémonos en el problema con Access para encontrar una solución para hoy y si puede ser también mañana.

Los informes solo se pueden abrir una única estancia y son estáticos, para cambiar los datos se tienen que cerrar, hacer los cambios y volver a abrirlo con los nuevos, si con el abierto se abre nuevamente -sin antes cerrarlo- el único válido es el primero (y no devuelve error).

Cuando lo exportamos no hay opción para aplicar condiciones, si las necesita (para seleccionar el cliente, la factura...) se suele aplicar el método de abrirlo (condicionado) y con el abierto exportarlo, la exportación lo volverá a abrir pero no lo puede actualizar (y como no delata error) utilizara el que está abierto- y condicionado- asumiendo ‘que es el suyo’.

¿Cómo se gestiona que un alumno tenga más de un curso y que se desee emitir un PDF por curso al que asistió?

Pues con dos bucles, uno que recorra los alumnos y otro en el que -por alumno- recorra sus cursos (un clásico: bucle dentro de bucle).

Al respecto de que repita el mismo informe (del mismo alumno) tantas veces como cursos completo, es que la referencia para el bucle es incorrecta, se ha de ir ‘al siguiente alumno’, no al siguiente registro/curso ya que el informe por alumno engloba todos sus cursos (o debería hacerlo).

Exactamente que se desea obtener por alumno:
.- Un correo con único informe (adjunto) con todos sus cursos
.- Un correo con tantos informes (adjuntos) como cursos a los que asistió el alumno.

Crear un correo implica una dirección, un asunto, un contenido y tantos adjuntos como se necesite.

Los adjuntos tienen que crearse de forma previa para poder adjuntarlos antes de finalizar el correo y enviarlo a la bandeja de salida. Una vez finalizada la creación del correo-e los adjuntos se pueden borrar o mantener (guardar).

Hay un método que puede ahorrar tiempo a la hora de crear los adjuntos, evita el paso de abrir el informe condicionado (o personalizado), utilizarlo y cerrarlo (repitiendo el ciclo con el siguiente adjunto).

EL método consiste en generar el filtro (la condición) y aplicársela al informe al exportarlo, evitando abrirlo dos veces y cerrarlo una.
Solo requiere un mínimo cambio en el informe y no le afectara para cualquier otro uso del mismo, eso sí:
La condición que se le aplica con este método es prioritaria sobre cualquiera otra, se activa dándole contenido y se desactiva vaciando la variable(es de texto, se le asigna una cadena vacía).

Si actualmente se dispone de un código que genera los correos (aunque solo funcione de uno en uno) publícalo y se podrá adaptar a lo que ya existe.

De la actual tabla T_CURSOS se puede obtener un listado único de alumnos (una consulta) para utilizar en el bucle y enviar un correo por alumno con el adjunto o –con un segundo bucle- tantos adjuntos como cursos.

Respuesta
1

Vamos a ver si me explico. Primero, tal como tienes declarada la variable no te va a funcionar ya que Bite sólo llega hasta 255. Tendrás que declararla como integer, que llega hasta 32 mil y pico. Segundo, si quieres usar el Outlook que viene con el Office, tendrías que enviar uno, desplazarte a un nuevo registro, volver a enviar otro, etc. Sin embargo si usas el Outlook que viene con el Windows podrías hacerlo( parece muy complicado por la extensión, pero realmente es muy sencillo) con

Primero, abre el editor de VB y en la barra de menús pulsa Herramientas-Referencias y activa la casilla Microsoft Outlook XX.0 Object Library

Lo de XX es por la versión del Office que tengas instalado.

Y luego, en el evento, por ejemplo, Al hacer clic de un botón pon

Private Sub Comando47_Click()
dim i as integer
for i=1 to 430
DoCmd.OpenReport "facturas", acPreview, , "numfactura='" & Me.NumFactura & "'"
DoCmd.OutputTo acOutputReport, "facturas", "PDFFormat(*.pdf)", "c:\users\gonza\documentos\borrar\Facturas\" & "" & Me.NumFactura & "" & ".pdf", False, "", , acExportQualityPrint
DoCmd.Close acReport, "facturas"
Dim Enviar As Outlook.Application
    Dim pTaskItem, ptaskitemasig As Outlook.TaskItem
    Const olCreateTasks = 3
    Const olDialog = 1
    Const olSound = 8
    Set Enviar = CreateObject("Outlook.Application")
    sSubject = "Tengo la obligación de remitirte este facturón"
    sBody = "Si no pagas no hay perdón"
    dDue = Now()
    dStart = Now()
    sSoundFile = "alarm3"
    bReminderSet = True
    Set pTaskItem = Enviar.CreateItem(olCreateTasks)
        pTaskItem.Subject = sSubject
        pTaskItem.Body = sBody
        pTaskItem.DueDate = dDue
        pTaskItem.StartDate = dStart
        pTaskItem.ReminderSet = bReminderSet
        If bReminderSet Then
              pTaskItem.ReminderSoundFile = sSoundFile
              pTaskItem.ReminderTime = Now()
        End If
        pTaskItem.Recipients.Add ("'" & Me.Email & "'")
        pTaskItem.Attachments.Add ("C:\users\gonza\documentos\borrar\Facturas\" & "" & Me.NumFactura & "" & ".pdf")
        pTaskItem.Save
        pTaskItem.Assign
        pTaskItem.Send
        Set pTaskItem = Nothing
    Set Enviar = Nothing
Next
End Sub

Tienes que cambiar mis nombres por los tuyos.

Me explico. Primero abre el informe con el Idalumno=1, lo guarda como PDF en la carpeta Facturas con el( en este caso) numero de factura.pdf, cierra el informe y envía el archivo a la bandeja de salida del Microsoft Outlook como archivo adjunto. Se va a la siguiente i, para el ejemplo, el 2. Abre el informe con IdAlumno=2, lo guarda en la carpeta Facturas con el IdAlumno. Cierra el informe y lo envía a la bandeja de salida. Y así hasta...

Dependiendo de como tengas configurado el Outlook, te los mantiene en la bandeja de salida hasta que decidas enviarlos o te lo envía directamente según lo reciba.

De todas formas, si quieres, repito, si quieres, mándame un mensaje (sólo el mensaje) a [email protected] y te mando un ejemplo, que opino que es como mejor se ve.

Si lo haces, en el asunto del mensaje pon tu alias Ray Romel, ya que si no sé quien me escribe ni los abro

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas