Il blog di Gianni Giaccaglini

Blog su VBA e VSTO
Gianni Giaccaglini

My Links

News

NB - V. anche gli ARTICOLI (in fondo a questa barra)
Solo quesiti validi a: giannigiac@tin.it
Il mio Best seller su VBA
(v. www.hoepli.it)


Il mio ultimo libro su Open XML
(v. www.FAG.it):



La mia nipotina ELISA

Foto con dedica a ME di
Bill Gates giovanissimo
nei mitici anni 80!

Categorie Post

Categorie Articoli

Archivio

Immagini

Blog Stats

martedì 20 dicembre 2011 #

Spedire circolari Outlook da indirizzari Excel

Spedire circolari Outlook da indirizzari Excel

La tecnologia OLE Automation , detta anche sinteticamente Automation, permette proficui dialoghi fra applicativi. Si tratta di un sistema Client/Server dove il primo (Client) richiama la libreria del secondo (Server) utilizzandone proprietà e metodi.

Il codice macro che propongo deriva da una soluzione più completa dovuta a un mio corrispondente conosciuto tramite ShareOffice. Trattasi – onore al merito! – di Ettore Caliendo che tra l’altro sfrutta una caratteristica non a tutti ben nota: il formato HTML per il messaggio Outlook. Di conseguenza si può inglobare nel messaggio un’immagine, il logo della ditta nella fattispecie, mediante il tag (evidenziato in giallo, insieme ad altre particolarità, nella macro qui sotto riportata).

Il predetto Ettore all’inizio mi aveva palesato una perplessità, dovuta al fatto che tale logo non perveniva ai suoi corrispondenti. Per non sapere né leggere né scrivere (in tema di messaggi Outlook in formato HTML, lo confesso...)  tuttavia gli ho subito detto: dovresti inserirla su un sito web, altrimenti come potrebbero gli estranei vedere la figura che risiede sul TUO PC?.

Compresa l’antifona, il rimedio è stato provato e andato in porto, con reciproca soddisfazione. Ed ecco, a beneficio delle masse, una Sub mutuata dal sullodato Ettore e un po' semplificata che va incorporata in un opportuno archivio Excel, tipo MessOutlook.xls, o MessOutlook.xlsm con Office 2010. Ho pensato di corredarla di due argomenti, il Cliente e l’IndirEmail di chiara semantica:

------------------

 

Sub MessHTML(Cliente As String, IndirEmail As String)

  Dim Corpo As String

  Dim Outlk As New Outlook.Application ' Early binding

  Dim MioMess As Outlook.MailItem

  Set MioMess = Outlk.CreateItem(olMailItem)

  Corpo = "<html><body><p>"

  Corpo = Corpo & "<img border='0'  src='http://www.elicasrl.eu/loghi/logo_Elica.bmp'>&nbsp;&nbsp;&nbsp;&nbsp;"

  Corpo = Corpo & "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"

  Corpo = Corpo & "<img border='0' src='http://www.elicasrl.eu/loghi/logo_Crif.bmp' ></p>"

  Corpo = Corpo & "<p><font face='Tahoma' size='4'>Gentilissimo/a " & Cliente & ",<br>"

  Corpo = Corpo & "la presente per richiederLe quanto segue: <br><br><br>"

  Corpo = Corpo & "<br><br>"

  Corpo = Corpo & "RingraziandoLa anticipatamente, Le porgiamo distinti saluti.<br><br>"

  Corpo = Corpo & "&nbsp; &nbsp; &nbsp; Elica srl<br>"

  Corpo = Corpo & "&nbsp; Rossi Asdrubale <br><br><br>"

  Corpo = Corpo & "-------------------------------------------------------------------------<br>"

  Corpo = Corpo & "TRAFFICI VARI srl<br>"

  Corpo = Corpo & "Via Sette bellezze n. 103<br>"

  Corpo = Corpo & "00123 Roma (RM)<br>"

  Corpo = Corpo & "e-mail: settebell@gmail.it<br>"

  Corpo = Corpo & "Tel. ******<br>"

  Corpo = Corpo & "Fax  ******<br>"

  Corpo = Corpo & "web: www.settebell.com<br>"

  Corpo = Corpo & "</font></p>"

  Corpo = Corpo & "</body>"

  With MioMess

    .Subject = "Richiesta chiarimenti"

    .Bcc = "pallino.pinco@lib.it"

    .To = IndirEmail

    .HTMLBody = Corpo

  End With

  MioMess.Send ' Invia il messaggio

  ' Libera le variabili “pesanti”:

  Set MioMess = Nothing

  Set Outlk = Nothing

End Sub

 

 

