I’m trying to export all of the documents and their attachments from a Lotus Notes database (with Designer 7.0). I can get the document data and can get an attachment, but only if I hard code the name. The two methods, in LotusScript, I’ve found for getting the filename programmatically aren’t working, as shown in the lower two code blocks. In the first, doc.GetFirstItem( “Body” ) returns Nothing, and in the second, there’s a Type Mismatch during execution on the Forall line.Any help on how to extract the attachments would be greatly appreciated! I’m not sure whether the attachments are stored as “attachments” or OLE, but I suspect as attachments, since they’re primarily PDFs.
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim query As String
Dim collection As NotesDocumentCollection
Dim doc As NotesDocument
Dim fileCount As Integer
Dim attachment As NotesEmbeddedObject
Dim fileName As String
Set db = session.CurrentDatabase
’ get a document that has an attachment
Set collection = db.FTSearch( "06/25/2013", 10 )
fileNum% = Freefile()
fileName$ = "c:\kcw\lotusexport.txt"
Open fileName$ For Output As fileNum%
Write #fileNum%, "docs found", collection.Count
Set doc = collection.GetFirstDocument
' write out document properties
Forall x In doc.Items
Write #fileNum%, x.Name, " = ", x.Text
End Forall
'extract document (using hardcoded name)
Set attachment = doc.GetAttachment("OCSE-FRONT_SCANTODESKTOP_06262013-104822.pdf")
Call attachment.ExtractFile _
( "c:\kcw\attachment" )
'try to get attachment through "Body", but rtitem is Nothing
Set rtitem = doc.GetFirstItem( "Body" )
Write #fileNum%, "rtitem is Nothing", rtitem Is Nothing
fileCount = 0
If Not rtitem Is Nothing Then
If ( rtitem.Type = RICHTEXT ) Then
Write #fileNum%, "rtitem is RICHTEXT"
Forall o In rtitem.EmbeddedObjects
Write #fileNum%, "has Embedded Objects"
fileCount = fileCount + 1
Write #fileNum%,"rtitem num", fileCount
Call o.ExtractFile _
( "c:\kcw\newfile" & Cstr(fileCount) )
End Forall
End If
End If
'Fails with "Type mismatch" at Forall loop
If doc.HasEmbedded Then
Write #fileNum%, "doc has embedded"
Forall objects In doc.EmbeddedObjects
Write #fileNum%, "in for loop"
Write #fileNum%, "filename= ", object.Source
End Forall
End If
Close fileNum%
You need to add error handling, or at least check the return values.
Here is a code snippet from an exporter I built:
Forall i In doc.Items
’ *** Locate attachments and detach them
If Left$(i.Name,1)<>“$” Or Lcase(i.Name)=“$file” Then
If i.IsSummary = False Then
If Not Isempty(i.EmbeddedObjects) Then
If ( i.Type = RICHTEXT ) Then
Forall obj In i.EmbeddedObjects
If ( obj.Type = EMBED_ATTACHMENT ) Then
Call obj.ExtractFile(basePath & obj.Source)
End If
End Forall
End If
End If
End If
You can’t necessarily rely on that - sometimes Notes will give the attachment an internal name rather than the actual name. This would typically be something like an 8-digit number with the correct file extension.
Some situation where this could happen is if someone attaches the same file more than once in the same document (I see this fairly often), the subsequent instances after the first will be assigned a name by Notes that it uses internally, even though the two objects actually have the same file name.
Or if a user edits a document to replace an attachment rather than edit it directly through the Notes document, and they don’t delete the old version prior to attaching the new one, it could also be assigned an internal name.
OK, dumb question first - is your RT field actually named “Body”? And if so, is that the only RT field, or could there be other RT fields where the attachment could have been placed?
Sorry, but I had to ask.
Also, what is the result of the last part of the code where you use the doc.HasEmbedded property?
The “Body” code came from the LotusScript help example. This is my first Notes assignment, so I’m not familiar with the various RT fields.
doc.HasEmbedded returns true, however when looking at the doc.EmbeddedObjects in the debugger, it is blank, which I suppose is why it throws a Type Mismatch.
Thanks for your post; hopefully the code I posted earlier works for more than just one document.