Appending text to a RichText item ("Body") is resulting in TWO Body items...why? - lotus-notes

An email arrives into a mail-in database. I look at it and see that it has a single Body item, which is Rich Text.
In an agent run after new mail arrives, I want to update the arriving memo, and append some text to that Body item and then save it. I use getfirstitem to get a handle on it, and then use AddNewLine and Appendtext in successive lines of code, adding a bit of text to it, before saving it.
After this is done, I look at the backend document again and where there used to be a single Body item there are now two. Each has a portion of what I expected a single item to have. Between the two, nothing is missing.
Note: The incoming email also has attachments...but it did originally before I updated it and again, there was only one Body item.
Note2: Sending the email from Outlook. How that could be related I don't know.
What could be causing this or what might I do to work around this. Open to all suggestions/ideas.
Thank you
Matt Smith

If you call Compact on the Body after you've finished adding to it (and before saving if you do an explicit save), that might reduce it to a single item, but it's not guaranteed.
There are cases where Body is forced to be 2 or more items. E.g.:
If an email comes in as MIME (which is common for emails from outside your network), each MIME part is always a separate Body item, and there are normally 2 or more MIME parts for a single email.
I think each rich-text item has a strict 64 kB size limit for the raw data, so content exceeding 64 kB will always be 2 or more items, but I'm not sure of this.
As others have said in comments, it's normal to have more than 1 item for rich-text content. You should never have to care about this. If you use GetFirstItem to get a rich-text item and add text to the end of it, it will act like one item from an end-user perspective.

I decided on another way to accomplish what i needed, not appending text, so this question is no longer in need of help, other than to sate my own curiosity. Thanks guys.

Related

Adding and Removing Fields Programmatically on Forms

Sorry this isn't a specific coding question, it is more of a design concept.
What is the usage case for programmatically adding and removing fields to Notes Forms e.g. NotesDocument.RemoveItem(), ie why would you add and remove fields in the background?
For many years I have designed my forms with the fields layed out on the form which are required and then hide and show as required.
By adding dynamically you can't position them and frustratingly removing them or deleting they still appear the Database Fields in Domino Designer, getting rid of them is a bit a a black art, but that's another story.
I must be missing a trick or a basic design concept. Any thoughts on best practice would be appreciated.
Many thanks.
Yes, you are missing the difference between "Fields" and "Items". A field is a design element that you can place anywhere on your form. You define how it looks, what content it contains, what datatype it is, etc.
When creating a document with the form the value of the FIELD is stored in an ITEM in the resulting NotesDocument.
This item is totally decoupled from the field that created it. If you were to change the field in the form from text to number or move it around or make a names- field of it, the item in the existing documents would never change unless you open the documents and save them in frontend or use any LotusScript or Formula Code to recalculate the document in backend.
Very often items are added programmatically to documents to fulfill different purposes: Calculate values to be displayed in views, calculate values that are import for the workflow but not for the user, etc.
Complex applications often consist of a lot more items than there are fields in the several forms.
Back to your question: Removing an item from a document simply removes the value that was created by the field in the form. When reopening the document, the item will be repopulated, either by default value or whatever....
Usually you would use this to remove items that you no longer need (and probably already removed from the form).
As soon as you removed all references to a field / item everywhere in design and documents, you can finally get rid of it completely by compacting the database.
An item is distinct from a field in Notes. The form is purely a UI concept, the item is what the data is stored in.
Manipulating data in the backend can be used for a number of reasons. One such use case is the setting of a flag when a date on the form has expired.
Say you want a view showing all documents that have expired. Your rules dictate that documents are considered as "Expired" after 7 days. You could create a view with a formula that shows all document whose date is 7 days older than today:
SELECT Date < #Adjust(#Today; 0; 0; -7; 0; 0; 0);
This view will ALWAYS be out of date and will constantly be updated by the server as it re-evaluates #Today.
Now, a better way would be to create an agent that runs daily that sets an item on the document to indicate that it has expired e.g.
#SetField("Expired"; 1);
The view formula would then be
SELECT Expired = 1
The view would only need to update daily and you have a much faster view because of it.
RemoveItem is used to get rid of data no longer needed e.g. FaxNumber.
There are many use cases for RemoveItem. Here's one that comes up frequently.
You have a database and an agent that processes documents in that database. Every time it runs, the agent replaces the value of a bunch of items. There are a variety of error conditions that can cause it to abort processing a document early, but you're a smart programmer and you've accounted for that with on error traps. When you hit one, you log an error message, save your document, and then either abort your agent or go on to processing the next document.
But at this point, some of the items that the agent normally updates have values saved from this run, and some of them have values saved from a previous run. This might be bad. This might be confusing for someone who is looking at the item values and trying to figure out what's going on. This might even cause validation errors on the form.
So how do you avoid this? At the very beginning of your agent, you call a cleanup sub that finds and removes all the items that the agent is going to update. Now you have a clean slate, and if your agent hits that error condition, it can save whatever it can save without any concern about whether it is leaving things in an inconsistent state. Of course, in cases where you are doing this to avoid validation errors, your validation formulas will have to be smart enough to be checking #IsAvailable for dependent items, but that's a good practice anyhow.

Removing hotspots from body using Lotus notes C API

