por para outlookapp olmailitem mitem macro insertar imagen firma enviar desde cuerpo correo con archivo vba outlook access-vba outlook-vba

vba - para - set mitem outlookapp createitem olmailitem



Cómo agregar una firma predeterminada en Outlook (11)

Estoy escribiendo un script de VBA en Access que crea y rellena automáticamente algunas docenas de correos electrónicos. Hasta ahora ha sido una codificación sencilla, pero soy nuevo en Outlook. Después de crear el objeto mailitem, ¿cómo agrego la firma predeterminada al correo electrónico ?

  1. Esta sería la firma predeterminada que se agrega automáticamente al crear un nuevo correo electrónico.

  2. Idealmente, me gustaría usar ObjMail.GetDefaultSignature , pero no puedo encontrar nada parecido.

  3. Actualmente, estoy usando la función a continuación (que se encuentra en elsewhere en Internet) y haciendo referencia a la ruta y el nombre de archivo exactos del archivo htm. Pero esto será utilizado por varias personas y pueden tener un nombre diferente para su archivo de firma htm predeterminado. Entonces esto funciona, pero no es ideal:

    Function GetBoiler(ByVal sFile As String) As String ''Dick Kusleika Dim fso As Object Dim ts As Object Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2) GetBoiler = ts.readall ts.Close End Function

    (Llamado con getboiler(SigString = "C:/Users/" & Environ("username") & "/AppData/Roaming/Microsoft/Signatures/Mysig.txt") )

Editar

Gracias a JP (ver comentarios), me doy cuenta de que la firma predeterminada aparece al principio, pero desaparece cuando uso HTMLBody para agregar una tabla al correo electrónico. Así que supongo que mi pregunta es ahora: ¿cómo visualizo la firma predeterminada y sigo mostrando una tabla html?

Sub X() Dim OlApp As Outlook.Application Dim ObjMail As Outlook.MailItem Set OlApp = Outlook.Application Set ObjMail = OlApp.CreateItem(olMailItem) ObjMail.BodyFormat = olFormatHTML ObjMail.Subject = "Subject goes here" ObjMail.Recipients.Add "Email goes here" ObjMail.HTMLBody = ObjMail.Body & "HTML Table goes here" ObjMail.Display End Sub


A menudo, esta pregunta se realiza en el contexto de la función RangeToHTML de Ron de Bruin, que crea un PublishObject de PublishObject HTML de un Excel.Range , lo extrae a través de FSO e inserta el flujo de HTML resultante en el HTMLBody del correo electrónico. Al hacerlo, esto elimina la firma predeterminada (la función RangeToHTML tiene una función auxiliar GetBoiler que intenta insertar la firma predeterminada).

Desafortunadamente, el método Application.CommandBars mal documentado no está disponible a través de Outlook:

wdDoc.Application.CommandBars.ExecuteMso "PasteExcelTableSourceFormatting"

Aumentará un tiempo de ejecución 6158:

Pero aún podemos aprovechar Word.Document que es accesible a través del método MailItem.GetInspector , podemos hacer algo como esto para copiar y pegar la selección de Excel en el cuerpo del correo electrónico de Outlook, preservando su firma predeterminada (si hay una).

Dim rng as Range Set rng = Range("A1:F10") ''Modify as needed With OutMail .To = "[email protected]" .BCC = "" .Subject = "Subject" .Display Dim wdDoc As Object ''## Word.Document Dim wdRange As Object ''## Word.Range Set wdDoc = OutMail.GetInspector.WordEditor Set wdRange = wdDoc.Range(0, 0) wdRange.InsertAfter vbCrLf & vbCrLf ''Copy the range in-place rng.Copy wdRange.Paste End With

Tenga en cuenta que en algunos casos esto puede no conservar perfectamente el ancho de las columnas o, en algunos casos, las alturas de fila, y aunque también copiará formas y otros objetos en el rango de Excel, esto también puede causar algunos problemas de alineación funky, pero para tablas simples y Rangos de Excel, es muy bueno:


Construí este enfoque mientras buscaba cómo enviar un mensaje en un horario recurrente. Encontré que el enfoque donde hace referencia a la propiedad Inspector del mensaje creado no agregaba la firma que quería (tengo más de una cuenta configurada en Outlook, con firmas separadas).

El enfoque a continuación es bastante flexible y aún simple.

