access stampa unione e invio mail personalizzate in pdf

Anonimo
2017-01-13T11:39:27+00:00

Buongiorno a tutti.

E' un po' di tempo che cerco di risolvere questo problema; ho letto, studiato e cercato di applicare al mio caso specifico decine di soluzioni in merito, ma, mancandomi quasi completamente le basi, non riesco nell'intento. Entriamo nel merito:

Lavoro periodico: capita spesso in studio di dover inviare delle lettere circolari personalizzate ai clienti; ho quindi creato un file di word generico "Stampa unione" con campi unione prelevati da una tabella di Access;

Obiettivo: inviare un file PDF personalizzato per ogni cliente come allegato ad una mail e salvare i files Pdf creati in apposita directory (va bene anche un unico file);

Procedura: da una maschera di Access apro il file di word "stampa unione" (pulsante con collegamento ipertestuale ?), lo salvo in una cartella predefinita con un nome specifico (esempio: "Nuove scadenze 2017"); completo il testo del file di word; torno in Access e con un pulsante invio le mail ai singoli destinatari con gli allegati PDF.

Tra le altre cose ho provato ad adattare quanto proposto da Maurizio Capannoli nella sua "Stampa unione e VBA: creare PDF e inviarli via email " ma restituisce una serie di errori che non riesco a superare.

Confido nel vostro prezioso aiuto e ringrazio fin da ora.

Buon week end a tutti.

Andrea Lucca

Microsoft 365 e Office | Access | Per la casa | Windows

Domanda bloccata. Questa domanda è stata eseguita dalla community del supporto tecnico Microsoft. È possibile votare se è utile, ma non è possibile aggiungere commenti o risposte o seguire la domanda.

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2017-03-02T20:10:16+00:00

ciao Andrea,

se non ci mostri la modifica alla routine come facciamo...? :-)

prova come segue :

      CreateEmailWithOutlook Rs.Fields("Mail"), strsubject, strMessaggio, strFile, CStr(Rs.Fields("ID_clienti"))

passa alla routine che crea l'email l'idcliente.

e modifica come segue la routine CreateEmailWithOutlook  ( in grassetto le modifiche) :

Option Compare Database

    Option Explicit

    Private outLookIstance As Object 'Outlook.Application

    Private Const strPathDichiarazione  As String = "E:\tuoPathSecondoFilePdfDaAllegare" '<<<< personalizzare

Public Function CreateEmailWithOutlook( _

    ByVal MessageTo As String, _

    ByVal Subject As String, _

    ByVal MessageBody As String, _

    ByVal strFile As String, _

    ByVal strID As String)

    ' Define app variable and get Outlook using the "New" keyword

    Dim olMailItem As Object ' Outlook.MailItem  ' An Outlook Mail item

Dim strSecondAtt As String

    ' Create a new email object

        newOlIstance

        Set olMailItem = outLookIstance.CreateItem(0)

    ' Add the To/Subject/Body to the message and display the message

        With olMailItem

            .To = MessageTo

            .Subject = Subject

            .Body = MessageBody

            .Display    ' To show the email message to the user

            .attachments.Add strFile

             strSecondAtt = strPathDichiarazione & "2016" & strID & ".pdf"

If fileExists(strSecondAtt) Then

.attachments.Add strSecondAtt

End If

        End With

        emailFocus2 Subject

    ' Release all object variables

    Set olMailItem = Nothing

End Function

e aggiungi questa funzione che controlla se il file esiste.

Private Function fileExists(ByVal strFile As String) As Boolean

On Error Resume Next

fileExists = (GetAttr(strFile) And vbDirectory) = 0

End Function

se esiste lo alleghi altrimenti no.

la modalità di creazione del strSecondAtt è brutta perché ho preso come riferimento la costante 2016 per l'anno 2016...le costanti sono il male come dicono i veri developers (io faccio mia questa loro indicazione) se devi allegare file dell'anno corrente meglio qualcosa del tipo :

strSecondAtt = strPathDichiarazione & format$(vba.date,"yyyy") & strID & ".pdf"

se invece la scelta dell'anno dovesse dipendere da altro si può ragionare diversamente....

Facci sapere.

ciao, Sandro.

La risposta è stata utile?

