Greg Gessel writes to ask:
Using LotusScript, is it possible to attach a file to a Notes document using the V2-Attachment style where the Notes document does not contain a Rich Text field? I am maintaining an old web app where the attachments are all V2-Style and I need to do some updates to the attachments. With LotusScript I can find, detach, and remove without any issue problem, I just can’t add, replace or rename. Thanks!
As Greg found, the API doesn’t contain functions to directly support this. I thought to try attaching the files to a hidden rich text item — one that’s not on the form — and then deleting the rich text item, leaving just the attachments. But LotusScript is too smart for that — when you delete rich text items it also deletes the $FILE items to which they refer.
However, it’s possible to do exactly this with DXL (or with the C API functions called from LotusScript, but that’s always my second-to-last choice — right before using LS2J to call Java functions).
Specifically, to do it with DXL, you would create the document with an attachment in a rich text field, export the document as DXL, run the output through an XML parser to remove the rich text item, but don’t also remove the $FILE item(s) corresponding to the attachments.
Option Public
Option Declare
Sub Initialize
Dim ses As New NotesSession
Dim coll As NotesDocumentCollection
Dim db As NotesDatabase
Dim docCur As NotesDocument
Set db = ses.CurrentDatabase
Set coll = db.UnprocessedDocuments
Set docCur = coll.GetFirstDocument
Do Until docCur Is Nothing
Call ses.UpdateProcessedDoc(docCur)
Dim dxle As NotesDXLExporter, dxli As NotesDXLImporter, domp As NotesDOMParser
Set domp = ses.Createdomparser
Set dxle = ses.Createdxlexporter(docCur, domp)
dxle.Richtextoption = RICHTEXTOPTION_RAW ' because rich text in DXL format doesn't round-trip perfectly.
dxle.Process
Dim nl As NotesDOMNodeList, el As NotesDOMElementNode, i%, bMod As Boolean
Set nl = domp.Document.Documentelement.Getelementsbytagname("item")
For i = 1 To nl.Numberofentries
Set el = nl.Getitem(i)
If el.Getattribute("name") = "Attach" Then
el.Parentnode.Removechild el
bMod = True
Exit For
End If
Next
Set docCur = coll.GetNextDocument(docCur)
If bMod Then
Dim stream As NotesStream
Set stream = ses.Createstream
domp.setoutput stream
domp.Serialize
Set dxli = ses.Createdxlimporter(stream, db)
dxli.Documentimportoption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE
Call dxli.Import
End If
Loop
End Sub
The above code sample assumes the documents have already been saved and the agent’s selection criteria is selecting them. The rich text item “Attach” wouldn’t need to be on the form — it can be created by back-end code specifically to have something to attach the file to.
You can do the same thing with a document you created in memory, or a previously existing document in memory that you modified by adding the Attach field to but haven’t saved yet (as would likely be Greg’s case).
One other option to look into in the specific case Greg poses, is whether it actually matters to the application whether the attachment is V2-style versus in a rich text field that’s just not on the form. The web server and Notes client treat these cases the same as a V2-style attachment — they’re displayed under a line below the document.
If you find this website helpful and want to give back, may I suggest buying, reading, and reviewing one of my excellent books? More are coming soon!
If you want email whenever there’s a new post, you can subscribe to the email list, which is 100% private and used only to send you information about stuff on this site.
If you did want to use the C API, that would likely give much better performance, but I didn’t try to code that one.