Private Sub Add_Signature(ByVal addy as String, ByVal subj as String, ByVal body as String) Dim oMsg As MailItem Set oMsg = Application.CreateItem(olMailItem) oMsg.To = addy oMsg.Subject = subj oMsg.Body = body Dim sig As String '' Mysig is the name you gave your signature in the OL Options dialog sig = ReadSignature("Mysig.htm") oMsg.HTMLBody = Item.Body & "<p><BR/><BR/></p>" & sig '' oMsg.HTMLBody oMsg.Send Set oMsg = Nothing End Sub Private Function ReadSignature(sigName As String) As String Dim oFSO, oTextStream, oSig As Object Dim appDataDir, sig, sigPath, fileName As String appDataDir = Environ("APPDATA") & "/Microsoft/Signatures" sigPath = appDataDir & "/" & sigName Set oFSO = CreateObject("Scripting.FileSystemObject") Set oTextStream = oFSO.OpenTextFile(sigPath) sig = oTextStream.ReadAll '' fix relative references to images, etc. in sig '' by making them absolute paths, OL will find the image fileName = Replace(sigName, ".htm", "") & "_files/" sig = Replace(sig, fileName, appDataDir & "/" & fileName) ReadSignature = sig End Function


Descubrí un camino, pero puede ser demasiado descuidado para la mayoría. Tengo un Db simple y quiero que pueda generar correos electrónicos para mí, así que aquí está la solución sucia y sucia que utilicé:

Descubrí que el comienzo del texto del cuerpo es el único lugar donde veo el " <div class=WordSection1> " en el HTML Cuerpo de un nuevo correo electrónico, así que simplemente hice un simple reemplazo, reemplazando

" <div class=WordSection1><p class=MsoNormal><o:p> "

con

"<div class=WordSection1><p class=MsoNormal><o:p>" & sBody

donde sBody es el contenido del cuerpo que quiero insertar. Parece que funciona hasta ahora.

.HTMLBody = Replace(oEmail.HTMLBody, "<div class=WordSection1><p class=MsoNormal><o:p>", "<div class=WordSection1><p class=MsoNormal><o:p>" & sBody)


El siguiente código creará un mensaje de perspectiva y mantendrá la firma automática

Dim OApp As Object, OMail As Object, signature As String Set OApp = CreateObject("Outlook.Application") Set OMail = OApp.CreateItem(0) With OMail .Display End With signature = OMail.body With OMail ''.To = "[email protected]" ''.Subject = "Type your email subject here" ''.Attachments.Add .body = "Add body text here" & vbNewLine & signature ''.Send End With Set OMail = Nothing Set OApp = Nothing


He hecho de esto una respuesta Wiki comunitario porque no podría haberlo creado sin la investigación de PowerUser y la ayuda en comentarios anteriores.

Tomé Sub X PowerUser y agregué

Debug.Print "n------" ''with different values for n Debug.Print ObjMail.HTMLBody

después de cada declaración. De esto descubrí que la firma no está dentro de .HTMLBody hasta después de ObjMail.Display y solo si no he agregado nada al cuerpo.

Volví a la solución anterior de PowerUser que usaba C:/Users/" & Environ("username") & "/AppData/Roaming/Microsoft/Signatures/Mysig.txt") . PowerUser no estaba contento con esto porque quería su solución para trabajo para otros que tendrían diferentes firmas.

Mi firma está en la misma carpeta y no puedo encontrar ninguna opción para cambiar esta carpeta. Solo tengo una firma, así que al leer el único archivo HTM en esta carpeta, obtuve mi única firma / predeterminada.

Creé una tabla HTML y la inserté en la firma inmediatamente después del elemento <body> y configuré el cuerpo html para el resultado. Me envié el correo electrónico a mí y el resultado fue perfectamente aceptable proporcionándote el formato que incluí para verificar que pudiera.

Mi subrutina modificada es:

Sub X() Dim OlApp As Outlook.Application Dim ObjMail As Outlook.MailItem Dim BodyHtml As String Dim DirSig As String Dim FileNameHTMSig As String Dim Pos1 As Long Dim Pos2 As Long Dim SigHtm As String DirSig = "C:/Users/" & Environ("username") & _ "/AppData/Roaming/Microsoft/Signatures" FileNameHTMSig = Dir$(DirSig & "/*.htm") '' Code to handle there being no htm signature or there being more than one SigHtm = GetBoiler(DirSig & "/" & FileNameHTMSig) Pos1 = InStr(1, LCase(SigHtm), "<body") '' Code to handle there being no body Pos2 = InStr(Pos1, LCase(SigHtm), ">") '' Code to handle there being no closing > for the body element BodyHtml = "<table border=0 width=""100%"" style=""Color: #0000FF""" & _ " bgColor=#F0F0F0><tr><td align= ""center"">HTML table</td>" & _ "</tr></table><br>" BodyHtml = Mid(SigHtm, 1, Pos2 + 1) & BodyHtml & Mid(SigHtm, Pos2 + 2) Set OlApp = Outlook.Application Set ObjMail = OlApp.CreateItem(olMailItem) ObjMail.BodyFormat = olFormatHTML ObjMail.Subject = "Subject goes here" ObjMail.Recipients.Add "my email address" ObjMail.Display End Sub

