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 ?
Esta sería la firma predeterminada que se agrega automáticamente al crear un nuevo correo electrónico.
Idealmente, me gustaría usar
ObjMail.GetDefaultSignature
, pero no puedo encontrar nada parecido.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
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
Trabajará con el
SignatureName.htm
y laSignatureName_files Folder
No necesita experiencia
HTML
, los archivos se abrirán en un programa de edición como Notepad o Notepad ++ o su programa HTML especificadoNavegue a la ubicación del archivo de firma (el estándar debe ser
C:/Users/"username"/AppData/Roaming/Microsoft/Signatures
)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")Use
Ctrl+F
e ingrese.png
;.jpg
o si no conoce su tipo de imagen, useimage001
Verá algo como:src="signaturename_files/image001.png"
C:/Users/YourName/AppData/Roaming/Microsoft/Signatures/SignatureNameFolder_files/image001
cambiar eso a la dirección completa de la ubicación de la imagenC:/Users/YourName/AppData/Roaming/Microsoft/Signatures/SignatureNameFolder_files/image001
o
src="E:/location/Signatures/SignatureNameFolder_files/image001.png"
Guarde su archivo (sobrescríbalo, por supuesto, hizo una copia de seguridad del original)
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."
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.Display
sí MailItem.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.