I'm tasked with a very simple objective. Open a new email window in lotus notes using VBA, but please keep reading the fully understand my issue. Currently, I have developed vba code that creates a new email in lotus notes and fills it with all sorts of information, such as the recipient, subject, body and attachments; and then finally sends the email to the recipient. It all works flawlessly. The only problem is that it does all of this behind the scenes, and if it wasn't for checking with the recipient I would have no idea the email sent. To get around this I want the vba code to psychically pop open a new email window, with all of the same information, but instead force me to manually send the email (by hitting the send button). This way I know the email will have been sent, and also so I can add in extra information if needed.
I've looked at more threads than I can count and all seem to address a slightly different issue than mine. Any suggestions or hints in the right direction would be appreciated.
Thanks!
Thanks for the suggestions. Heres my code:
Sub Prepare_email()
Dim Maildb As Object
Dim MailDoc As Object
Dim Body As Object
Dim Session As Object
Dim Subject As String
'Start a session to notes
Set Session = CreateObject("Lotus.NotesSession")
'This line prompts for password of current ID noted in Notes.INI
Call Session.Initialize
'Open the mail database in notes
Set Maildb = Session.GETDATABASE("", MailDbName)
If Maildb.IsOpen = True Then
Else
Call Maildb.Open
End If
'Create the mail document
Set MailDoc = Maildb.CREATEDOCUMENT
Call MailDoc.ReplaceItemValue("Form", "Memo")
'Set the recipient, calls a GetPrimary Email function
Call MailDoc.ReplaceItemValue("SendTo", GetPrimaryEmail)
'Set subject, calls subject function
Subject = getCompanyName
Call MailDoc.ReplaceItemValue("Subject", Subject)
'Create and set the Body content
Set Body = MailDoc.CREATERICHTEXTITEM("Body")
Call Body.APPENDTEXT("BODY Content")
'Example to save the message
MailDoc.SAVEMESSAGEONSEND = True
'Send the document
Call MailDoc.ReplaceItemValue("PostedDate", Now())
Call MailDoc.SEND(False)
'Clean Up
Set Maildb = Nothing
Set MailDoc = Nothing
Set Body = Nothing
Set Session = Nothing
End Sub
By "behind the scenes", I presume you mean that you are using the Notes "back-end classes". If you want to actually open a window in the client, you have to use the "front-end" classes.
An important difference to understand is that the "front-end" classes are exposed as OLE objects (Notes.NotesUIWorkspace), and the "back-end" classes are exposed both as OLE (Notes.NotesSession) and COM (Lotus.NotesSession) objects. Note the different prefixes: 'Notes' for OLE classes, 'Lotus' for COM classes.
The NotesUIWorspace class and the other front-end classes that you can drive through it are all about automating the actual operation of the Notes client. You can find documentation for the NotesUIWorkspace class here. When you use OLE classes, the Notes client starts automatically unless it is already running. When you use the COM classes, the Notes client does not need to be running and does not start automatically.
The first step involves saving your document instead of calling Send, i.e. call Call doc.Save( True, True ) if doc is your NotesDocument class.
The second step is showing the document by using CreateObject("Notes.NotesUIWorkspace").EDITDOCUMENT True, doc
As a side note: Showing your code would actually help answering the question!
Related
I work at a Company that gets requests we filter in terms of
being eligibile for financing from our financing partner
requiring more information from the enquirer
There is a lot of monotonous work, in copy pasting email replies.
I looked into creating a Quick Action in Outlook, but because our mother company does not allow certain freedoms, like the Font has to be specifically Segoe Ui Light etc. I could not use this, so I thought about writing a macro.
I intended for a macro button to:
Open a new Reply email, replying to all in the original mail.
In this new email text body, use a template email that I already made and saved as a template. (This way it saved the Font, size and other formatting.)
Put in the original Sender and CC'ed mail addresses as well as the Subject from the original mail.
And then display the email, so I could make edits if I wanted to before sending.
Sub ReplyGewerbeanmeldung()
Dim origEmail As MailItem
Dim replyEmail As MailItem
Set origEmail = Application.ActiveWindow.Selection.Item(1)
Set replyEmail = Application.CreateItemFromTemplate(" "C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft"\ReplyGewerbeanmeldung.oft")
replyEmail.To = origEmail.Sender
replyEmail.CC = origEmail.CC
replyEmail.Subject = origEmail.Subject
replyEmail.HTMLBody = replyEmail.HTMLBody & origEmail.Reply.HTMLBody
replyEmail.Display
End Sub
First of all, it seems you need to correct the file path to the template message. The following string is not a valid file path:
" "C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft"\ReplyGewerbeanmeldung.oft"
Try to use the following string instead:
Set replyEmail = Application.CreateItemFromTemplate("C:\Users\XYZ\AppData\Roaming\Microsoft\Templates\ReplyGewerbeanmeldung.oft")
You can read more about that in the How To: Create a new Outlook message based on a template article.
Anyway, creating items from a template will not preserve the original message body. Moreover, in Outlook you will not get any visual appearance that a particular items was replied. So, you need to call the ReplyAll method on the original item in Outlook to avoid this artefacts in Outlook.
You can create a new mail item, but only for copying the message body response which is required to paste into the reply. The NameSpace.OpenSharedItem method can be used to to open iCalendar appointment (.ics) files, vCard (.vcf) files, and Outlook message (.msg) files. You may consider using it instead of creating a new item based on the template to grab the message body from there.
I currently have two Lotus Notes databases, each with their own email addresses associated with them. As expected, when I send an email through the first database to my gmail account, it shows up as "From: notesAccount1#db1.com" and when I send using the second database, the message shows up as "From: notesAccount2#db2.com" in my gmail.
I have working code that opens up the second database, searches the inbox for an email containing a certain keyword, and extracts an email address from that email. It then creates a new document in that second database, inserts the recipients name, subject, body, etc., sends the email, and saves it to my sent folder. Everything works smoothly up to this point.
However, when I send an email from the second database to my gmail account using this VBA method, the email shows up in my gmail as "From: notesAccount1#db1.com" - the email associated with the first database.
I can't figure out why this is happening. Pretty limited knowledge of the interactions between VBA and Lotus Notes, and Lotus Notes servers/databases in general. The first database is technically my default one that only I have access to and the second database was added later and multiple people have access to it. I don't know if that's relevant.
Would appreciate any help! Thanks.
Note: This code was copied and adapted from several sources, including some on SO, IBM and other Notes sources, and anything else Google threw my way, including
http://www.fabalou.com/vbandvba/lotusnotesmail.asp
http://www-01.ibm.com/support/docview.wss?uid=swg21178583
Code: (This will have to be adapted as I have taken out server names and mail file names)
Sub ReadNotesEmail()
Dim sess As Object
Dim db As Object
Dim folder As Object
Dim docNext As Object
Dim memoSenders As Variant
Dim newEmail As Object
Dim view As Object
Dim entry As Object
Dim entries As Object
Dim templateEmail As Object
Dim mailServer As String
Dim mailFile As String
Dim folderName As String
Dim todayDate As String
Dim memoBody As String
Dim senderEmail As String
Dim emailStartPos As Integer
Dim emailEndPos As Integer
'This program will search a particular folder in a Notes database that I designate.
'It will search that folder for emails that contain certain key words. Once it finds
'an email that fits, it will grab the sender's email address (written in the body, not
'in the 'from') and send them an email.
'Name of folder to search for emails
folderName = "($Inbox)"
'Create a Lotus Notes session and open it (will require password)
Set sess = CreateObject("Lotus.NotesSession")
sess.Initialize ("")
'Set the mail server, mail file, and database. This will be the tricky part as I need this to
'look at the second mail server as opposed to the default mail server of jdyagoda
Set db = sess.GETDATABASE("***name of second Notes server***", "***name of second mail file***")
'Open the mail database in notes
If Not db.IsOpen = True Then
Call db.Open
End If
Set folder = db.GetView(folderName)
'Now look through the emails one at a time with a loop that ends when no emails are left.
'If an email contains the key word, look for the email address of the person who submitted
'the contact-us form. It follows the string "Email:" and preceeds
'the string "Phone:".
Set doc = folder.GetFirstDocument
Do Until doc Is Nothing
Set docNext = folder.GETNEXTDOCUMENT(doc)
memoBody = LCase(doc.GetItemValue("body")(0))
If (memoBody Like "*") Then 'This is where you designate the keyword
'Here's where you extract the email address - taken out for the purpose of this SO question
'senderEmail = testName#test.com
'Now create a new email to the intended recipient
Set newEmail = db.CREATEDOCUMENT
Call newEmail.ReplaceItemValue("Form", "Memo")
Call newEmail.ReplaceItemValue("SendTo", senderEmail)
Call newEmail.ReplaceItemValue("Subject", "Thank you for your email")
Call newEmail.ReplaceItemValue("body", "Test Body 1. This is a test.")
newEmail.SAVEMESSAGEONSEND = True
'Send the new email
Call newEmail.ReplaceItemValue("PostedDate", Now()) 'Gets the mail to appeaer in the sent items folder
Call newEmail.SEND(False)
End If
Set doc = docNext
Loop
End Sub
Notes will normally send the mail using the email address for the ID you use to login. So if you login using notesAccount1/Domain, then all emails will be coming from notesAccount1#example.com.
If you want to fake the sender, you need to use an undocumented method: inject the email directly into mail.box.
You should not attempt to do this unless you really know what you are doing.
I have posted code on my blog for a mail notification class, it supports this work-around to set the sender on outgoing emails. You can find the latest code at http://blog.texasswede.com/updated-mailnotification-class-now-with-html-email-support-and-web-links/
I am new to a Notes environment, so I've spent a lot of time reading here and other forums in an attempt to learn how to VBA an email via Lotus/IBM Notes.
There seems to be 2 main approaches; I am using the NotesUI method, since one of the requirements for the email is to embed an image of a portion of the Excel worksheet, as well as attaching the file itself.
At this stage, I have functioning code which achieves this (more often than not!) from the email address of the person who runs the macro. I can claim no credit for this - it has been borrowed with gratitude from the web.
However, the team has a shared email account, from which I wish to send the email.
I have seen some discussion of Principal and being able to specify a FromName, but I've so far been unable to achieve this last part.
The code I am using to successfully send an email with an attachment and an image of a section of my worksheet is below - and tips on how to modify the existing code to send from another email address would be most welcomed!
Sub SendEmbedMail(mailTo As String, stSubject As String, _
copyData As Range, Optional msgBeforeEmbed As String, _
Optional msgAfterEmbed As String, Optional attachFile As Workbook)
Dim Notes As Object, db As Object, WorkSpace As Object
Dim UIdoc As Object, UserName As String, MailDbName As String
Dim AttachMe As Object, EmbedObj As Object
'Create & Open New Document
Set WorkSpace = CreateObject("Notes.NotesUIWorkspace")
Call WorkSpace.COMPOSEDOCUMENT(, , "Memo")
Set UIdoc = WorkSpace.CURRENTDOCUMENT
Call UIdoc.inserttext(mailTo)
Call UIdoc.gotofield("Body")
Call UIdoc.inserttext(msgBeforeEmbed)
copyData.CopyPicture
Call UIdoc.Paste
Call UIdoc.inserttext(msgAfterEmbed)
Call UIdoc.gotofield("Subject")
Call UIdoc.inserttext(stSubject)
If Not attachFile Is Nothing Then
Set AttachMe = UIdoc.Document.CreateRichTextItem("Attachment")
Set EmbedObj = AttachMe.EmbedObject(1454, vbNullString, _
attachFile.FullName, "Attachment")
End If
Call UIdoc.Send(0, mailTo)
End Sub
Writing the document directly to the server's mail.box file is often used as a solution for this. See the first answer to this question, and look at the code of the OpenNTF Team Mailbox project for more details. Doing this generally won't completely remove the sender's info from the message, though. (It may vary depending on the Notes and Domino versions, but Notes has never been fully cooperative with spoofing attempts done this way.)
If you want to completely hide the identity of the sender, the approach that works best is to use an agent running on the server to send the message - or in your case, to re-send it. The agent can be signed by a generic Notes id instead of the developer's or the server's id, so by the time the actual send to the actual recipient occurs, the end-user isn't part of the process. In your case, you could accomplish that by creating a mail-in database and changing your VBA code from Call UIdoc.inserttext(mailTo) to Call UIdoc.inserttext("My mail-in database name goes here") but you'll also have to put your mailTo value somewhere, otherwise the agent won't know where to re-send it. You can do that by adding a line of code like this:
Call UIdoc.Document.ReplaceItemValue("actualRecipient",mailTo)
Your agent can be set up to run after new mail arrives in the mail-in database, and it can then clean up the message by removing the From and ReplyTo and INETFrom (if they exist - see here) items, and setting the SendTo and Principal and INETFrom fields. Omitting the basic framework code for the agent (some examples here) and assuming that doc is the variable that contains the NotesDocument that you are re-sending, the actual working part of the agent could be similar to this:
doc.RemoveItem("From")
doc.RemoveItem("InetFROM")
doc.RemoveItem("ReplyTo")
if doc.hasItem("actualRecipient") then
doc.ReplaceItemValue("SendTo",doc.actualRecipient(0))
doc.RemoveItem("actualRecipient")
else
' here you'll want to do something sensible if a message arrives in the mail-in
' database but it doesn't have an actualRecipient; i.e., it wasn't sent by your
' VBA code!
End if
Call doc.ReplaceItemValue("Principal","support#company.com#Your Notes Domain Goes Here <support#company.com>")
Call doc.ReplaceItemValue("INETFrom", "support#company.com")
Call doc.Send()
You could also do this using back-end classes (not UI). I wrote a class to help with creating emails, it includes changing the from-address to anything you like:
http://blog.texasswede.com/lotusscript-mail-notification-class/
You just have to add a method to insert a picture in the text, you can use the approach described by Thomas Hampel at http://blog.tomcat2000.com/blog/tomcat2000.nsf/dx/notesapi-import-pictures-into-richtext-fields-using-backend-classes.htm.
I'm attempting to generate an email from MS Access when a particular procedure is run and certain conditions are met, the email will include a hyperlink. I've found the sendobject macro command does not allow for hyperlink, only static text. It seems that the solution is to code the portion of the entire process that generates and sends the email in VBA and call on that code in the appropriate segment of my if function within my macro.
I can't figure out the appropriate code to generate and send and email with a hyperlink to an individual however. It will be very simple, single recepient, unchanging title, and the body will read 'New providers require designation, please access the provider designation dashboard for provider designation' ideally the provider designation dashboard would be the hyperlink and point to a shared network space.
What commands do I need to accomplish this, I'm inexperienced in VBA and this is eating up a fair amount of time I don't have.
Thank you
There are some different approaches for sending e-mail with code. The code bellow uses an Outlook Application COM object to generate the message with a hyperlink - thus, it will only work if MS Outlook is installed in the user's machine.
Sub NewEmail(ByVal mylink As String, ByVal therecipient As String)
Dim Outlook As Object, Email As Object
Set Outlook = CreateObject("Outlook.Application")
Set Email = Outlook.CreateItem(0) 'olMailItem = 0
With Email
.Subject = "My Subject" 'message subject
.HTMLBody = "Greetings, please check this link: <a href='" & mylink & "'>Click me</a>." 'message body, in html. concatenate multiple strings if you need to
.To = therecipient 'recipient
'use this if you want to generate the message and show it to the user
.Display
'use this instead if you want the mail to be sent directly
'.Send
End With
Set Email = Nothing
Set Outlook = Nothing
End Sub
Put the code in a module. Then anywhere in your code you may call the procedure with something like:
NewEmail "www.mysite.com/targetpage.html", "persontomail#domain.com"
Notice that the routine above uses late binding. To use early binding (and get intellisese, but with some drawbacks), you would have to add a reference to Microsoft Outlook XX.X Object Library and dim the "Outlook" and "Email" objects as Outlook.Application and Outlook.MailItem, respectively.
I'm stuck with this problem for days
I have to read a specific mailbox in lotus notes and bring all the content into an excel spread sheet
but so far I have only been able to read the default inbox and have no way of switching to the other mailbox. I 'm really new to VBA can any one help me sort this out
here is the code I 'm using
Set NSession = CreateObject("Notes.NotesSession")
'get the name of the mailfile of the current user
DbLocation = NSession.GETENVIRONMENTSTRING("mail/mailbox", True)
'Get the notesdatabase for the mail.
Set NMailDb = NSession.GETDATABASE("mailboxer", DbLocation)
MsgBox (DbLocation)
I get an empty msgbox poping up
GetEnvironmentString() reads the notes.ini file. I'm not sure that's what you really want to be doing. Just from the syntax, I think you're using "mail/mailbox" as a placeholder for the actual path to the mailbox that you're looking for. E.g., you're really trying to read the mail from something like "mail/jsmith.nsf". (If I'm wrong, and you really do want to be reading the notes.ini file to get the location of the mail file, then your problem is that "mail/mailbox" is not a valid key for an ini file entry.)
My next assumption is that the Domino server where the mailbox lives is called "mailboxer", because that's what you're putting in the first argument of GetDatabase().
If I'm right about these things, then what what you need is
Set NMailDb = NSession.GETDATABASE("mailboxer", "mail/mailbox")
where "mail/mailbox" is replaced with the actual path to the mailbox that you are trying to open.
Some thoughts:
use Lotus.NotesSession if you don't have to interact with the Notes UI (Lotus.NotesSession is COM based, whereas Notes.NotesSession is OLE based)
make sure the user of the Notes client on the workstation running your VBA application has the rights require to open and read the mailbox
As D. Bugger stated, you need to be sure you have the Notes client installed on the same client machine your VB code will run, and you need to be sure the folder with the nnotes.exe file and the folder with the notes.ini file are in your environment path. (If not, you will get a COM error instantiating the Notes.NotesSession object.
If this helps, here is some starter code - not tested, but a rough guide... This walks through all documents in a Notes mailbox database, ignores anything except email documents (which have the form field = "Memo") and grabs some fields from each email.
Public Sub exportNotesMail(MailServer$, MailDBPath$)
Dim mailDb As Object, doc As Object, alldocs As Object, Session As Object
Set Session = CreateObject("Notes.NotesSession")
Set mailDb = Session.GETDATABASE(MailServer, MailDbPath$)
If mailDb.IsOpen = False Then mailDb.OPENMAIL
Set alldocs = mailDb.AllDocuments
Set doc = alldocs.GetFirstDocument
while not (doc is nothing)
If doc.GetItemValue("Form")(0) = "Memo" Then
thisSubject = doc.getItemValue("Subject")(0)
thisFrom = doc.getItemValue("From")(0)
' get more field values
' Export to Excel or wherever
End If
Set doc = alldocs.GetNextDocument(doc)
Next i
' done
End Sub
call exportNotesMail ("MyServer", "mail\myMailFile.nsf")