Dado que tanto PowerUser como yo hemos encontrado nuestras firmas en C:/Users/" & Environ("username") & "/AppData/Roaming/Microsoft/Signatures , sugiero que esta es la ubicación estándar para cualquier instalación de Outlook. ¿Se puede cambiar este valor predeterminado? No puedo encontrar nada que sugiera que pueda. El código anterior claramente necesita algún desarrollo, pero logra el objetivo de PowerUser de crear un cuerpo de correo electrónico que contenga una tabla HTML sobre una firma.


La mayoría de las otras respuestas simplemente concatenan su cuerpo HTML con la firma HTML. Sin embargo, esto no funciona con imágenes, y resulta que hay una forma más "estándar" de hacerlo. 1

Microsoft Outlook pre-2007 que está configurado con WordEditor como su editor y Microsoft Outlook 2007 y más allá, utiliza una versión ligeramente reducida del Editor de Word para editar correos electrónicos. Esto significa que podemos usar el Modelo de Objeto de Documento de Microsoft Word para realizar cambios en el correo electrónico.

Set objMsg = Application.CreateItem(olMailItem) objMsg.GetInspector.Display ''Displaying an empty email will populate the default signature Set objSigDoc = objMsg.GetInspector.WordEditor Set objSel = objSigDoc.Windows(1).Selection With objSel .Collapse wdCollapseStart .MoveEnd WdUnits.wdStory, 1 .Copy ''This will copy the signature End With objMsg.HTMLBody = "<p>OUR HTML STUFF HERE</p>" With objSel .Move WdUnits.wdStory, 1 ''Move to the end of our new message .PasteAndFormat wdFormatOriginalFormatting ''Paste the copied signature End With ''I am not a VB programmer, wrote this originally in another language so if it does not ''compile it is because this is my first VB method :P

1


Me gusta la respuesta de pero descubrí que no conservaba las fuentes predeterminadas que son específicas del usuario. El texto apareció en una fuente del sistema como texto normal. El código a continuación conserva las fuentes favoritas del usuario, mientras lo hace solo un poco más. Se basa en el enfoque de , utiliza una expresión regular para reemplazar el texto del cuerpo predeterminado y coloca el texto del cuerpo elegido por el usuario donde pertenece mediante el uso de GetInspector.WordEditor. Descubrí que la llamada a GetInspector no completó el HTMLbody como dice dimitry streblechenko en este hilo, al menos, no en Office 2010, por lo que el objeto aún se muestra en mi código. De paso, tenga en cuenta que es importante que MailItem se cree como un Objeto, no como un MailItem directo; consulte here para obtener más información. (¡Ah, y lo siento por los gustos diferentes, pero prefiero los nombres de las variables descriptivas más largas para poder encontrar las rutinas!)

