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")
Related
I am new to the VBA coding. I am currently making a ms access db for printing official letters using mail merge. I have already make that happen. Now I want to make a button that saves the current record to db and simultaneously print to word file using the mail merge option.
It will be really helpful for me if you solve this problem.
Thanks in Advance.
I have a word document that uses mail merge feature and gets its information from the access db. When I use this code it does not open the word document with the current information. It opens the word document with the last saved information.
If I open the word document on its own, from the task bar, it asks if I want to run the SQL and I click yes and everything operates normally. I want to click a button from within access to accomplish this same task to open the contract.
here is the code if it can help:-
Private Sub Command205_Click()
Dim LWordDoc As String
Dim oApp As Object
'Path to the word document
LWordDoc = "C:\Users\.....k Up\01- Proposal\contract.docx"
If Dir(LWordDoc) = "" Then
MsgBox "Document not found."
Else
'Create an instance of MS Word
Set oApp = CreateObject(Class:="Word.Application")
oApp.Visible = True
'Open the Document
oApp.Documents.Open FileName:=LWordDoc
End If
End Sub
I am creating a Form on Access. This Form has source controls to an underlying Access DB. This Form is ONLY INTENDED for insertion of a new record into the DB (No intention of modifying any of the DB's existing data).
In the Access DB, there is a field for Attachments. And on the Form, there is an Attachment Control that is Source Controlled to the Attachments field in the Access DB. The Attachment Control allows users to select files and attach to the form's current record.
I have tried closing the Form and re-opening, but that means the form goes through its life cycle, and does the BeforeUpdate()+AfterUpdate()! This means that the data on the Form that was just recently closed, was entered into the DB. I don't want that!
For the reason that this Form is only for creating new records into the DB, I want a button that can wipe the current Form clean, without the Form doing its BeforeUpdate()+AfterUpdate() methods, which means I can't close the Form and re-open it. I have got most of the Controls on the form figured out in terms of giving it default values. My only problem is resetting the Attachment Control.
What is a programmatic way (In VBA or some other language, DAO?) to remove entries on this Attachment Control (Not the Attachment Field in the DB, but the actual data on the Form currently being used)?
I am aware that in BeforeUpdate(), you may cancel the form's update by setting its Cancel = true in the definition of BeforeUpdate(). But there should still be a way to programmatically deal with Attachment Control (Not the attachment field, I know DAO can handle that easily), it just seem stupid not to have a way for it.
(EDIT) Addon 8/30/19:
It's a better idea to store the pathname of the file in your Access DB rather than the attachment it self, and then do a file copy from one location to another (Looks at the code below as my example). And this is exactly what I did, so I don't have to deal with the attachment control. I have found this control to be too limiting in terms of the programmatic-actions that it can offer to developers.
Dim fso As Object
Set fso = VBA.CreateObject("Scripting.FileSystemObject")
On Error GoTo DebugMsg ' DebugMsg is where I defined what happens on Error
fso.CopyFile srcPath, dstPath, False
The attachment field holds a subrecordset of type Recordset2, so you must deal with it as such:
Private Sub DeleteCurrentAttachment()
Dim Records As DAO.Recordset
Dim Attachments As DAO.Recordset2
Set Records = Me.RecordsetClone
Records.Bookmark = Me.Bookmark
Set Attachments = Records!YourAttachmentFieldName.Value
While Not Attachments.EOF
Attachments.Delete
Attachments.MoveNext
Wend
Attachments.Close
End Sub
Open the form in design mode.
Then in the Form property's > in Data Tab > set Data Entry to True.
add Event to the form
Private Sub Form_AfterInsert()
DoCmd.RunCommand acCmdRecordsGoToNew
End Sub
All this action will insure that you are all the time in new record mode .
I am trying to write VBA code that will read data from fields in a Lotus Notes document. Currently, I am able to read data using the FieldGetText method, however this only works when I have the document open. I need to be able to loop through documents without opening them, as there are several hundred. I need to be able to read these same fields from many documents, but cannot figure out how to loop through them. My code currently is:
Set LotusNotes = CreateObject("Notes.NotesUiWorkspace")
Set CurrentDoc = LotusNotes.CurrentDocument
While Not (CurrentDoc Is Nothing)
' Affectation of data
DueDate = CurrentDoc.FieldGetText("RevDueDate")
DueTime = CurrentDoc.FieldGetText("RevDueTime")
DateClosed = CurrentDoc.FieldGetText("DateClosed")
Wend
I understand that this uses a Front End object. I was able to use a Back End object that could loop through documents (without them being open), however the data (for the dates, specifically) did not match the field text from the documents. That code looked like this:
Set LotusNotes = CreateObject("Notes.NotesSession")
Set db = LotusNotes.GetDatabase("")
Set view = db.GetView(view_name)
view.AutoUpdate = False
Set columnview = view.AllEntries
Set doc = view.GetFirstDocument
While Not (doc Is Nothing)
revDate = doc.GetItemValueDateTimeArray("RevDueDate")
revDate = doc.RevDueDate
Set doc = view.GetNextDocument(doc)
Wend
Basically, I'm just wondering if it's possible to loop through multiple files using the NotesUIWorkspace class that I tried first, or if it's possible to somehow use FieldGetText in the NotesWorkspace class instead.
Any help is appreciated, thanks.
You're using the Notes "front-end" classes rooted at Notes.NotesUIWorkspace. These are OLE classes, which means that they need the Notes client to be running and they work on the open document. There are also back-end classes rooted at Notes.NotesSession. These are also OLE classes, so they still need the Notes client to be running but they can access other documents (and other databases, servers, etc.). There is also a set of back-end classes rooted at Lotus.NotesSession. Note the different prefix. These are COM classes, so they do not need the Notes client to be running - though it does have to be installed and configured, and your code will have to provide the user's password since the client won't prompt for it.
You can find documentation and examples for the NotesSession class here. Down near the bottom of the page, you'll find links to information about using them via OLE or COM. You can find a bunch of examples based on using the COM classes here, including one that traverses the documents in a view in database. Apart from the inital setup of the session, it would be the same if you use OLE.
It is possible, and also better to use the 'Back end' object Notes.NotesSession. So try this:
Set doc = view.GetFirstDocument
While Not (doc Is Nothing)
'Check if you have the field in the document
if doc.HasItem("RevDueDate") Then
revDate = doc.getFirstItem("RevDueDate").Text
End If
Set doc = view.GetNextDocument(doc)
Wend
It is also possible to use Notes.NotesUiWorkspaceobject by opening every document in the client, getting the fields data and closing the document but I would highly recommend NOT TO make it like this as there is high possibility that you will crash the Notes client, if you need to loop on more documents.
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 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!