------------------ 

A ignari & immemori comincio col ricordare che per funzionare Automation chiede che nell'Editor VBA si fissino i riferimenti opportuni, mediante il comando Strumenti > Riferimenti... scegliendo poi Microsoft Outlook 12 Object Library nel nostro caso (diventa Outlook 14 con Office 2010).

Qui vale la pena di fare un paio di osservazioni. La prima è l’utilizzo della sintassi As New Outlook.Application, che al pregio della sinteticità unisce quello di fornire il cosiddetto Early Binding (associazione immediata) contrapposto al Late Binding (associazione tardiva) offerto invece dalla classica istruzione utilizzata dal nostro amico:

Outlk = CreateObject(“Outlook.Application”)

Nel qual caso la variabile è del tipo generale Object, con due conseguenze: maggior lentezza e segnalazione di errori solo a run-time, unita alla mancanza dell’intellisense. Infatti solo con l’early binding accanto al punto (.) della variabile Outlk spuntano, comodamente, cose come .Subject (l’oggetto del messaggio), .Bcc (il corrispondente in “carbon copy”, che può convenire assumere come il proprio email, per un riscontro, ovviamente al posto del comico e fantomatico pallino.pinco@lib.it!), .To IndirEmail (l’email del destinatario) e .HTMLBody = Corpo (il “corpo” del messaggio in formato HTML).

La seconda osservazione è il fatto che il buon Ettore ha impostato i riferimenti non a Microsoft Outlook bensì a Microsoft Office 12 (o 14 nell’edizione 2010), con un certo mio stupore! A caldo penso che questa sia più generale, ergo più “pesante” di quella che userebbe il sottoscritto. Ma non ne sono sicuro.

Nota. Posso però testimoniare che, in un’altra circostanza – Automation di Word – la libreria MS Office NON presentava una certa proprietà... Misteri dell’OLE Automation...

 

Tornando al testo del messaggio, a parte la sua genericità, che travalica il più squallido umorismo, esso dovrebbe essere chiaro a chiunque mastica il linguaggio HTML, faccio solo notare che con il concatenamento Gentilissimo & Cliente si ottiene l’inserimento del nome del destinatario nel corpo del messaggio stesso.

A questo punto, fatte le debite personalizzazioni, gl’interessati possono testare la predetta routine con un’istruzione del tipo seguente:

  MessHTML "Michele Topo", topolino@disney.com

 

Più vantaggiosamente si può pensare a una serie di nominativi sul foglio Excel affiancati dai rispettivi indirizzi di posta elettronica:

Matteo Evangelista

matteoevang@gmail.com

Giovanni Telegrafista

giovantelegrafist@tin.it

 

Eccetera.

Immaginando, per estrema semplicità che i due dati siano collocati nelle colonne A e B a partire da A1, si potrebbe ricorrere alla procedura dell’evento BeforeDoubleClick:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)

  If Target.Column <> 1 Or Target.Value = "" Then

    Cancel = True ' Annulla il minieditor della cella

    Exit Sub

  End If

  MessHTML Target.Value, Target.Offset(0, 1).Value

  Cancel = True ' Annulla il minieditor della cella

End Sub

Che sul doppio click in una cella non vuota in colonna A lancia il massaggio Outlook a quel dato soggetto.

Nota ultimissima. In altri mondo OLE Automation si ha la proprietà Visible, che va impostata a True se si vuole che Excel o Word siano visualizzati, altrimenti agiscono nell’ombra.  Nel caso Outlook Visible non esiste proprio. Poco male, perché l’applicativo può, indifferentemente, agire in background o allo scoperto, qualora fosse già aperto sulla nostra scrivania.

 

Mi fermo qui suggerendo agl’interessati altri esperimenti, in particolare un’applicazione di circolari più o meno standard, nel qual caso un opportuno ciclo del tipo For Each Nome In Indirizzario... Next sarà al centro del lavoretto o lavorone che ciascuno saprà implementare.

Ultim’ora: un’altra possibilità, anzi due

Questa variante mi è venuta in mente nel metrò (giuro). Consiste nell’uso della sintassi ; ; ... della casella A: (oppure Cc: o Ccn) che ha il vantaggio di registrare in Outlook un’unica missiva a più corrispondenti. Ed ecco la ricetta, che comprende due varianti. La prima consiste nel limitarsi al solo argomento IndirEmail  della routine in questione:

(questo perché ora non è possibile specificare i singoli nominativi? ma più avanti vedremo che si può)

La seconda variante è un suggerimento, ovvero usare il metodo Save in luogo di Send. In tal modo si rimanda l’invio a tempi successivi, di tipo manuale ma con possibilità di adattamenti e/o ri-usi. Ed ecco il risultato:

