outlook vba code to display pictures in email - vba

By default, my MS Outlook 2013 is set NOT to download images in received HTML e-mail messages. I would like to keep this setting.
There are some senders whose emails are handled by my Outlook VBA code...and filed into specific folders (rather than the INBOX). I do not use the in-built RULES.
These are known senders...and I would like to have the pictures in the emails from these SELECT KNOWN senders downloaded and displayed. I could do this manually for each email... by right clicking etc... but that is a pain... when there are many such emails.
I am unable to figure out the few lines of code (one line ?) required to download / enable display of images / pictures in the email. Something like... MailItem.Display (which does not work... it only displays the mail in an independent window)... or MailItem.DisplayImages (that is not a known method!).
I would include this one line (or lines) in the routine which handles emails from some known senders....so that their emails always have images / pictures downloaded and displayed.
Thanks.

You would need to set the PidTagBlockStatus property - see http://msdn.microsoft.com/en-us/library/ee219242(v=exchg.80).aspx.
Note that while you can read/write that property using MailItem.PropertyAccessor.SetProperty, you will not be able to calculate its value correctly - Outlook Object Model rounds off the value of the message delivery time, and you would need the raw Extended MAPI value (accessible in C++ or Delphi only) as the FileTime structure.
If using Redemption (I am its author) is an option, it exposes the RDOMail.DownloadPictures property. Something like the following should do the job (VB script):
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Item = Session.GetRDOObjectFromOutlookObject(YourOutlookItem)
Item.DownloadPictures = true
Item.Save

The Outlook object model doesn't provide any property or method for that.

Related

Outlook VBA - can view email Source Code?

In MS Outlook, I want to loop through each selected email, and for each email, view the source code and check if the source file (as in txt format) contains a certain string "XX". Since using view source code can display the email content into html format and I would like to trace some format which with issues in the text.
Currently, I am doing manually by opening the mail, right click > View source > Ctrl+F to find the string I am looking for.
Is there a view to use VBA to do the action of "view source" in the email?
Dim individualItem As Object
For Each individualItem In Application.ActiveExplorer.Selection
'View Source Code of the email
'Find "XX" in the email body content
If Instr(individualItem.body, "XX") = 1 Then
Msgbox ("Find string!")
End if
Next Message
Thanks.
You are almost right, I see two issues:
1.) There are two distinct properties Body (only text) and HTMLBody.
2.) Instr returns the position of the search token. It can be any positive number if the token is found.
So try:
If Instr(individualItem.HTMLBody, "XX") <> 0 Then
By "source" do you mean the MIME headers of the message? They are stored in the PR_TRANSPORT_MESSAGE_HEADERS property - take a look at the message with OutlookSpy (I am its author - click IMessage button). You can reads that property using MailItem.PropertyAccessor.GetProperty. The DASL name of the PR_TRANSPORT_MESSAGE_HEADERS property "http://schemas.microsoft.com/mapi/proptag/0x007D001F".
Note that full MIME source of a message is never stored by Outlook - MIME is not native Outlook format.

Send calendar item properties from Acces form to Outlook agenda

My script in Access-vba works (I can send from an Access form a calendar item to Outlook). But now I want to send some poperties (such as subject and location of the appointment) to the agenda in Outlook and then I get an error (see image attached). For subject I want to use some text from my current form (Me.Monitor_account) but that does not work. See the image attached. If I use: .Subject = "test" then it works. But I dont see the difference between the two.
.Subject = (Me![MonitorAccount]) 'worked!

creating fields in lotus notes document?

