Extracting attachments from two rich text fields i

2019-08-13 22:03发布

问题:

I am extracting attachments in a document to user's local machine using LotusScript. The document has two rich text fields Body1 and Body2 and many a times only one of them has an attachment in it. I am using the below code snippet:

Dim doc As NotesDocument
Dim richTextItem As NotesRichTextItem
.....
.....
If doc.Hasembedded Then
    Set richTextItem = doc.Getfirstitem("Body1")
    ForAll o In richTextItem.Embeddedobjects
        Call o.ExtractFile(dirName + "\" + o.Name)
    End ForAll

    Set richTextItem = doc.Getfirstitem("Body2")
    ForAll o In richTextItem.Embeddedobjects
        Call o.ExtractFile(dirName + "\" + o.Name)
    End ForAll
End If

The problem is that if Body1 does not have attachment in it and Body2 does then the above code throws error of Type mismatch on statement ForAll o In richTextItem.Embeddedobjects and vice versa as there are no embedded objects in that rich text item. Also doc.Embeddedobjects does not work because attachments are present inside rich text items. And the NotesRichTextItem class does not have Hasembedded property which can be used to check presence of attachments in it.

What would be a way out of this?

回答1:

Try this instead:

Dim doc As NotesDocument
.....
.....
If doc.Hasembedded Then
    Set richTextItem = doc.Getfirstitem("Body1")
    Set rtnav = richTextItem.CreateNavigator

    If rtnav.FindFirstElement(RTELEM_TYPE_FILEATTACHMENT) Then
        Do
            Set att = rtnav.GetElement()
            filepath$ = dirName + "\" + att.Source
            Call att.ExtractFile(filepath$)      
        Loop While rtnav.FindNextElement()
    End If

    Set richTextItem = doc.Getfirstitem("Body2")
    Set rtnav = richTextItem.CreateNavigator

    If rtnav.FindFirstElement(RTELEM_TYPE_FILEATTACHMENT) Then
        Do
            Set att = rtnav.GetElement()
            filepath$ = dirName + "\" + att.Source
            Call att.ExtractFile(filepath$)      
        Loop While rtnav.FindNextElement()
    End If
End If

You may also want to extract the redundant logic into a subroutine.



回答2:

This is a short code if you want extract all attachments of a document no matter where they are stored:

Dim vAttachmentList As Variant
vAttachmentList = Evaluate("@AttachmentNames", doc)
If vAttachmentList(0) <> "" then
    ForAll sAttachmentName In vAttachmentList
        Call doc.Getattachment(sAttachmentName).ExtractFile(dirName + "\" + sAttachmentName)
    End ForAll
End if


回答3:

Updated answer

Instead of accessing the EmbeddedObjects property directly in the forall, assign it to a variant and check it first, using the TypeName function to make sure that the returned value was really an array of NotesEmbeddedObject objects, like this:

dim objectArray as variant
If doc.Hasembedded Then
    Set richTextItem = doc.Getfirstitem("Body1")
    Set objectArray = richTextItem.Embeddedobjects
    If TypeName(objectArray) = "NOTESEMBEDDEDOBJECT( )" Then
        ForAll o In objectArray
            Call o.ExtractFile(dirName + "\" + o.Name)
        End ForAll
    End If
End If