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.