I am trying to export items from my access database into lotus notes. The document I am trying to export to is a stationary, and has all the data written into it, I just need to somehow mark placeholders and then update the values. I have read the documentation and it appears I will need to address fields and then call a method to replace the text like so:
'where body is the field and the following string is what to replace field with
Call doc.ReplaceItemValue("body", "REPLACE BODY")
To be clear, my entire code looks like:
Set session = CreateObject("Notes.NotesSession")
Set maildb = session.GetDatabase("server", "mail\box.nsf")
Set View = maildb.GetView("Stationery")
Set entries = View.AllEntries
Set entry = entries.GetFirstEntry
Set doc = entry.Document
Call doc.ReplaceItemValue("Subject", "Report - " & Date)
'add code here
Call doc.send(False, "person.to.receive#thisemail.com")
End Sub
I have noticed that while perusing documentation, there seems to be an ability to create fields, and then address those fields to update values. So for example, if I have a field named $COST, then one could do:
Call doc.ReplaceItemValue("$COST", "The cost is $3000")
And that field should be updated to reflect the value I passed through the method. My big problem is, even looking through documentation, I cannot figure out where I need to go to add in my custom fields. It seems that the documentation assumes that you know how to create these fields and just address them. Or am I only supposed to create these fields programatically and then fill in the data? My client is Lotus Notes 8. Thanks!
Yes, that is the cool thing about IBM Lotus Notes databases: you can put items (=fields) in a Notes document without a prior definition of fields.
If you create items in a document with doc.ReplaceItemValue() and save or send the document then the items are just there. You can check the items when you open the property box for a selected document. All items are listed on document properties' second tab.
Another question is of course to define fields in a form so that the created items are visible to user without looking at document properties box. Open database in Designer and put the fields in right position and size to form.
Your question and comments telling that you want to create a document, fill it with data and send it to users.
If all users have access to your Notes server then you can create that document in your existing database and send just a link mail to users. This way you can create a good looking form and position all your data fields. Users will access the document in database through link.
An alternative is to create an nice looking HTML file, attach it to the mail and send it.
In this case you would add this code to your example at 'add code here:
Call doc.RemoveItem("Body")
Set rtitem = doc.CreateRichTextItem( "Body" )
Call rtitem.AppendText("your mail text")
Call rtitem.EmbedObject(EMBED_ATTACHMENT, "", "report.html")
Based on the comment thread on #Knut Herrmann's answer, I believe that the solution you really want involves using "stored form". The first argument to the NotesDocument.Send() method is a boolean that specifies whether you want to store the form or not.
Normally, you would use Domino Designer to create a stored form. You would not need Designer rights to anyone's mailbox. You would just need to create an empty database of your own, and put a form into it. You woould change your code to open that database and create the document in there instead of in a mailbox database as you are doing now. (One of the other cool things about Notes is that you don't actually have to be working in a mailbox database in order to mail a document. You can mail any document from any database, as long as you put the approporiate fields into it.)
There is also a way to do this without Domino Designer, and you could even dynamically generate the form with truly custom fields that your code only discovers as it runs. You could do this with DXL, which is an XML format for describing Lotus Notes objects, including forms. You would just need some sample DXL to work from. Preferably that should be of an empty database that contains a simple form that is set up more or less in the layout that you would want, though again you would need Domino Designer for that. You could just use the same mailbox database that your code is currently using, but that will leave you with a lot of extra stuff in the DXL that doesn't need to be there; and given that you're not all that familiar with Notes, it would likely be difficult for you to navigate through it all to find what you need.
Either way, though, you could use the NotesDXLExporter class to generate the DXL file. Your code could manipulate the DXL, adding/changing elements as needed (following the pattern that you see in sample, of course), and they you could use NotesDXLImporter to create the database that your code will actually use to create the document in and mail the message with the stored form.

Send HTML Mail from Cocoa with Mail.app

