Sending an email using VBA and IBM Lotus Notes - excel

I know about topics dealing with similar problem but none of them solves directly my problem (or at least I don't see it). I am using following code:
Sub SendEmailUsingCOM()
'*******************************************************************************************
' Unlike OLE automation, one can use Early Binding while using COM
' To do so, replace the generic "object" by "commented" UDT
' Set reference to: Lotus Domino Objects
'*******************************************************************************************
Dim nSess As Object 'NotesSession
Dim nDir As Object 'NotesDbDirectory
Dim nDb As Object 'NotesDatabase
Dim nDoc As Object 'NotesDocument
Dim nAtt As Object 'NotesRichTextItem
Dim vToList As Variant, vCCList As Variant, vBody As Variant
Dim vbAtt As VbMsgBoxResult
Dim sFilPath As String
Dim sPwd As String
'*******************************************************************************************
'To create notesession using COM objects, you can do so by using.
'either ProgID = Lotus.NotesSession
'or ClsID = {29131539-2EED-1069-BF5D-00DD011186B7}
'Replace ProgID by the commented string below.
'*******************************************************************************************
Set nSess = CreateObject("Lotus.NotesSession") 'New:{29131539-2EED-1069-BF5D-00DD011186B7}
'*******************************************************************************************
'This part initializes the session and creates a new mail document
'*******************************************************************************************
sPwd = Application.InputBox("Type your Lotus Notes password!", Type:=2)
Call nSess.Initialize(sPwd)
Set nDir = nSess.GetDbDirectory("")
Set nDb = nDir.OpenMailDatabase
Set nDoc = nDb.CreateDocument
'*******************************************************************************************
'If you want to send it to multiple recipients then use variant array to get the names from
'the specified range as below
'Add / Remove Comment mark from vCCList as per your needs.
'*******************************************************************************************
vToList = Application.Transpose(Range("A1").Resize(Range("A" & Rows.Count).End(xlUp).Row).Value)
vCCList = Application.Transpose(Range("B1").Resize(Range("B" & Rows.Count).End(xlUp).Row).Value)
'*******************************************************************************************
'If you want to send it to multiple recipients then use variant array to get the names from
'the specified range as below
'Add / Remove Comment mark from vCCList as per your needs.
'*******************************************************************************************
With nDoc
Set nAtt = .CreateRichTextItem("Body")
Call .ReplaceItemValue("Form", "Memo")
Call .ReplaceItemValue("Subject", "Test Lotus Notes Email using COM")
With nAtt
.AppendText (Range("C2").Value)
'Decide if you want to attach a file.
vbAtt = MsgBox("Do you want to attach document?", vbYesNo, "Attach Document")
Select Case vbAtt
Case 6
.AddNewLine
.AppendText ("********************************************************************")
.AddNewLine
sFilPath = Application.GetOpenFilename
Call .EmbedObject(1454, "", sFilPath) '1454 = Constant for EMBED_ATTACHMENT
Case 7
'Do Nothing
End Select
End With
Call .ReplaceItemValue("CopyTo", vCCList)
Call .ReplaceItemValue("PostedDate", Now())
Call .Send(False, vToList)
End With
End Sub
The code stops at Set nSess = CreateObject("Lotus.NotesSession") saying Run-time error 429: ActiveX component can't create object
I saw some discussions about missing nnotes.dll but when I try to add it using Tools>References> and browse to the nnotes.dll file, it says "Can't add a reference to the specified file"
For sure I miss some basic knowledge, but I would just love to make it work and send specific ranges in excel via email.
Do you know, ideally step by step, what I should do?

Related

VBA - How do I specify the Inbox instead of using my inbox?

In my excel spreadsheet I have column A and column B. In column A I have email addresses, in column B I have unique variables. The code below is designed to look into an inbox, compare if any of the subject lines match the unique variable in column B and if they do then forward the email to the email address from column A of that unique variable. This is the code currently:
Public Sub Forward_Email(findSubjectLike As String, forwardToEmailAddresses As String)
Dim NSession As Object
Dim NMailDb As Object
Dim NViewObj As Object
Dim NInboxView As Object
Dim NDocument As Object
Dim NUIWorkspace As Object
Dim NUIDocument As Object
Dim NFwdUIDocument As Object
Set NSession = CreateObject("Lotus.NotesSession")
Call NSession.Initialize("password")
Set NUIWorkspace = CreateObject("Notes.NotesUIWorkspace")
Set NMailDb = NSession.GetDatabase("", "TEST.nsf")
Set NViewObj = NMailDb.GetView("Inbox")
Set NDocument = Find_Document(NInboxView, findSubjectLike)
If Not NDocument Is Nothing Then
Set NUIDocument = NUIWorkspace.EditDocument(False, NDocument)
NUIDocument.Forward
Set NFwdUIDocument = NUIWorkspace.CurrentDocument
Sleep 100
NFwdUIDocument.GoToField "To"
Sleep 100
NFwdUIDocument.InsertText forwardToEmailAddresses
NFwdUIDocument.GoToField "Body"
NFwdUIDocument.InsertText "This email was forwarded at " & Now
NFwdUIDocument.InsertText vbLf
NFwdUIDocument.Send
NFwdUIDocument.Close
Do
Set NUIDocument = NUIWorkspace.CurrentDocument
Sleep 100
DoEvents
Loop While NUIDocument Is Nothing
NUIDocument.Close
Else
MsgBox vbCrLf & findSubjectLike & vbCrLf & "not found in Inbox"
End If
Set NUIDocument = Nothing
Set NFwdUIDocument = Nothing
Set NDocument = Nothing
Set NMailDb = Nothing
Set NUIWorkspace = Nothing
Set NSession = Nothing
End Sub
Private Function Find_Document(NView As Object, findSubjectLike As String) As Object
Dim NThisDoc As Object
Dim thisSubject As String
Set Find_Document = Nothing
Set NThisDoc = NView.GetFirstDocument
While Not NThisDoc Is Nothing And Find_Document Is Nothing
thisSubject = NThisDoc.GetItemValue("Subject")(0)
If LCase(thisSubject) = LCase(findSubjectLike) Then Set Find_Document = NThisDoc
Set NThisDoc = NView.GetNextDocument(NThisDoc)
Wend
End Function
The issue is that now the code looks within the user inbox of the logged in user (in this case being me). I have another inbox open (lets call it TEST) am I able to specify this code to view the information from the open TEST inbox instead. Right now it compares the information from my inbox with TEST as it triggers the error line "not found in inbox".
What it does currently is it looks for the unique variable within my finds it, then tries to compare with TEST for that subject line to forward it. I want it to both look in TEST and then compare with TEST.
You state "The issue is that now the code looks within the user inbox of the logged in use". It doesn't. It uses NSession.CurrentDatabase,, and your NotesSession is loaded into VBA using the Notes OLE classes. It's the OLE classes becuase you are using Notes.NotesSession instead of Lotus.NotesSesion. In the COM classes, that are loaded if you use Lotus.NotesSession., the CurrentDatabase property isn't defined. In the OLE classes, I honestly don't know what the expected behavior is in the OLE classes, but I know for sure that you can't rely on the current database always being the current user's mailbox database.
In any case, if you want to access another user's Inbox, first you have to open that user's mailbox database. To do that, you have to know what server that mailbox database is on, and what the path to the mailbox is on that server. You do that by writing code to read that information from that user's Person document in the Domino Directory, or you can put that information into your spreadsheet for each user. With that, you can use NotesSession.GetDatabase, open the database, and access it more or less the way you are accessing your own mailbox database.

Convert Outlook Contact Group early binding Excel VBA to late binding

I am trying to insert a list of email addresses from Excel into a contact group in Outlook.
I found Excel VBA code online. It uses early binding. It is not an option to force the user to go into Tools-> References -> Outlook, when they open the file.
I need to transform the code from early to late binding.
Questions:
I understand that I need to change Outlook.Application to
CreateObject('Outlook.Application') and that I can access
olFolderContacts with the number 10 instead. See code below.
I can't figure out how to access the remaining items such as
CreateItem(olDistributionListItem).
Sub CreateContactGroupfromExcel()
Dim objContactsFolder As Outlook.Folder
Dim objContact As Outlook.ContactItem
Dim objContactGroup As Outlook.DistListItem
Dim objNameCell As Excel.Range
Dim objEmailCell As Excel.Range
Dim strName As String
Dim strEmail As String
Dim objTempMail As Outlook.MailItem
Dim objRecipients As Outlook.Recipients
Set objContactsFolder = Outlook.Application.Session.GetDefaultFolder(olFolderContacts)
Set objContactGroup = Outlook.Application.CreateItem(olDistributionListItem)
'You can change the contact group name
objContactGroup.DLName = "PlaceHolder_VBA"
i = 0
Do While Range("vba_email_outlook").Offset(i, 0).Value <> "":
strName = Range("vba_name_outlook").Offset(i, 0).Value
strEmail = Range("vba_email_outlook").Offset(i, 0).Value
Set objContact = objContactsFolder.Items.Find("[FullName] = '" & strName & "'")
'If there is no such a contact, create it.
If objContact Is Nothing Then
Set objContact = Outlook.Application.CreateItem(olContactItem)
With objContact
.FullName = strName
.Email1Address = strEmail
.Save
End With
End If
'Add the contacts to the new contact group
Set objTempMail = Outlook.CreateItem(olMailItem)
objTempMail.Recipients.Add (strName)
Set objRecipients = objTempMail.Recipients
objContactGroup.AddMembers objRecipients
i = i + 1
Loop
'Use "objContactGroup.Save" to straightly save it
objContactGroup.Display
objTempMail.Close olDiscard
End Sub
Declare object variables as generic Object
Dim objContactsFolder As Object
Determine number values of constants. With early binding, these values can be seen when hovering over constant or in VBA immediate window: ?olMailItem. Then reference number in place of constant or leave constants referenced as they are and declare them as constants with Const statements. Const olMailItem = 0
olFolderContacts = 10
olMailItem = 0
olDistributionListItem = 7
I am not an expert but this code allows you to add the reference when you run the VBA script, but it will mean that if it errors out the code quits running you will not be able to debug.
On Error Resume Next ''' If reference already exist this would cause an error
Application.VBE.ActiveVBProject.References.AddFromFile ("C:\Program Files (x86)\Microsoft Office\Office16\MSOUTL.OLB") ''' Might have to change file path
On Error GoTo 0

How do I copy the contents of one word document to the end of another using vba?

Goal for my project:
I want to be able to copy the contents of one document and append that selection to the end of another document.
What it does... (this is just background info so you understand why I am trying to do this):
I am trying to dynamically produce a document which quotes a variety of information regarding different parts and materials involved for a product.
The document itself has a consistent format which I have broken down and separated into two documents. The first contains a bunch of data that needs to be entered manually, and is where I want to append all additional content. The second contains roughly a dozen custom fields which are updated from an excel spreadsheet in VBA. For a single part and as a single doc this works as I want it (my base case). However my issue is when there are multiple parts for a project.
The Problem:
For multiple parts I have to store information in an array which changes in size dynamically as each additional part is added. When someone has added all the necessary parts they can select a button called "Create Quote".
Create quote runs a procedure which creates/opens separate copies of the two template documents mentioned above (saved on my computer). It then iterates through the array of parts and updates all the custom field in the 2nd document (no problems). Now I just need the contents of the 2nd document appended to the end of the first which is my problem.
What I want:
Ideally, my procedure will continue to iterate through every part in the array - updating custom fields, copy then paste the updated text, repeat... Until every part is included in the newly generated quote.
What I Tried - this code can be found in my generate quote procedure
I have tried many of the examples and suggestions provided by people who had similar question, but I don't know if its because I am operating from an excel doc, but many of their solution have not worked for me.
This is my most recent attempt and occurs after each iteration of the for loop
wrdDoc2.Fields.Update 'Update all the fields in the format document
wrdDoc2.Activate
Selection.WholeStory ' I want to select the entire document
Selection.Copy ' Copy the doc
wrdDoc1.Activate ' Set focus to the target document
Selection.EndKey wdStory ' I want the selection to be pasted to the end of the document
Selection.PasteAndFormat wdPasteDefault
QUOTE PROCEDURE - I am only including a handful of the fields I am updating because its not necessary to show them all
Private Sub quote_button_Click()
On Error GoTo RunError
Dim wrdApp1, wrdApp2 As Word.Application
Dim wrdDoc1, wrdDoc2 As Word.Document
Set wrdApp1 = CreateObject("Word.Application")
Set wrdApp2 = CreateObject("Word.Application")
wrdApp1.Visible = True
wrdApp2.Visible = True
Set wrdDoc1 = wrdApp1.Documents.Add(Template:="C:\MWES\AQT_v1.1(start).docm", NewTemplate:=False, DocumentType:=0)
Set wrdDoc2 = wrdApp2.Documents.Add(Template:="C:\MWES\AQT_v2.1(format).docm", NewTemplate:=False, DocumentType:=0)
Dim propName As String
For i = LBound(part_array, 1) To UBound(part_array, 1)
For Each prop In wrdDoc2.CustomDocumentProperties
propName = prop.name
' Looks for and sets the property name to custom values of select properties
With wrdDoc2.CustomDocumentProperties(propName)
Select Case propName
Case "EST_Quantity"
.value = part_array(i, 0) ' "QTY" ' Sheet1.Cells(1, 3) 'NA
Case "EST_Metal_Number"
.value = part_array(i, 1) ' "METAL_#" ' Sheet1.Cells(2, 3) 'NA"
Case "EST_Metal_Name"
.value = part_array(i, 2) ' "METAL_N" ' Sheet1.Cells(5, 2)
End Select
End With
Next prop ' Iterates until all the custom properties are set
wrdDoc2.Fields.Update 'Update all the fields in the format document
wrdDoc2.Activate
Selection.WholeStory ' I want to select the entire document
Selection.Copy ' Copy the doc
wrdDoc1.Activate ' Set focus to the target document
Selection.EndKey wdStory ' I want the selection to be pasted to the end of the document
Selection.PasteAndFormat wdPasteDefault
Next i ' update the document for the next part
RunError: ' Reportd any errors that might occur in the system
If Err.Number = 0 Then
Debug.Print "IGNORE ERROR 0!"
Else
Dim strError As String
strError = "ERROR: " & Err.Number & vbCrLf & Err.Description & vbCrLf & Erl
MsgBox strError
Debug.Print strError & " LINE: " & Erl
End If
End Sub
I apologize this was so long winded. Let me know if there is anything confusing or you may want clarified. I think I included everything though.
I think you're close, so here are a couple of comments and an example.
First of all, you're opening two separate MS Word Application objects. You only need one. In fact, it's possible that the copy/paste is failing because you're trying to copy from one Word app to a document opened in the other. (Trust me, I've seen weird things like this.) My example below shows how to do this by only opening a single application instance.
Dim mswApp As Word.Application
Set mswApp = AttachToMSWordApplication() 'more on this function below...
Dim doc1 As Word.Document
Dim doc2 As Word.Document
Set doc1 = mswApp.Documents.Open("C:\Temp\combined.docx")
Set doc2 = mswApp.Documents.Open("C:\Temp\control.docx")
While I don't often write code for Word, I've found that there are so many different ways to get at the same content using different objects or properties. This is always a source of confusion.
Based on this answer, which has worked well for me in the past, I then set up the source and destination ranges to perform the "copy":
Dim destination As Word.Range
Dim source As Word.Range
Set source = doc1.Content
Set destination = doc2.Content
destination.Collapse Direction:=Word.wdCollapseEnd
destination.FormattedText = source
Here is the whole module for reference:
Option Explicit
Sub AddDocs()
Dim wordWasRunning As Boolean
wordWasRunning = IsMSWordRunning()
Dim mswApp As Word.Application
Set mswApp = AttachToMSWordApplication()
Dim doc1 As Word.Document
Dim doc2 As Word.Document
Set doc1 = mswApp.Documents.Open("C:\Temp\combined.docx")
Set doc2 = mswApp.Documents.Open("C:\Temp\control.docx")
Dim destination As Word.Range
Dim source As Word.Range
Set source = doc1.Content
Set destination = doc2.Content
destination.Collapse Direction:=Word.wdCollapseEnd
destination.FormattedText = source
doc2.Close SaveChanges:=True
doc1.Close
If Not wordWasRunning Then
mswApp.Quit
End If
End Sub
Here's the promised note on a couple functions I use in the sample. I've built up a set of library functions, several of which help me access other Office applications. I save these modules as .bas files (by using the Export function in the VBA Editor) and import them as needed. So if you'd like to use it, just save the code below in using a plain text editor (NOT in the VBA Editor!), then import that file into your project.
Suggested filename is Lib_MSWordSupport.bas:
Attribute VB_Name = "Lib_MSWordSupport"
Attribute VB_Description = "Variety of support functions operating on MS Word"
Option Explicit
Public Function IsMSWordRunning() As Boolean
Attribute IsMSWordRunning.VB_Description = "quick check to see if an instance of MS Word is running"
'--- quick check to see if an instance of MS Word is running
Dim msApp As Object
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- not running
IsMSWordRunning = False
Else
'--- running
IsMSWordRunning = True
End If
End Function
Public Function AttachToMSWordApplication() As Word.Application
Attribute AttachToMSWordApplication.VB_Description = "finds an existing and running instance of MS Word, or starts the application if one is not already running"
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function