0 commenti Nessun commento
Risposta accettata dall'autore della domanda
Anonimo
2017-01-14T13:51:38+00:00

ciao Andrea,

[...]

Ti ringrazio per il complimento circa la pazienza e la buona volontà ! E' vero, quelle non mi mancano, purtroppo mi manca la conoscenza delle basi, in particolare ho una spiccatissima ed innata avversione per i cicli !!!!!

[...]

:-)

[...]

  • non tiene conto della condizione "clienti.invio = true";

[...]

secondo me si invece.

[...]

  • non cicla il recordset ma si limita a creare il Pdf solo per il cliente selezionato !!!;

[...]

per come lo hai impostato devi ciclare il recordsetclone della form visto i parametri passati, ma forse ti è più facile utilizzare il recordset creato ad hoc, passando il campo del recorset, nel codice qui sotto capirai perché

[...]

  • a livello di invio mail non trova l'allegato; temo poi che se anche lo trovasse, così come strutturato, il codice non sarebbe in grado di allegare a ciascun cliente il proprio messaggio personalizzato.

In buona sostanza UNA SCHIFEZZA, anche se spero che tu apprezzi almeno un po' lo sforzo profuso !

[...]

no secondo me no, la logica è giusta e ti sei fermato ad un passo dalla meta.

non trovi l'allegato perché non passi il path correttamente.

[...]

  • ogni volta che faccio un invio accodo in una tabella i campi data, ID cliente, oggetto e path dell'invio fatto;
  • creo una maschera basata su quella tabella che mi permetta di cercare con l'ID cliente oppure con la data oppure con l'oggetto gli invii effettuati.

Ho capito bene ?

[...]

si è esattamente quello che intendo che ti lascio sviluppare in autonomia,

Ovvia che se hai qualche difficoltà siamo qua.

Ti lascio la routine modificata che salva il doc in pdf e crea l'email.

Mi sono limitato a nominare "scolasticamente" il nome del file in pdf con il nome del cliente.

Non vedrei male nominare il file con data in formato americano concatenando nome cliente o suo id, tanto poi con la form basata sulla tabella di cui alla parte che devi sviluppare se serve il file lo individui facilmente.

