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-16T20:24:59+00:00

    ciao Andrea,

    mi sfugge il linchetto non so che cosa sia.. :-(.

    [...]

    • ad un certo punto il comando funzionava correttamente senza errori (unico problema che inviava una sola mail anche se i clienti selezionati erano più di uno);

    [...]

    la routine genera una mail per ogni cliente selezionato con invio=spuntato o vero e deve funzionare così'.

    semmai serve forzare il salvataggio del record post selezione ma è un dettaglio che vediamo in un secondo momento.

    per questo punto :

    [...]

    ho provato con quanto mi hai suggerito e l'errore lo da su

    With Err

    MsgBox "ERR#" & .Number _

    & vbNewLine & .Description _

    , vbOKOnly Or vbCritical

    [...]

    dopo avere impostato il punto di interruzione devi eseguire passo - passo la routine con F8.

    In caso di errore il codice si sposta immediatamente alla gestione errori, la riga che mi hai segnalato, però mi devi dire quale è la riga che genera l'errore seguendo passo - passo la routine, altrimenti non capisco cosa non va.

    intendo dire la riga precedente al quella che mi hai segnalato tu, with err...ect...

    Attendo news.

    [...]

    Scusami di nuovo, grazie.

    Andrea Lucca

    nessuna ragione di scusarsi :-) evidentemente qualcosa sfugge, magari di molto banale...

    ciao, Sandro.

    La risposta è stata utile?

    0 commenti Nessun commento
  2. Anonimo
    2017-01-17T09:47:01+00:00

    Buongiorno e scusa ma non avevo capito per bene la procedura.

    Subito dopo aver digitato F8 su quanto segue:

    .saveas FileName:=strfile, _

    FileFormat:=17   ' wdFormatPDF

    si sposta sulla gestione errori.

    Ciao e grazie

    Andrea Lucca

    PS

    Il linchetto è un folletto presente nella tradizione popolare della provincia di Lucca, sia in Lucchesia, che in Versilia, che in Garfagnana.

    Secondo il Vocabolario lucchese di Idelfonso Nieri, il linchetto è uno spirito non cattivo ma dispettoso, che va di notte, entra per le camere, scopre le persone, sconvolge, tramuta gli oggetti che ci sono e sghignazza delle burle che fa. Il nome deriverebbe dal latino incubus con agglutinazione dell'articolo, attraverso le forme lincubetto, lincuetto ^[1]^. Secondo l'italianista Felice Del Beccaro, infatti, il linchetto sarebbe un relitto del dio silvestre Fauno che nel suo aspetto di Incubus spaventava la gente e tormentava gli uomini con sogni cattivi e apparizioni^[2]^

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2017-01-17T10:26:19+00:00

    ciao Andrea,

    forte il linchetto :-).

    Buongiorno e scusa ma non avevo capito per bene la procedura.

    Subito dopo aver digitato F8 su quanto segue:

    .saveas FileName:=strfile, _

    FileFormat:=17   ' wdFormatPDF

    [...]

    bene ora hai assimilato uno dei modi più pratici per debuggare il codice VBA se non altro...

    ricordatene la prossima volta che ottieni un errore...punto di interruzione e segui il codice passo passo per vedere dove si blocca.

    Ovviamente il debugging non si ferma qui, ma intanto questo è un buon inizio.

    Per il tuo problema...vediamo questo.

    Parliamo per caso di office 2007 per quanto alla tua versione?

    non è che per caso ti manca il componente aggiuntivo per salvare il pdf?

    Salvi in pdf un file di word direttamente da word?

    Se no vedi qui, https://www.microsoft.com/it-it/download/details.aspx?id=7.

    [...]

    Ciao e grazie

    Andrea Lucca

    Facci sapere!

    Ciao, Sandro.

    La risposta è stata utile?

    0 commenti Nessun commento