Runtime Error 13 - Type Mismatch when trying to edit richtext item of Lotus Notes

I'm trying to edit an existing notes document via VBA and then send it automatically.
I've already created pretty much everything - just need to figure out how exactly I can add a certain text at a certain position within the richtext element.
Sub sendMail() 'inputIndID As String, inputRecipient As String, inputIncDescription As String)
Dim mailDB As Object
Dim mailToSend As Object
Dim body As Object
Dim session As Object
Dim view As Object
Dim entries As Object
Dim docIDs() As String
Dim docSubjects() As String
Dim incID, incDescription As String
Dim element As String
Dim bodyNavigator As Object
incID = "<INC-ID>"
incDescription = "<INC-Betreff>"
'Start a session to notes
Set session = CreateObject("Notes.NotesSession")
'This line prompts for password of current ID noted in Notes.INI
'Call Session.Initialize
'or use below to supply password of the current ID
'Open the mail database in notes
Set mailDB = session.GetDatabase("Eschen10/Presta", "mail\qcpcsupport.nsf")
If mailDB.IsOpen = False Then
Call mailDB.Open
End If
'Search for all the messages in the folder "Umfrage"
Set view = mailDB.GetView("Umfrage")
Set entries = view.AllEntries
If entries.Count = 0 Then
MsgBox "Keine Nachricht im Umfrage Ordner."
End If
ReDim docIDs(entries.Count - 1)
ReDim docSubjects(entries.Count - 1)
Set entry = entries.GetFirstEntry
Do Until entry Is Nothing
docIDs(i) = entry.NoteID
docSubjects(i) = entry.Document.GetItemValue("Subject")(0) 'based on standard R5 mail template column order
'If the documents title matches the searched one it will be taken and worked with later
If docSubjects(i) = "Umfrage PC-Support Servicequalität" Then
Set mailToSend = entry.Document
End If
i = i + 1
Set entry = entries.GetNextEntry(entry)
Loop
'Set the recipient
Call mailToSend.ReplaceItemValue("SendTo", "simon.hartmann#thyssenkrupp.com")
'Get and change the body content
Set body = mailToSend.GetFirstItem("Body")
Set bodyNavigator = body.CreateNavigator()
'Replace markers with correct text
element = "<"
If (body.Type = RICHTEXT) Then
Call bodyNavigator.FindFirstString(element)
Call body.BeginInsert(bodyNavigator, True)
Call body.AppendText("123456")
Call bodyNavigator.FindNextString(element)
Call body.BeginInsert(bodyNavigator, True)
Call body.AppendText("Antrag Guest WLAN")
End If
'Example to save the message (optional)
mailToSend.SaveMessageOnSend = True
'Send the document
'Gets the mail to appear in the Sent items folder
mailToSend.Save True, False
Call mailToSend.ReplaceItemValue("PostedDate", Now())
Call mailToSend.Send(False)
'changes the body back and saves the document in the folder "Umfrage" so it can be resent next time
Call mailToSend.PutInFolder("Umfrage")
'Clean Up
Set mailDB = Nothing
Set mailToSend = Nothing
Set body = Nothing
Set session = Nothing
End Sub
Currently I am failing at the following line:
Call body.BeginInsert(bodyNavigator, True)
I get the error - Runtime Error 13 - Type Mismatch
I also already tried to give all variables the correct data type of Lotus Notes - but then I have the problem with each of those variables.
Is there a way I can "force" the bodynavigator to be of the correct type? Or where do I have my mistake? Am I missing a library or anything?
Thanks in advance!!!
Regards,
Simon
Did you read the documentation for NotesRichtextNavigator?
You find the following information there:
Parameters
target$
String. The search string.
options$
Long. Any of the following. Specify multiple options by combining them with addition or logical ORs.
RT_FIND_ACCENTINSENSITIVE (4) (default is accent sensitive)
RT_FIND_CASEINSENSITIVE (1) (default is case sensitive)
RT_FIND_PITCHINSENSITIVE (2) (default is pitch insensitive)
So: Your second parameter "true" is simply the wrong type... therefor the type mismatch...