Public Function GetSignedMailItemAsObject(ByVal ToAddress As String, _ ByVal Subject As String, _ ByVal Body As String, _ SignatureName As String) As Object ''=================================================================================================================''Creates a new MailItem in HTML format as an Object. ''Body, if provided, replaces all text in the default message. ''A Signature is appended at the end of the message. ''If SignatureName is invalid any existing default signature is left in place. ''================================================================================================================= '' REQUIRED REFERENCES '' VBScript regular expressions (5.5) '' Microsoft Scripting Runtime ''================================================================================================================= Dim OlM As Object ''Do not define this as Outlook.MailItem. If you do, some things will work and some won''t (i.e. SendUsingAccount) Dim Signature As String Dim Doc As Word.Document Dim Regex As New VBScript_RegExp_55.RegExp ''(can also use use Object if VBScript is not Referenced) Set OlM = Application.CreateItem(olMailItem) With OlM .To = ToAddress .Subject = Subject ''SignatureName is the exactname that you gave your signature in the Message>Insert>Signature Dialog Signature = GetSignature(SignatureName) If Signature <> vbNullString Then '' Should really strip the terminal </body tag out of signature by removing all characters from the start of the tag '' but Outlook seems to handle this OK if you don''t bother. .Display ''Needed. Without it, there is no existing HTMLbody available to work with. Set Doc = OlM.GetInspector.WordEditor ''Get any existing body with the WordEditor and delete all of it Doc.Range(Doc.Content.Start, Doc.Content.End) = vbNullString ''Delete all existing content - we don''t want any default signature ''Preserve all local email formatting by placing any new body text, followed by the Signature, into the empty HTMLbody. With Regex .IgnoreCase = True ''Case insensitive .Global = False ''Regex finds only the first match .MultiLine = True ''In case there are stray EndOfLines (there shouldn''t be in HTML but Word exports of HTML can be dire) .Pattern = "(<body.*)(?=<//body)" ''Look for the whole HTMLbody but do NOT include the terminal </body tag in the value returned OlM.HTMLbody = .Replace(OlM.HTMLbody, "$1" & Signature) End With '' Regex Doc.Range(Doc.Content.Start, Doc.Content.Start) = Body ''Place the required Body before the signature (it will get the default style) .Close olSave ''Close the Displayed MailItem (actually Object) and Save it. If it is left open some later updates may fail. End If '' Signature <> vbNullString End With '' OlM Set GetSignedMailItemAsObject = OlM End Function Private Function GetSignature(sigName As String) As String Dim oTextStream As Scripting.TextStream Dim oSig As Object Dim appDataDir, Signature, sigPath, fileName As String Dim FileSys As Scripting.FileSystemObject ''Requires Microsoft Scripting Runtime to be available appDataDir = Environ("APPDATA") & "/Microsoft/Signatures" sigPath = appDataDir & "/" & sigName & ".htm" Set FileSys = CreateObject("Scripting.FileSystemObject") Set oTextStream = FileSys.OpenTextFile(sigPath) Signature = oTextStream.ReadAll '' fix relative references to images, etc. in Signature '' by making them absolute paths, OL will find the image fileName = Replace(sigName, ".htm", "") & "_files/" Signature = Replace(Signature, fileName, appDataDir & "/" & fileName) GetSignature = Signature End Function


Mi solución es mostrar primero un mensaje vacío (¡con la firma predeterminada!) strHTMLBody insertar el strHTMLBody previsto en el HTMLBody existente.

Si, como PowerUser indica, la firma se borra al editar HTMLBody, puede considerar almacenar el contenido de ObjMail.HTMLBody en la variable strTemp inmediatamente después de ObjMail.Display y agregar strTemp después, pero eso no debería ser necesario.

Sub X(strTo as string, strSubject as string, strHTMLBody as string) Dim OlApp As Outlook.Application Dim ObjMail As Outlook.MailItem Set OlApp = Outlook.Application Set ObjMail = OlApp.CreateItem(olMailItem) ObjMail.To = strTo ObjMail.Subject = strSubject ObjMail.Display ''You now have the default signature within ObjMail.HTMLBody. ''Add this after adding strHTMLBody ObjMail.HTMLBody = strHTMLBody & ObjMail.HTMLBody ''ObjMail.Send ''send immediately or ''ObjMail.close olSave ''save as draft ''Set OlApp = Nothing End sub


Necesito 50 representantes para publicar un comentario en contra de la opción de firma que encontré más útil, sin embargo, tuve un problema con las imágenes que no se mostraban correctamente, así que tuve que encontrar un trabajo alternativo. Esta es mi solución:

Usando la respuesta de @Morris Maynard como base https://.com/a/18455148/2337102 Luego tuve que pasar por lo siguiente:

Notas:
Haga una copia de seguridad de su archivo .htm antes de comenzar, copie y pegue en una carpeta secundaria

  1. Trabajará con el SignatureName.htm y la SignatureName_files Folder

  2. No necesita experiencia HTML , los archivos se abrirán en un programa de edición como Notepad o Notepad ++ o su programa HTML especificado

  3. Navegue a la ubicación del archivo de firma (el estándar debe ser C:/Users/"username"/AppData/Roaming/Microsoft/Signatures )

  4. Abra el archivo SignatureName.htm en un editor de texto / htm (haga clic con el botón derecho en el archivo, "Editar con el programa")

  5. Use Ctrl+F e ingrese .png ; .jpg o si no conoce su tipo de imagen, use image001 Verá algo como: src="signaturename_files/image001.png"

  6. C:/Users/YourName/AppData/Roaming/Microsoft/Signatures/SignatureNameFolder_files/image001 cambiar eso a la dirección completa de la ubicación de la imagen C:/Users/YourName/AppData/Roaming/Microsoft/Signatures/SignatureNameFolder_files/image001
    o
    src="E:/location/Signatures/SignatureNameFolder_files/image001.png"

  7. Guarde su archivo (sobrescríbalo, por supuesto, hizo una copia de seguridad del original)

  8. Regrese a Outlook y abra un nuevo elemento de correo, agregue su firma. Recibí una advertencia de que los archivos habían sido cambiados, hice clic en Aceptar, necesité hacer esto dos veces, y luego una vez en el "Editar menú de firmas".

    Some of the files in this webpage aren''t in the expected location. Do you want to download them anyway? If you''re sure the Web page is from a trusted source, click Yes."

  9. Ejecute su evento Macro, las imágenes deberían mostrarse ahora.

