Invio email con body html da codice vba

Anonimo
2023-09-11T10:29:30+00:00

Salve,

Nell'ufficio dove lavoro, settimanalmente c'è la necessità di creare un foglio Excel dove dobbiamo inserire moltissimi dati e in alcune colonne invece dobbiamo importare dei dati da un altro foglio Excel che ci viene fornito ... tutto questo richiede due ore di tempo ...

Ho pensato quindi di automatizzare mediante codice Visual Basic Application

Abbiamo anche l'esigenza di dover inviare una email con allegato il file Excel creato nel cui corpo dobbiamo inserire una tabella riepilogativa

Ovviamente il codice vba che ho scritto
si occupa anche di creare l'email con il body html in cui inserisce automaticamente la tabella riepilogativa

Il problema è che usando il metodo "send" dell'oggetto "olmail" tutto il corpo dell'email viene inviato correttamente

Invece se utilizzo il metodo display (anteprima di outlook) la tabella riepilogativa perde la formattazione prestabilita

Qualcuno sa darmi qualche dritta per aggirare questo problema?

Ringrazio anticipatamente

Microsoft 365 e Office | Excel | Per il lavoro | Android

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

7 risposte

Ordina per: Più utili
  1. Anonimo
    2023-09-14T10:34:05+00:00

    Ciao Federico,

    Prima di tutto la ringrazio per la sua tempestiva risposta al mio quesito,

    Dunque, posto di seguito il codice (VBA) di invio email ma credo che sia del tutto inutile in quanto si tratta di una procedura standard ( una sub per intenderci) alla quale passo come parametri l'oggetto dell'email, i destinatari per competenza e conoscenza, il percorso completo del file Excel da allegare, la stringa del body dell'email ecc. ecc. ...

    Public Sub SendEMail(ByVal strHTMLMailBody As String, ByVal strEMailAddressees As String, ByVal strEMailAttachment As String, bla bla bla ... )

    Dim objOutlookApp As Object

    Dim objMail As Object

    Set objOutlookApp = CreateObject("Outlook.Application")

    Set objMail = objOutlookApp.CreateItem(olMailItem)

    With objMail

    .To = strEMailAddressees

    .Subject = "Test invio email"

    .Attachments.Add (strEMailAttachment)

    .BodyFormat = olFormatHTML

    .HTMLBody = strHTMLMailBody

    ...

    bla .. bla ..bla ... bla ...

    ...

    .Display

    ' .Send

    End With

    End Sub

    Infatti il mio problema non è l'invio dell'email che viene inviata correttamente ma è la formattazione della tabella riepilogativa nel body dell'email che Outlook altera se utilizzo il metodo display, per esempio l'head della tabella perde il colore dello sfondo impostato (background-color) gli attributi dei bordi non sono quelli che ho impostato ecc. ecc.

    Il body dell'email non è altro che il testo del codice HTML , questo contiene delle variabili di riferimento che per il codice HTML non sono null'altro che testo e che in breve vado a rimpiazzare tramite la funzione Replace di VBA con i valori da includere nella tabella riepilogativa; la sostituzione la eseguo fuori dalla Sub SendEMail(), a questa gli passo come parametro il testo html completo di tutti i valori ...

    Il testo HTM del body dell'email è memorizzato in una cella Excel

    Se dunque nella Sub SendEMail() uso direttamente il metodo .send e non uso il metodo .display la tabella riepilogativa nel body viene inviata correttamente se invece utilizzo il metodo display (quindi l'invio dovrà essere comandato manualmente nell'anteprima dell'email) la tabella riepilogativa subisce un'alterazione,

    Che la causa sia outlook ((della suite Microsoft Office 2021 Professional plus) è evidente ...

    Purtroppo in ufficio utilizziamo outlook per le emails e comunque l'anteprima dell'email è necessaria perché di volta in volta capita di dover aggiungere nel body dell'email qualche breve nota del caso

    Sfortunatamente, non hai incluso né un esempio dei tuoi dati né il codice che usi per passare l'intervallo HTML alla tua funzione.

    Per testare il tuo codice sarà necessario pubblicare tutto il codice rilevante e fornire dei dati di esempio.

    In attesa di un file, privo di dati sensibili, il tipo di codice che solitamente utilizzo è:

    '========>>

    Option Explicit

    '-------->>

    Public Sub Tester()

    Dim WB As Workbook 
    
    Dim SH As Worksheet 
    
    Dim Rng As Range 
    
    Const sFoglio As String = **"Foglio1"                                                             '<<=== Modifica** 
    
    Const sIntervallo As String = **"A1:A24"                                                         '<<=== Modifica** 
    
    Const sDestinatario As String = **"pippoCHIOCCIOLAgmail.com"               '<<=== Modifica** 
    
    Const sOggetto As String = **"Esempio\_Mail\_HTML"                                    '<<=== Modifica** 
    
    Set WB = ThisWorkbook 
    
    Set SH = WB.Sheets(sFoglio) 
    
    Set Rng = SH.Range(sIntervallo) 
    
    Call Invia\_Mail\_HTML(Rng, sDestinatario, sOggetto) 
    

    End Sub

    '-------->>

    Public Sub Invia_Mail_HTML(oRng As Range, sRecipient As String, sSubject As String)

    Dim oOutlook As Object 
    
    Dim oMail As Object 
    
    With Application 
    
        .EnableEvents = False 
    
        .ScreenUpdating = False 
    
    End With 
    
    Set oOutlook = CreateObject("Outlook.Application") 
    
    Set oMail = oOutlook.CreateItem(0) 
    
    On Error Resume Next 
    
    With oMail 
    
        .To = sRecipient 
    
        .CC = "" 
    
        .BCC = "" 
    
        .Subject = sSubject 
    
        .HTMLBody = RangetoHTML(oRng) 
    
        .Display  '\\ .Send 
    
    End With 
    
    On Error GoTo 0 
    
    With Application 
    
        .EnableEvents = True 
    
        .ScreenUpdating = True 
    
    End With 
    
    Set oMail = Nothing 
    
    Set oOutlook = Nothing 
    

    End Sub

    '--------->>

    Public Function RangetoHTML(Rng As Range)

    Dim fso As Object 
    
    Dim ts As Object 
    
    Dim TempFile As String 
    
    Dim TempWB As Workbook 
    
    TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm" 
    
    'Copy the range and create a new workbook to past the data in 
    
    Rng.Copy 
    
    Set TempWB = Workbooks.Add(1) 
    
    With TempWB.Sheets(1) 
    
        .Cells(1).PasteSpecial Paste:=8 
    
        .Cells(1).PasteSpecial xlPasteValues, , False, False 
    
        .Cells(1).PasteSpecial xlPasteFormats, , False, False 
    
        .Cells(1).Select 
    
        Application.CutCopyMode = False 
    
        On Error Resume Next 
    
        .DrawingObjects.Visible = True 
    
        .DrawingObjects.Delete 
    
        On Error GoTo 0 
    
    End With 
    
    'Publish the sheet to a htm file 
    
    With TempWB.PublishObjects.Add( \_ 
    
         SourceType:=xlSourceRange, \_ 
    
         FileName:=TempFile, \_ 
    
         Sheet:=TempWB.Sheets(1).Name, \_ 
    
         Source:=TempWB.Sheets(1).UsedRange.Address, \_ 
    
         HtmlType:=xlHtmlStatic) 
    
        .Publish (True) 
    
    End With 
    
    'Read all data from the htm file into RangetoHTML 
    
    Set fso = CreateObject("Scripting.FileSystemObject") 
    
    Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2) 
    
    RangetoHTML = ts.readall 
    
    ts.Close 
    
    RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", \_ 
    
                          "align=left x:publishsource=") 
    
    'Close TempWB 
    
    TempWB.Close savechanges:=False 
    
    'Delete the htm file we used in this function 
    
    Kill TempFile 
    
    Set ts = Nothing 
    
    Set fso = Nothing 
    
    Set TempWB = Nothing 
    

    End Function

    '<<========

    Eseguendo questo codice con un semplice file di prova, io ottengo un anteprima dell'email del seguente genere:

      [![Immagine](https://learn-attachment.microsoft.com/api/attachments/c685483a-31ed-45f0-a96b-b3c78c3cc33e?platform=QnA "filestore.community.support.microsoft.com")
    

    .

    ===

    Regards,

    Norman

    Immagine

    La risposta è stata utile?

    1 persona ha trovato utile questa risposta.
    0 commenti Nessun commento
  2. Anonimo
    2023-09-14T14:35:44+00:00

    Ho fatto molte verifiche e la colpa è di Microsoft Outlook, l'anteprima dell'email altera lo stile della tabella e evidentemente invia il body dell'email esattamente come mostrato in anteprima ecco perché il problema si presenta utilizzando il metodo Display dell'oggetto objEMail

    Non è neanche un problema del codice HTML perché se lo copio inserendolo in Notepad e lo salvo con estensione html la tabella riepilogativa viene visualizzata da Microsoft Edge correttamente come prestabilito

    Il metodo Send dell'oggetto objEMail che non passa attraverso l'anteprima di Outlook invia la tabella riepilogativa direttamente e esattamente come prestabilito ecco perché con il metodo Send il problema estetico non si presenta

    Ho fatto un'ulteriore prova per accertarmi che è l'anteprima di Outlook è la causa .. ho verificato che aprendo l'email in outlook inviata direttamente con il metodo send la tabella nuovamente risulta alterata ...

    Domanda : PERCHE' ?

    La risposta è stata utile?

    0 commenti Nessun commento
  3. Anonimo
    2023-09-14T14:20:02+00:00

    La ringrazio per il codice che mi ha postato ma non ho problemi ad inviare email da codice vba, anzi il codice che ho scritto funziona perfettamente e comunque è molto più complesso di quanto lei possa immaginare, considera che è un file Excel (appunto un Workbook) che contiene un modulo VBA (con circa 700 righe di codice VBA) + tre moduli di classe + tre Window procedure che gestiscono gli eventi di tre Window (form);

    Il predetto file Excel contiene lo Sheet vero e proprio in cui vengono inseriti dei dati manualmente (mediamente 350/400 righe di dati) e in funzione di questi dati vengono importati altri dati in tre colonne dello Sheet stesso che ci vengono forniti dall'azienda per cui lavoro (la procedura d'importazione è indipendente dal layout dell'origine dei dati da importare ...)

    Poi sono presenti altri Sheets nascosti che contengono dati "interni" utilizzati dal codice VBA e tra questi anche lo Sheet che contiene appunto il body html dell'email che non deve essere modificato per nessun motivo, l'inserimento dei dati per la tabella riepilogativa avviene iniettando il codice HTML in una variabile stringa e l'inserimento dei dati per la tabella di riepilogo viene effettuata sulla stringa e non nel codice HTML del body delle-mail

    Il codice poi non si limita solo ad importare dati e spedire e-mail esegue un controllo dei dati immessi, individua e corregge automaticamente gli errori ed eventuali dati duplicati ridondanti, in particolare verifica la correttezza dei dati immessi manualmente in alcune colonne che sono dei codici che hanno un ben preciso formato e un ben preciso significato ... (per darle un'idea pensi per esempio al codice fiscale che non è una banale stringa ...)

    Infine il codice esporta / estrapola in un file Excel a parte lo Sheet completo dei dati immessi e importati depurandolo dal codice vba incapsulato; questo viene poi allegato all'email che lo stesso codice VBA genera automaticamente inserendo nel body la tabella riepilogativa formata da 20 righe, 5 colonne e un' head

    Tutto questo funziona alla perfezione il problema è solo la tabella riepilogativa nel body dell'email :

    Se uso direttamente il metodo Send dell'oggetto objEMail (objEMail.Send) la tabella viene disegnata nel body esattamente come prestabilito e i destinatari la ricevono esattamente come ho prestabilito

    Se invece uso il metodo .Display (objEMail.Display), cosa che mi serve perché alle volte ci capita di aggiungere brevi note nel body dell'email, note che è impossibile automatizzare, l'anteprima dell'email altera alcuni attributi dei bordi e degli sfondi delle celle della tabella e i destinatari ricevono la tabella con gli attributi alterati. Non è questo un problema in quanto è solo una questione estetica ma non capisco perché Outlook mi debba cambiare gli attributi di stile della tabella

    Forse con delle immagini riesco a spiegarmi meglio ....

    Con il metodo Send l'invio è automatico e la tabella nel body è ricevuta dai destinatari esattamente come prestabilito:

    Con il metodo Display (che è quello che mi serve ... bla ... bla) l'anteprima altera lo stile della tabella, l'invio deve essere comandato manualmente e i destinatari ricevono la tabella come in figura con gli attributi di stile (soprattutto dei bordi) alterato ....

    Direi che c'è una bella differenza estetica, ribadisco non è iun problema di invio email che viene inviata correttamente con l'allegato ai destinatari prestabiliti il problema è l'alterazione dello stile della tabella che comunque è solo un problema estetico che se non riesco a risolvere l'accetto perché tutto il codice vba che ho scritto funziona perfettamente

    La risposta è stata utile?

    0 commenti Nessun commento
  4. Anonimo
    2023-09-14T09:33:57+00:00

    Prima di tutto la ringrazio per la sua tempestiva risposta al mio quesito,

    Dunque, posto di seguito il codice (VBA) di invio email ma credo che sia del tutto inutile in quanto si tratta di una procedura standard ( una sub per intenderci) alla quale passo come parametri l'oggetto dell'email, i destinatari per competenza e conoscenza, il percorso completo del file Excel da allegare, la stringa del body dell'email ecc. ecc. ...

    Public Sub SendEMail(ByVal strHTMLMailBody As String, ByVal strEMailAddressees As String, ByVal strEMailAttachment As String, bla bla bla ... )

    Dim objOutlookApp As Object 
    
    Dim objMail As Object 
    
    Set objOutlookApp = CreateObject("Outlook.Application") 
    
    Set objMail = objOutlookApp.CreateItem(olMailItem) 
    
    With objMail    
    
        .To = strEMailAddressees 
    
        .Subject = "Test invio email" 
    
        .Attachments.Add (strEMailAttachment) 
    
        .BodyFormat = olFormatHTML 
    
        .HTMLBody = strHTMLMailBody 
    
        ...
    
        bla .. bla ..bla ... bla ...
    
        ...
    
        .Display 
    
        ' .Send 
    
    End With 
    

    End Sub

    Infatti il mio problema non è l'invio dell'email che viene inviata correttamente ma è la formattazione della tabella riepilogativa nel body dell'email che Outlook altera se utilizzo il metodo display, per esempio l'head della tabella perde il colore dello sfondo impostato (background-color) gli attributi dei bordi non sono quelli che ho impostato ecc. ecc.

    Il body dell'email non è altro che il testo del codice HTML , questo contiene delle variabili di riferimento che per il codice HTML non sono null'altro che testo e che in breve vado a rimpiazzare tramite la funzione Replace di VBA con i valori da includere nella tabella riepilogativa; la sostituzione la eseguo fuori dalla Sub SendEMail(), a questa gli passo come parametro il testo html completo di tutti i valori ...

    Il testo HTM del body dell'email è memorizzato in una cella Excel

    Se dunque nella Sub SendEMail() uso direttamente il metodo .send e non uso il metodo .display la tabella riepilogativa nel body viene inviata correttamente se invece utilizzo il metodo display (quindi l'invio dovrà essere comandato manualmente nell'anteprima dell'email) la tabella riepilogativa subisce un'alterazione,

    Che la causa sia outlook ((della suite Microsoft Office 2021 Professional plus) è evidente ...

    Purtroppo in ufficio utilizziamo outlook per le emails e comunque l'anteprima dell'email è necessaria perché di volta in volta capita di dover aggiungere nel body dell'email qualche breve nota del caso

    La risposta è stata utile?

    0 commenti Nessun commento
  5. Anonimo
    2023-09-11T11:03:45+00:00

    Ciao Federico,

    Nell'ufficio dove lavoro, settimanalmente c'è la necessità di creare un foglio Excel dove dobbiamo inserire moltissimi dati e in alcune colonne invece dobbiamo importare dei dati da un altro foglio Excel che ci viene fornito ... tutto questo richiede due ore di tempo ...

    Ho pensato quindi di automatizzare mediante codice Visual Basic Application

    Abbiamo anche l'esigenza di dover inviare una email con allegato il file Excel creato nel cui corpo dobbiamo inserire una tabella riepilogativa

    Ovviamente il codice vba che ho scritto
    si occupa anche di creare l'email con il body html in cui inserisce automaticamente la tabella riepilogativa

    Il problema è che usando il metodo "send" dell'oggetto "olmail" tutto il corpo dell'email viene inviato correttamente

    Invece se utilizzo il metodo display (anteprima di outlook) la tabella riepilogativa perde la formattazione prestabilita

    Qualcuno sa darmi qualche dritta per aggirare questo problema?

    Ringrazio anticipatamente

    Avremmo bisogno di vedere il tuo codice e un semplice file di esempio, privo di dati sensibili,

    A questo proposito, ho spesso utilizzato codice per scopi simili e non ho riscontrato il tuo problema.

    ===

    Regards,

    Norman

    Immagine

    La risposta è stata utile?

    0 commenti Nessun commento