Fondamentalmente la stampa unione in Word è piuttosto semplice: Serve 1) un’origine dati (una tabella) le cui intestazioni di colonna diventeranno i “segnalibri” da inserire in word e 2) un bel foglio word ben costruito dove scriveremo tutte le parti fisse come siamo soliti fare e le parti variabili invece saranno popolate tramite i campi della tabella.
Dunque nulla di particolarmente complesso. Preparerò a breve un tutorial video poiché “vedere” è più facile che leggere. Talvolta.
Nella Macro di Word di cui vi ho illustrato le proprietà nel post precedente prendono vita due diverse funzioni. La prima si occupa di creare uno o pià documenti partendo dal template word e salvarli in una collocazione a scelta, con un nome facilmente intelligibile. La seconda invece si occupa della spedizione vera e propria della email e dell’allegato.
Il codice, sebbene non sia né semplice né breve, in realtà può essere facilmente “sezionato” e adattato alle più varie esigenze. Ovviamente può essere anche facilmente riutilizzato.
Dim objEmail, objConf, objFlds, vrtSelectedItem, selectedpath, MainDoc, msConfigURL Dim messaggio, SoggettoEmail, PDFallegato, mailServer, mailusername, mailpassword, mailto, MailSubject, mailBody, SMTPport, DocName, EmailAddress As String Dim i As Integer, fd As FileDialog Const cdoSendUsingPort = 2 ' usa SMTP per l'invio Const cdoBasicAuth = 1 ' autenticazione clear text Const cdoTimeout = 60 ' Timeout SMTP in secondi msConfigURL = "http://schemas.microsoft.com/cdo/configuration"
Fin qui nulla di che: le variabili, le costanti e gli oggetti vanno dichiarati e, dove serve, commentati.
'-------------configura qui i parametri di autenticazione e di invio--------------------
' indirizzo server SMTP
mailServer = "smtp.gmail.com"
' Porta SMTP
SMTPport = 465 '25 o 465
' Indorizzo email per il login
mailusername = "This email address is being protected from spambots. You need JavaScript enabled to view it."
'password per il login
mailpassword = "latuapassword"
Anche qui nulla di difficile: una volta dichiarate variabili e costanti nella parte precedente, assegniamo i valori che verranno utilizzati nel codice successivo. In questo modo tutto risulterà più leggibile e “riutilizzabile/riconfigurabile”.
'inizia procedura per la selezione della cartella di destinazione Set fd = Application.FileDialog(msoFileDialogFolderPicker) With fd 'Usa il metodo Show per mostrare la finestra di dialogo e restituire l'azione dell'utente If .Show = -1 Then For Each vrtSelectedItem In .SelectedItems 'vrtSelectedItem è una stringa che contiene l'indirizzo di ogni elemento selezionato. 'E' possibile usare qualsiasi funzione di I/O sui file utilizzando questo indirizzo. selectedpath = vrtSelectedItem Next vrtSelectedItem Else MsgBox ("Nessuna cartella è stata selezionata.") Exit Sub End If End With
In questa parte viene avviata una procedura che in sostanza vi chiede: “dove vuoi che inserisca i documenti PDF che creerò più tardi?”. La risposta sarà inserita nella variabile selectedpath.
'-----------prepara il documento Application.ScreenUpdating = False MainDoc = ActiveDocument.Name ChangeFileOpenDirectory selectedpath
Qui ci limitiamo a dare qualche dritta a Word: non farmi vedere i documenti a schermo quando li crei, il template da utilizzare è quello aperto in word ora, la directory di salvataggio è selectedpath.
A questo punta inizia una lunga routine che viene ripetuta tante volte quanti sono gli indirizzi email che abbiamo nell’origine dati: esattamente ActiveDocument.MailMerge.DataSource.RecordCount volte:
'inizia la routine di creazione e invio per ogni singolo indirizzo email in tabella For i = 1 To ActiveDocument.MailMerge.DataSource.RecordCount 'instanzio l'oggetto item per l'email With ActiveDocument.MailMerge .Destination = wdSendToNewDocument .SuppressBlankLines = True With .DataSource .FirstRecord = i .LastRecord = i .ActiveRecord = i
A questo punto viene la parte davvero importante:
'Utilizza alcuni campi del file sorgente per impostare il nome del file pdf 'IMPORTANTE: tali campi vanno personalizzati in base a quelli effettivamente 'presenti nella sorgente dati '-----attenti alle righe seguenti: nel database DEVE essere presente il campo denominato "nome e cognome"---- '-----ed inoltre un campo denominato "email"------- DocName = "Lettera_" & .DataFields("nome_e_cognome").Value & ".pdf" EmailAddress = .DataFields("email").Value ' prendiamo il percorso completo del file da allegare PDFallegato = selectedpath & "\" & DocName '----attenti a questa riga: personalizzate a piacimento il messaggio, inteso come corpo del testo------- messaggio = "Gentilissimo " & .DataFields("nome_e_cognome").Value & " Le inviamo in allegato la certificazione di partecipazione al convegno." '----attenti a questa riga: qui mettete l'oggetto del vostro messaggio email----- SoggettoEmail = "Invio certificato di partecipazione al convegno" End With
In questa parte alcuni dei dati contenuti in tabella “dialogano” con il codice. Dunque il nome dei campi (le intestazioni di colonna dell’origine dati excel) DEVONO combaciare ESATTAMENTE. Se il Sig. Mario Rossi è inserito nella colonna nome_e_cognome (notare gli underscore… non eliminiamoli per favore!) la variabile dovrà portare lo stesso nome. Il campo email? stessa sorte! Non me lo fate ripetere…
Ovviamente dovrete adattare le diverse righe di codice alle vostre necessità. Ricordate che le varibili di testo (stringa) vanno inserite SEMPRE tra doppi apici. Non eliminateli, per favore!
.Execute Pause:=False
Application.ScreenUpdating = False
End With
ActiveDocument.ExportAsFixedFormat OutputFileName:=DocName, _
ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, To:=1, _
item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
ActiveWindow.Close SaveChanges:=False
Questa parte si occupa di avvisare word di non eseguire pause di lavoro, di non generare un’immagine a schermo durante la successiva generazione dei PDF, di creare e salvare il PDF col nome DocName generato con la routine precedente. La parte che segue, sebbene si trovi nella stessa routine (ciclo for/next) è semplicemente tutto ciò che è necessario dell’invio della email e dell’allegato. I parametri indispensabili sono stati già dichiarati all’inizio e dunque:
'---------------invia tramite GMAIL---------------
Set objEmail = CreateObject("CDO.Message")
Set objConf = objEmail.Configuration
Set objFlds = objConf.fields
'configura le impostazioni per l'invio
With objFlds
.item(msConfigURL & "/sendusing") = cdoSendUsingPort
.item(msConfigURL & "/smtpserver") = mailServer
.item(msConfigURL & "/smtpserverport") = SMTPport
.item(msConfigURL & "/smtpusessl") = True
.item(msConfigURL & "/smtpconnectiontimeout") = cdoTimeout
.item(msConfigURL & "/smtpauthenticate") = cdoBasicAuth
.item(msConfigURL & "/sendusername") = mailusername
.item(msConfigURL & "/sendpassword") = mailpassword
.Update
End With
'invia il messaggio e l'allegato
objEmail.To = EmailAddress
objEmail.From = mailusername
objEmail.Subject = SoggettoEmail
objEmail.TextBody = messaggio
objEmail.AddAttachment PDFallegato
objEmail.Send
' se ci sono altri indirizzi in coda riprendi la routine, altrimenti esci dal ciclo
Next i
La procedura utilizza CDO (Collaboration Data Objects), un’interfaccia proprietaria di Microsoft per la messaggistica. La procedura è piuttosto semplice e facile da implementare in altri contesti/progetti.
Spero di esservi stato utile. Un caro saluto a tutti. Qui potete scaricare i file di esempio.