I'm trying to send html email from Cocoa app, through Mail.app. I want to open new message in Mail.app, include subject, recipient and add HTML Body with links and other content. But can't find the way to do this.
I already tried Scripting Bridge, but MailOutgoingMessage class doesn't have content type i can add content in plaintext.
tried AppleScript, something like this:
set htmlContent to read "/Path/index.html"
set recipientList to {"mail#mail.com"}
tell application "Mail"
set newMessage to make new outgoing message with properties {subject:"qwerty", visible:true}
tell newMessage
make new to recipient at end of to recipients with properties {address:"mail#s.com"}
set html content to htmlContent
--send
end tell
end tell
this code send email with html, only if I'm changing --send to send. But i need to send letter later, after user made some changes.
To recap the problem: Using AppleScript to create a message with HTML content for interactive editing does not work (as of OS X 10.9.2): the new-message form comes up with an empty body.
This should be considered a bug and I encourage everyone to let Apple know at http://bugreport.apple.com - caveat: the html content message class property is not defined in Mail.sdef, Mail.app's AppleScript dictionary, so assigning HTML may not be officially supported.
There is a workaround, but it ain't pretty:
Create the message invisibly.
Save it as a draft.
Open the draft message, at which point the HTML content will appear.
Implementing this robustly is challenging, because several workarounds are required. The following code tries its hardest, though:
Note: Since the code uses GUI scripting, Access for Assistive Devices must be enabled (via System Preferences > Security & Privacy > Accessibility) for the application running this code (e.g., AppleScript Editor or, if run via osascript, Terminal.app).
# Example values; use `read someFile` to read HTML from a file.
set htmlContent to "<html><body><h1>Hello,</h1><p>world.</p></body></html>"
set recipientList to {"person1#example.com", "person2#example.com"}
set msgSubject to "qwerty"
tell application "Mail"
# Create the message *invisibly*, and assign subject text
# as well as the HTML content.
set newMessage to make new outgoing message with properties ¬
{visible:false, subject:msgSubject, html content:htmlContent}
# Add recipients.
# !! Given the workaround below, this is currently pointless.
tell newMessage
repeat with toRcpt in recipientList
make new to recipient at end of to recipients with properties {address:toRcpt}
end repeat
end tell
# Save the current number of drafts messages.
set draftCountBefore to count messages of drafts mailbox
# !! Save the new message as a *draft* - this is necessary
# for the HTML content to actually appear in the message
# body when we open the message interactively later.
save newMessage
# !! Sadly, it takes a little while for the new message
# !! to appear in the drafts mailbox, so we must WAIT.
set newMessageAsDraft to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
set draftCountNow to (count messages of drafts mailbox)
if draftCountNow > draftCountBefore then
set newMessageAsDraft to message 1 of drafts mailbox
exit repeat
end if
delay 0.1 # sleep a little
end repeat
# Abort, if the draft never appeared.
if newMessageAsDraft is missing value then error "New message failed to appear in the drafts mailbox within the timeout period."
# Open the new message as a *draft* message - this ensures that
# the HTML content is displayed and editable in the message body.
# !! The ONLY solution I found is to use `redirect`, which, unfortunately,
# !! *wipes out the recipients*.
# !! It does, however, ensure that the draft is deleted once the message is sent.
redirect newMessageAsDraft with opening window
# Activate Mail.app and thus the draft message's window.
activate
# !! Since the recipients have been wiped out, we need to
# !! add them again - unfortunately, the only way we can do that is to
# !! *GUI scripting* - simulating invocation of a menu command or
# !! sending keystrokes.
tell application "System Events"
# We must make sure that the target window is active before
# we can perform GUI scripting on it.
set newMessageWindow to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
tell (first window of (first process whose frontmost is true) whose subrole is not "AXFloatingWindow")
if name is msgSubject then
set newMessageWindow to it
exit repeat
end if
end tell
delay 0.1 # sleep a little
end repeat
if newMessageWindow is missing value then error "New message failed to become the active window within the timeout period."
# Turn the list of recipients into comma-delimited *string* for pasting into the To field.
set {orgTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
set recipientListString to (recipientList as text)
set AppleScript's text item delimiters to orgTIDs
# Save the current clipboard content.
set prevClipboardContents to the clipboard
# Cursor is in the "To:" field, so use GUI scripting to send the Edit > Paste command now.
# NOTE: Access for assistive devices must be enabled via System Preferences > Security & Privacy > Accessibility.
set the clipboard to recipientListString
my pasteFromClipboard("")
# Restore the previous clipboard content.
# !! We mustn't do this instantly, as our temporary content may not have
# !! finished pasting yet. It would be non-trivial to determine
# !! when pasting has finished (examining `count of to recipients` doesn't work),
# !! so we take our chances with a fixed, small delay.
delay 0.1
set the clipboard to prevClipboardContents
# Place the cursor in the message *body*.
# !! This works as of Mail.app on OS X 10.9.2, but may break in the future.
try
tell newMessageWindow
tell UI element 1 of scroll area 1
set value of attribute "AXFocused" to true
end tell
end tell
end try
end tell
end tell
(*
Pastes form the clipboard into the active window of the specified application (process) using GUI scripting
rather than keyboard shortcuts so as to avoid conflicts with keyboard shortcuts used to invoke this handler.
Specify "" or `missing value` to paste into the currently active (frontmost) application.
The target process may be specified by either name or as a process object.
CAVEAT: While this subroutine IS portable across *UI languages*, it does make an assumption that will hopefully hold for
all applications: that the "Edit" menu is the *4th* menu from the left (Apple menu, app menu, File, Edit).
Examples:
my pasteFromClipboard("") # paste into frontmost app
my pasteFromClipboard("TextEdit")
*)
on pasteFromClipboard(targetProcess)
tell application "System Events"
if targetProcess is missing value or targetProcess = "" then
set targetProcess to first process whose frontmost is true
else
if class of targetProcess is text then
set targetProcess to process targetProcess
end if
-- Activate the application (make it frontmost), otherwise pasting will not work.
set frontmost of targetProcess to true
end if
tell menu 1 of menu bar item 4 of menu bar 1 of targetProcess
-- Find the menu item whose keyboard shortcut is Cmd-V
set miPaste to first menu item whose value of attribute "AXMenuItemCmdChar" is "V" and value of attribute "AXMenuItemCmdModifiers" is 0
click miPaste
end tell
end tell
end pasteFromClipboard
It isn't clear what your are looking for, but I'll do my best to offer some help.
If you leave send commented, then the message should already be open in Mail.app, waiting for further editing and sending.
By adding the line save newMessage, it will be saved to the drafts folder. The user can open it and continue editing whenever they please. If you want to actually send the draft from your application, use:
set sendMessage to first message of drafts mailbox
send sendMessage
Good luck!
I didn't see that you needed to edit the message before sending, so my previous answer was wrong. This time it should be correct.
It basically
takes a preformatted RTF file,
renders it & puts it into the clipboard,
creates a new message,
fills in the fields,
moves the focus to the message body,
pastes the formatted clipboard
Here is the code:
set textSubject to "HTML Test"
set toAddress to "john.doe#gmail.com"
set toName to "John Doe"
tell application "Mail"
do shell script "cat ~/Documents/RTF\\ File.rtf | textutil -stdin -stdout -convert rtf | pbcopy"
set refMessage to make new outgoing message with properties {name:toName, address:toAddress, subject:textSubject, visible:true}
tell refMessage
make new to recipient at end of to recipients with properties {name:toName, address:toAddress}
end tell
end tell
tell application "System Events"
tell application process "Mail"
set frontmost to true
set value of attribute "AXFocused" of scroll area 4 of window textSubject to true
end tell
keystroke "v" using {command down}
end tell
Again, this worked fine on Snow Leopard
Hope that helped.

Set Email Flag Status in Outlook 2007

Is there a way in Outlook 2007 to set a follow-up flag on an email object? It looks like it was supported in Outlook 2003 with .FlagStatus property, but I can't find it in 2007.
From the outlook change notes:
For Follow Up Flags For Follow Up Flags, introduced in Microsoft Office Outlook 2003, are replaced by task flags and color categories. You no longer see colored flags in the Mail view. If you flagged items in the earlier version of Outlook to indicate that they were important or that they belonged to a particular group, you should now use color categories instead. If you used flags to indicate the time at which you were to take action on an item, you should now use task flags. This change is being made to increase the functionality of flags. With task flagging, you can place an item in the overall task management system, allowing you to see your tasks in the To-Do Bar, Daily Task List in Calendar, and in the Tasks view. By categorizing an item, you can easily scan your Inbox for categorized items, the same way that you might previously have scanned your Inbox for flagged items. You can also find categorized items in the Categorized Mail Search Folders.
So the concept of the flag changed, which is why the FlagStatus property has changed. According to this, the following should work:
Set SelectedItems = Outlook.ActiveExplorer.Selection
For Each Item In SelectedItems
With Item
.ToDoTaskOrdinal = dtTaskDate
.TaskDueDate = dtTaskDate
.TaskStartDate = dtTaskDate
.FlagStatus = 2
.FlagRequest = strFlagRequest
.Categories = strCategories
.FlagIcon = 6
.Save
End With
Next Item
This is what http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook._mailitem.flagstatus.aspx has to say:
Dim instance As _MailItem
Dim value As OlFlagStatus
value = instance.FlagStatus
instance.FlagStatus = value