Sub MessHTML(IndirEmail As String)

   . . . idem c. s. . . .

  With MioMess
    .Subject = "Richiesta chiarimenti"
    .Bcc = "pallinopinco@lib.it"
    .To = IndirEmail
    .HTMLBody = Corpo
    .Save
  End With
  Set MioMess = Nothing
  Set Outlk = Nothing

End Sub

Ciò premesso, ecco una possibile macro:

Sub Circolare()

  Dim Indirizzi As String, PrimaCellaIndir As Range, i As Integer

  Set PrimaCellaIndir = Range("PrimaCellaIndir")

  Indirizzi = PrimaCellaIndir.Value

  i = 2

  While PrimaCellaIndir(i).Value <> ""

    Indirizzi = Indirizzi & ";" & PrimaCellaIndir(i)

    i = i + 1

  Wend

  MsgBox Indirizzi ' Da usare solo in fase di debug

  MessHTML Indirizzi

End Sub

 

Ritengo che la ricetta parli da sola, dico solo che “PrimaCellaIndir” è il nome affibbiato alla prima cella dell’indirizzario, che sarà un campo in Colonna B o altrove.

E la seconda possibilità appena preannunciata? Dapprima non ci avevo pensato, ma è semplice. Consiste nell’utilizzare entrambi gli argomenti dell’iniziale routine MessHTML, passandole come secondo argomento una stringa di nominativi concatenati, tutti terminanti con
. Bando alle chiacchiere, fornisco la soluzione completa, che parte da una tabella Nomi/indirizzi come già vista:

Mario Zaccariai

mario.zaccaria@gmail.com

Arturo Benedetti

arturbened@libero.it

TreDenari Paolina

treden@info.com

Rossi Michele

rossi.michele@boh.eu

 

La routine, ripetuta per comodità del lettore (ma la parte evidenziata è l’unica modifica):

Sub MessHTML(Cliente, IndirEmail As String)

  Dim Corpo As String

  Dim Outlk As New Outlook.Application

  Dim MioMess As Outlook.MailItem

  Set MioMess = Outlk.CreateItem(olMailItem)

  Corpo = "

"

  Corpo = Corpo & "    "

  Corpo = Corpo & "                      "

  Corpo = Corpo & "

"

  Corpo = Corpo & "

Gentilissimi " & "
" & Cliente
& "
"

  Corpo = Corpo & "la presente per richiederLe quanto segue:


"

  Corpo = Corpo & "

"

  Corpo = Corpo & "RingraziandoLa anticipatamente, Le porgiamo distinti saluti.

"

  Corpo = Corpo & "      Elica srl
"

  Corpo = Corpo & "  Rossi Asdrubale


"

  Corpo = Corpo & "-------------------------------------------------------------------------
"

  Corpo = Corpo & "TRAFFICI VARI srl
"

  Corpo = Corpo & "Via Sette bellezze n. 123
"

  Corpo = Corpo & "00123 Roma (RM)
"

  Corpo = Corpo & "e-mail: settebell@gmail.it
"

  Corpo = Corpo & "Tel. ******
"

  Corpo = Corpo & "Fax  ******
"

  Corpo = Corpo & "web: www.settebell.com
"

  Corpo = Corpo & "

"

  Corpo = Corpo & ""

  With MioMess

    .Subject = "Richiesta chiarimenti"

    .Bcc = "giannigiac@tin.it"

    .To = IndirEmail

    .HTMLBody = Corpo

    MioMess.Save

  End With

  ' MioMess.Send ' Alternativa possibile

  Set MioMess = Nothing

  Set Outlk = Nothing

End Sub

La macro connessa a un opportuno pulsante Activex:

Private Sub CommandButton1_Click()

  Dim ZonaNomi As Range, Iniz As Range

  Set Iniz = Range("InizNomi")

  With Iniz

    Set ZonaNomi = Range(.Cells(1), .End(xlDown))

  End With

  Dim Nomi As String, Indirizzi As String, i As Integer

  Nomi = Iniz.Value & "
"

  Indirizzi = Iniz.Offset(0, 1).Value

  For i = 2 To ZonaNomi.Count

    Nomi = Nomi & ZonaNomi(i).Value & "
"

    Indirizzi = Indirizzi & ";" & ZonaNomi(i).Offset(0, 1).Value

  Next

  MessHTML Cliente:=Nomi, IndirEmail:=Indirizzi

End Sub

 

Meditate il ciclo in giallo, gente e vedrete che funziona.

 

?>

?>

?>

?>

posted @ 10.49 | Feedback (0)