Extracting attachments - doc.GetFirstItem("Body") returns Nothing

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%

End Sub

Subject: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

See my response to your question on StackOverflow as well. types - How to retrieve Lotus Notes attachments? - Stack Overflow

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

End If

End Forall

You can rea dmore about my exporter here: Notes XML Exporter

Subject: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

I found that the filename is stored in Items, in the $FILE item. This code gets the filename then extractst the file:

Dim item As NotesItem

Set item = doc.Items( 0 ) 'assumes first item is $FILE

Dim attachmentName As String

attachmentName = item.Values(0)

Write #fileNum%, "attachmentName= ", attachmentName

Set attachment = doc.GetAttachment(attachmentName)

Call attachment.ExtractFile _

( "c:\kcw\" + attachmentName)

Subject: RE: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

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.

Subject: RE: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

The Source property will always give the original name of the file, while the Name property potentially will give your the internal name.

Subject: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

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?

Subject: RE: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

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.

Subject: RE: Extracting attachments - doc.GetFirstItem(“Body”) returns Nothing

In that code, “Body” is the name of the field where the files are attached.

You need to look at your form design and determine the name(s) of the rich text field(s) and then modify the code to use your actual field names.