Crédito
MrExcel - Error de código de firma de código VBA: http://bit.ly/1gap9jY


Outlook agrega la firma a los nuevos mensajes sin modificar (no debe modificar el cuerpo antes de eso) cuando llama a MailItem.Display (que hace que el mensaje se muestre en la pantalla) o cuando accede a la propiedad MailItem.GetInspector ; lo hace no tiene que hacer nada con el objeto Inspector devuelto, pero Outlook rellenará el cuerpo del mensaje con la firma.

Una vez que se agrega la firma, lea la propiedad HTMLBody y HTMLBody con la cadena HTML que está intentando establecer. Tenga en cuenta que no puede simplemente concatenar 2 cadenas de HTML: las cadenas deben fusionarse. Por ejemplo, si desea insertar su cadena en la parte superior del cuerpo HTML, busque la subcadena "<body" , luego encuentre la siguiente aparición de ">" (esto se ocupa del elemento <body> con atributos), luego inserte tu cadena HTML después de eso ">".

Outlook Object Model no expone las firmas en absoluto.

En general, el nombre de la firma se almacena en los datos del perfil de la cuenta a los que se accede a través de la interfaz IOlkAccountManager Extended MAPI. Como esa interfaz es MAPI extendida, solo se puede acceder usando C ++ o Delphi. Puede ver la interfaz y sus datos en OutlookSpy si hace clic en el botón IOlkAccountManager .
Una vez que tenga el nombre de la firma, puede leer el archivo HTML del sistema de archivos (tenga en cuenta que el nombre de la carpeta (Firmas en inglés) está localizado.
También tenga en cuenta que si la firma contiene imágenes, también deben agregarse al mensaje como archivos adjuntos y las etiquetas <img> en el cuerpo de la firma / mensaje ajustadas para señalar el atributo src a los archivos adjuntos en lugar de una subcarpeta de la carpeta Firmas donde se almacenan las imagenes
También será su responsabilidad fusionar los estilos HTML del archivo HTML de firma con los estilos del mensaje en sí.

Si usa Redemption es una opción, puede usar su objeto de cuenta RDOAccount (accesible en cualquier idioma, incluido VBA). El nuevo nombre de firma de mensaje se almacena en la propiedad 0x0016001F , la firma de respuesta está en 0x0017001F . También puede usar la cuenta RDOAccount . ReplySignature y NewSignature .
La redención también expone RDOSignature . Método ApplyTo que toma un puntero al objeto RDOMail e inserta la firma en la ubicación especificada para fusionar correctamente las imágenes y los estilos:

set Session = CreateObject("Redemption.RDOSession") Session.MAPIOBJECT = Application.Session.MAPIOBJECT set Drafts = Session.GetDefaultFolder(olFolderDrafts) set Msg = Drafts.Items.Add Msg.To = "[email protected]" Msg.Subject = "testing signatures" Msg.HTMLBody = "<html><body>some <b>bold</b> message text</body></html>" set Account = Session.Accounts.GetOrder(2).Item(1) ''first mail account if Not (Account Is Nothing) Then set Signature = Account.NewMessageSignature if Not (Signature Is Nothing) Then Signature.ApplyTo Msg, false ''apply at the bottom End If End If Msg.Send

EDITAR : a partir de julio de 2017, MailItem.GetInspector en Outlook 2016 ya no inserta la firma. Solo MailItem.DisplayMailItem.Display hace.


Dim OutApp As Object, OutMail As Object, LogFile As String Dim cell As Range, S As String, WMBody As String, lFile As Long S = Environ("appdata") & "/Microsoft/Signatures/" If Dir(S, vbDirectory) <> vbNullString Then S = S & Dir$(S & "*.htm") Else S = "" S = CreateObject("Scripting.FileSystemObject").GetFile(S).OpenAsTextStream(1, -2).ReadAll WMBody = "<br>Hi All,<br><br>" & _ "Last line,<br><br>" & S ''Add the Signature to end of HTML Body

Solo pensé en compartir cómo logro esto. No estoy seguro de si es correcto en el sentido de definición de variables, pero es pequeño y fácil de leer, que es lo que me gusta.

Adjunto WMBody a .HTMLBody dentro del objeto Outlook.Application OLE.

Espero que ayude a alguien.

Gracias, Wes.