VBA to Lotus Notes - Variable body with formatting ( Colors )

I'm currently working in the automation of a process at work that used to require a lot of hand work and gathering data from several sources and ended in sending an email with:
Header ( fixed ) Regular
Description ( One line for each cell with data in a given range ) Bold
Footer ( fixed ) - Text Color: Red
Attachment
Well, we had a stationery to aid with the email, but as i can't guarantee that everybody will have the stationery properly set up i am looking for a more elegant way to do so ( basically the goal is to make it fool-proof ), so i started to work on a way to do it mixing VBA+Formulas in the cells.
So far my code creates the message on notes, inserts the adress list, title and attaches the file that it generates, but when it comes to inserting the body, fat chance! I can insert a single-lined message but without any formatting or styles, the ones described above in bold next to the elements of the body.
What i'm chasing is a way to paste the text in given cells from my spreadsheet to notes and apply formatting on them, so each cell value would be a line of text on notes, with different styling.
I've been reading questions and articles for about 3 days already without any success, and i decided to ask it myself cause it's a big step forward in my project, is there a way to do it? i believe i'm looking for something like
notesmagicproperty.boldthisrange("B3")
that translates to
"03 - Lorem ipsum dolor sit amet"
Thanks in advance, Stack Overflow has saved me a thousand times already!
Also, sorry for not posting the code, i'm writing this from home and it's 3am so i have no access to it at the moment.
0. NotesRichTextRange.SetStyle method
NotesRichTextRange.SetStyle method is what you are looking for. For this method you need to create NotesRichTextStyle object. Also you need to SetBegin end SetEnd of range by using NotesRichTextNavigator object.
Here is example:
Dim ses As New NotesSession
Dim doc As NotesDocument
Dim richText As NotesRichTextItem
Dim navigator As NotesRichTextNavigator
Dim range As NotesRichTextRange
Dim headerStyle As NotesRichTextStyle
Dim descriptionStyle As NotesRichTextStyle
Dim footerStyle As NotesRichTextStyle
'Create your doc.
'Generate rich text content:
Set richText = doc.CreateRichTextItem("Body")
Set navigator = richText.CreateNavigator
Set range = richText.CreateRange
richText.AppendText("Header")
richText.AddNewline(1)
Set headerStyle = ses.CreateRichTextStyle
headerStyle.Underline = True
Set descriptionStyle = ses.CreateRichTextStyle
descriptionStyle.Bold = True
Set footerStyle = ses.CreateRichTextStyle
footerStyle.NotesColor = COLOR_RED
navigator.FindFirstElement(RTELEM_TYPE_TEXTPARAGRAPH)
range.SetBegin(navigator)
range.SetEnd(navigator)
Call range.SetStyle(headerStyle)
For index% = 0 To 7
richText.AppendText("Description" & index%)
richText.AddNewline(1)
navigator.FindNextElement(RTELEM_TYPE_TEXTPARAGRAPH)
range.SetBegin(navigator)
range.SetEnd(navigator)
Call range.SetStyle(descriptionStyle)
Next
richText.AppendText("Footer")
richText.AddNewline(1)
navigator.FindNextElement(RTELEM_TYPE_TEXTPARAGRAPH)
range.SetBegin(navigator)
range.SetEnd(navigator)
Call range.SetStyle(footerStyle)
Call richText.EmbedObject(EMBED_ATTACHMENT, "", "SomeFile")
richText.Update
'Process your doc.
This example generates this rich text:
1. NotesDocument.RenderToRTItem method
The other way is to use NotesDocument.RenderToRTItem method. For this method you need to create a form and style it as you need. For example, create a form "Message" and add to this form four fields:
And use this form in your code:
Dim ses As New NotesSession
Dim db As NotesDatabase
Dim messageDoc As NotesDocument
Dim attachment As NotesRichTextItem
Dim description(7) As String
Dim doc As NotesDocument
Dim richText As NotesRichTextItem
Set db = ses.CurrentDatabase
Set messageDoc = db.CreateDocument
messageDoc.Form = "Message"
messageDoc.Header = "Header"
For index% = 0 To Ubound(description)
description(index%) = "Description" & index%
Next
messageDoc.Description = description
messageDoc.Footer = "Footer"
Set attachment = messageDoc.CreateRichTextItem("Attachment")
Call attachment.EmbedObject(EMBED_ATTACHMENT, "", "SomeFile")
'Create your doc.
'Generate rich text content:
Set richText = doc.CreateRichTextItem("Body")
Call messageDoc.RenderToRTItem(richText)
richText.Update
'Process your doc.
This example generates this rich text:
2. NotesUIDocument.Import method
You can genereate the rich text content somewhere else and import it to your document by using NotesUIDocument.Import method.
Here is example for importing html content:
Dim ses As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim richText As NotesRichTextItem
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
'Generate html file
tempdir$ = Environ("Temp")
file = Freefile
filename$ = tempdir$ & "\temp.html"
Open filename$ For Output As file
Print #file, "<u>Header</u><br>"
For index% = 0 To 7
Print #file, "<b>Description" & index% & "</b><br>"
Next
Print #file, "<font color='red'>Footer</font><br><br>"
Close file
Set db = ses.CurrentDatabase
Set doc = db.CreateDocument
'Create your doc.
'Add attachment to rich text:
Set richText = doc.CreateRichTextItem("Body")
Call richText.EmbedObject(EMBED_ATTACHMENT, "", "SomeFile")
Set uidoc = ws.EditDocument(True, doc)
uidoc.GotoField("Body")
uidoc.Import "html", filename$
'Process your doc.
This example generates this rich text:
Please note that this code IS NOT MINE
I took it from user John_W in a mr excel post, I'm just pasting it here because I wanted to share something that helped me as it might help others. Also, I won't link the page here because I don't think it's fair with Stack Overflow but I have a big Thank You for John_W for sharing this online.
Sub Notes_Email_Excel_Cells()
Dim NSession As Object
Dim NDatabase As Object
Dim NUIWorkSpace As Object
Dim NDoc As Object
Dim NUIdoc As Object
Set NSession = CreateObject("Notes.NotesSession")
Set NUIWorkSpace = CreateObject("Notes.NotesUIWorkspace")
Set NDatabase = NSession.GetDatabase("", "")
If Not NDatabase.IsOpen Then
NDatabase.OPENMAIL
End If
'Create a new document
Set NDoc = NDatabase.CreateDocument
With NDoc
.SendTo = "email.address#email.com" 'CHANGE THIS
.CopyTo = ""
.subject = "Pasted Excel cells " & Now
'Email body text, including marker text which will be replaced by the Excel cells
.body = "Text in email body" & vbNewLine & vbNewLine & _
"**PASTE EXCEL CELLS HERE**" & vbNewLine & vbNewLine & _
"Excel cells are shown above"
.Save True, False
End With
'Edit the just-created document to copy and paste the Excel cells into it
Set NUIdoc = NUIWorkSpace.EDITDocument(True, NDoc)
With NUIdoc
'Find the marker text in the Body item
.GotoField ("Body")
.FINDSTRING "**PASTE EXCEL CELLS HERE**"
'.DESELECTALL 'Uncomment to leave the marker text in place (cells are inserted immediately before)
'Replace it with the Excel cells
Sheets("Sheet1").Range("A1:E6").Copy 'CHANGE THIS
.Paste
Application.CutCopyMode = False
.Send
.Close
End With
Set NSession = Nothing
End Sub

Resources