I am trying to remove hotspots from Note body using C API.
I know one way to do this:
1) NSFNoteOpen(hDb, noteId, 0 /*NO FLAGS*/, &hNote);
2) Enumerate allTYPE_COMPOSITE items, Keep appending all CD records in separate buffer except records between SIG_CD_HOTSPOTBEGIN and SIG_CD_HOTSPOTEND
3) remove this item and append newly created item.
4) NSFNoteUpdate(hNote, UPDATE_FORCE);
But problem is that, all Rich text infomations is lost
Is it possible to achieve the same when note is opened with
OPEN_RAW_MIME flag? There are no TYPE_COMPOSITE items in the note in this case.
Thanks
You need to determine the type of the Body field and act accordingly. I.e., if the Body is stored as TYPE_COMPOSITE, you already know what to do. But if the Body is stored as TYPE_MIME_PART, you need to use the Notes C API calls whose names all start with "MIME". You can find these functions listed in the Notes C API Reference. Here are a couple of blog posts that talk a bit about some related subjects.

iText page number references

I am generating a large document that will have many references to other pages in the document. For instance, the text might say:
"This topic is covered in Chapter 46 (see page XX)."
or
"See the chart on page XX"
Since I don't know the page number ahead of time, my initial thought was to create the PDF in multiple passes, as outlined in "iText in Action", chapter 6. However, as I understand it, this would not work because the PDFStamper cannot edit existing chunks of text once they are created. My second thought is to create the document twice. The first time, I would create the document and simply make a hashmap of referenced places in the text and page numbers. The second time, I would use those to generate references.
Is there a better way to do this?
Create a PdfTemplate as placeholder for all the unknown data, store these in an array.
Mark the referred text with onGenericTag() and fill out the templates stored in the array with the page number.
Main problem: how to define the size of the PdfTemplate? That problem can't be solved.

Custom memo field isn't copied to Reply or Forward in Lotus Notes 6.5

I work in a development/support team which has a shared Lotus Notes mailbox. We need to be able to associate an issue ID with each email. We started by adding this ID to the subject line (eg. "Something doesn't work [ID12345]"). For performance reasons, our IT dept don't allow indexing of shared mailboxes, so it takes a long time to search for a particular ID.
I decided to add a new ID field, which can be shown as a sortable column in views and folders. I put this field to the visible header (just below 'Subject') in the ($All) view and the ($Inbox) folder, and copied the ($Inbox) design to all the other folders in the database. That much was easy.
My problem is that when we reply or forward, this custom field is not carried over to the new memo, so we have to manually add it again before sending. And of course when the user responds, the field is again missing and must be manually added. I have searched the docs and the internet and haven't found any information on this. Either I have to declare this field as something which persists across replies and forwards, or I have to add a line somewhere which explicitly copies the field contents to the new memo.
fsw,
We do exactly this with our complaint system however our database is indexed although this should not be an issue to you. We created a view that is sorted by ID by extracting just the ID from the subject line, order it by ID and then by date descending. Base it on the $ALL folder view so you get both incoming and sent emails.
We then altered the memo form to include an embedded view single category of the new view that sits above the body which shows all other documents linked to the ticket.
This should avoid having to delve to far into the very complex mail template any further. One thing is to make sure you have a copy of the changes you made and a bit of doco re deploying as you can guarantee that one day your template will be completely overwritten in an upgrade and all your good work will be gone.
As the additional field would have to incorporated into all Memo forms in mail templates in your corporation and as these fields do not easily travel via SMTP, you should stick with the ID in the subject.
What you could do is to parse the subject (#Mid, #Right, ...) in the column formula in the view and only display the ID there (like you did with the additional field).
The other option I envision if having a field is required is to have an agent that processes the incoming message(reply) to have it parse out the issue ID from the subject and write it to the field. You could also do that with queryopen or postopen if running an agent is not possible

WATIR: how do drive outlook web access

since the emails loads dynamically how do you find a specific email that contains a button back to your site. This is like signing up at a site. Customer receives email to confirm.
Thanks for the support
BigD
OWA, bless MS's little hearts (at least in the circa 2003 version I'm looking at here) uses frames, so first of all brush up on that or you are gonna be hating life. The list of incoming messages is in a frame named 'viewer' The message summaries are contained in a table lacking any useful means to identify it that is in a div of class 'msgViewerCont" and an ID of dvContents. So to see if a message exists you want to look to see if you can find a row in that table which contains the subject you expect to see.
(be careful using ID values on OWA.. apparently nobody in the group that developed it read the part of the HTML standard that specifies that ID values are supposed to be unique.. the re-use them all over that page.)
Presuming you know the subject of the message you are about to receive, and also that you keep that mail account cleared out so that it will be the ONLY message there with that subject line, then you can check to see if it exists usng
subject = regex.new("subject you are looking for")
browser.frame(:name, 'viewer').div(:id, dvContents).table(:index, 1).row(:text, subject).exists?
to click on it use .click instead of exists.
once you've clicked it, OWA will refresh the PreviewPane iframe.. inside that iframe is another one that has the message body in it.
all those frames, are nested inside the viewer frame. welcome to nested frame hell. hope you enjoy your stay. (like I said, bone up on frames, you're in for a fun ride)

Resources