Ricordati nell'automazione di word di chiudere l'istanza aperta e di distruggere le variabili oggetto, non sempre access fa il suo dovere ( con l'istanza la distruzione deve essere esplicita) nel resettare tutto a fine routine quindi diamogli una mano :-)

L'idea di utilizzare una funzione esterna per la gestione dei bookmarks è buona, non l'ho seguita perché a mio avviso il codice appare ordinato e lineare anche popolando i bookmarks nella routine esistente.

Personalizza il nome dei controlli....comando15...! ed inserisci una gestione errori.

prova la routine che segue :

Private Sub Comando15_Click()

    Dim Rs As DAO.Recordset

    Set Rs = CurrentDb.OpenRecordset("SELECT * FROM clienti WHERE clienti.invio = True ", dbOpenDynaset)

    Dim Wrd As Object, Doc As Object

    Dim Modello As String, NomeFile As String, i As Integer

    Dim Record As String, sql As String

    Dim PercorsoFile As String

    Dim PercorsoPdf As String

    Dim strMessaggio As String

    Dim strsubject As String

     PercorsoFile = "\DS1515PLUS\DatiAziendali\stampa unione"

     PercorsoPdf = "\DS1515PLUS\DatiAziendali\stampa unione\stampe pdf"

     NomeFile = "stampa unione modello demo.dotx"

     NomeDocWord = PercorsoFile & NomeFile

     'NomePDF = PercorsoPdf & Trim(Me.Nome) & "prova.pdf"

     strsubject = "Comunicazione"

     'strFile = PercorsoPdf

     On Error Resume Next

     Set Wrd = GetObject(, "Word.Application")

        If Err.Number = 429 Then

            Set Wrd = CreateObject("Word.Application")

        End If

     On Error GoTo 0

     On Error GoTo errHandler

     Wrd.Visible = False

     'Wrd.Activate

     'ReplSel = Wrd.Options.ReplaceSelection

     'Wrd.Options.ReplaceSelection = True

     Do Until Rs.EOF

            Set Doc = Wrd.Documents.Add(NomeDocWord)

            'Doc.Activate

            strMessaggio = "Gentile " & Rs.Fields("Nome") & vbNewLine

            With Doc.bookmarks

                .Item("nome").Range.Text = Rs.Fields("Nome")

                .Item("indirizzo").Range.Text = Rs.Fields("Indirizzo")

                .Item("frazione").Range.Text = Rs.Fields("Frazione")

                .Item("cap").Range.Text = Rs.Fields("Cap")

                .Item("città").Range.Text = Rs.Fields("Città")

                .Item("mail").Range.Text = Rs.Fields("Mail")

             End With

             strFile = PercorsoPdf & Rs.Fields("nome")

             With Doc

                .saveas FileName:=strFile, _

                        FileFormat:=17   ' wdFormatPDF

                .Close SaveChanges:=False

            End With

            strMessaggio = strMessaggio & "In allegato trasmettiamo la comunicazione in oggetto." & vbNewLine & "Distinti saluti" & vbNewLine & "Studio Pinco pallino."

            CreateEmailWithOutlook Rs.Fields("Mail"), strsubject, strMessaggio, strFile & ".pdf"

            Rs.MoveNext

       Loop

     'Call StampaBookmark(Doc, Wrd, "nome", Me.Nome)

     'Call StampaBookmark(Doc, Wrd, "indirizzo", Me.Indirizzo)

     'Call StampaBookmark(Doc, Wrd, "frazione", Me.Frazione)

     'Call StampaBookmark(Doc, Wrd, "cap", Me.Cap)

     'Call StampaBookmark(Doc, Wrd, "città", Me.Città)

     'Call StampaBookmark(Doc, Wrd, "mail", Me.Mail)

ExiterrorHandler:

    Rs.Close

    Set Rs = Nothing

    Set Doc = Nothing

    Wrd.Quit

    Set Wrd = Nothing

    Exit Sub

errHandler:

  With Err

        MsgBox "ERR#" & .Number _

             & vbNewLine & .Description _

             , vbOKOnly Or vbCritical

  End With

  Resume ExiterrorHandler

End Sub

Ciao, Sandro.

La risposta è stata utile?

0 commenti Nessun commento

70 risposte aggiuntive

Ordina per: Meno recente
  1. Anonimo
    2017-01-13T12:53:28+00:00

    ciao Andrea,

    la generazione di un file di word con automazione da un modello è realizzabile, come il suo salvataggio in PDF ed invio email, ma non ho presente la proposta del signore che citi nel tuo post.

    Prova a mostrare quanto sei stato in grado di mettere assieme e poi ragioniamo sulla messa a punto.

    Magari con una demo, così da provare sul campo il tutto.

    Ciao!

    Sandro.

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2017-01-13T16:09:29+00:00

    Ciao e buon pomeriggio Sandro.

    In realtà non ho ancora costruito il database ma ho provato ad adattare i vari esempi che ho trovato in rete, senza successo: mi sento un vero catrame !!!!!

    Comunque l'esempio citato da me stamani lo trovi al seguente link:

    http://www.c2czip.com/mau/vba/88-stampa-unione-invio-pdf-via-email

    L'ho adattato ad un file di Word con origine dati una tabella di Access ma, eseguendo la macro da Word mi restituisce l'errore "Il membro richiesto dall'insieme non esiste" e il debug evidenzia:

    DocName = "Lettera_" & .DataFields("nome").Value & ".pdf"

    In effetti ho notato che nel codice "DocName" non è stato definito: ho scritto un'eresia ?

    Ho poi provato ad adattare un codice (scritto grazie al vostro aiuto) che serve per creare da una maschera di Access dei file Pdf per il singolo cliente, utilizzando i campi presenti nella tabella ma il risultato è che crea un singolo file Pdf e non tanti quanti sono i records della tabella: la mia cronica avversione verso i cicli è una presenza costante purtroppo.

    Se vuoi una demo di Access la creo ma non so come fare ad allegare anche il file di Word con la stampa unione.

    Grazie per la pazienza

    Andrea Lucca

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2017-01-13T16:16:01+00:00

    Ciao Andrea,

    potresti, al posto del documento Word, utilizzare una report Access?

    Mimmo

    La risposta è stata utile?

    0 commenti Nessun commento