Search This Blog

Showing posts with label Lotus script. Show all posts
Showing posts with label Lotus script. Show all posts

Monday, December 6, 2021

db.createdocumentcollection()

 Hi

This is unbelievable.

After 20 years of working with Notes I found out that there always was a method db.createdocumentcollection() for creating a blank collection.

Why the hell neither IBM nor HCL included it into documentation and made it public? 

Previously I always got an empty collection by either ran search with query which for sure would return nothing or used db.GetProfileDocCollection() - both these approaches worked well but made the code less obvious/self-explaining.


Dim s As New NotesSession
Dim db As notesdatabase
Dim col As notesdocumentcollection
Set db = s.currentdatabase
Set col = db.createdocumentcollection()

Sunday, August 8, 2021

Do not use NotesRichTextItem.ConvertToHTML() or use it but be ready it will be removed in the future release.

 Hi

Just a suggesstion.

Since R9(?) it was possible to use NotesRichTextItem.ConvertToHTML(), see its description here: https://help.hcltechsw.com/dom_designer/9.0.1/appdev/H_CONVERTOHTML_METHOD_NOTESRICHTEXTITEM.html

It was kind of relief to be able to use a native API instead of making those custom solutions based on MIME/DXL/XmlHttpRequest/...

However, later we noticed that every call of NotesRichTextItem.ConvertToHTML() in server agent showed this message in the Domino console: 

        CSRF Init: iNotes_WA_Security_ReturnUrlCheck> c_CSRFReturnUrlCheck: 1

It is very easy to reproduce it. Create an agent which works in server's context (run it from console or by schedule) and write something like Dim s As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Dim rtItem As NotesRichTextItem Dim html As String Set db = s.Currentdatabase Set doc = db.Alldocuments.Getfirstdocument() '<-- This is a doc with richtextitem Body Set rtItem = doc.Getfirstitem("Body") html = rtItem.convertToHTML() Domino console has to show: [0AB8:0025-08E8] 31-05-2021 16:32:21,71 CSRF Init: iNotes_WA_Security_ReturnUrlCheck> c_CSRFReturnUrlCheck: 1 [0AB8:0025-08E8] 31-05-2021 16:32:21 AMgr: Start executing agent 'testAgent' in 'test\test.nsf' [0AB8:0025-08E8] iNotes Init: Credential Store Configuration not enabled, less secure mode. [0AB8:0025-08E8] 31-05-2021 16:32:22 AMgr: Agent 'testAgent' in 'test\test.nsf' completed execution We have a big database with several RichTextItems in every document and for every such item in every document a scheduled agent does some magic and uses rtItem.convertToHTML() - Domino console spams million of such messages for more than 1 hour.

I contacted HCL regarding this and they said that they forgot to hide this method: it is not supported and will be removed in a future release, though it was reproduced even in R12.


Thursday, July 21, 2016

Avoid processing items as both NotesItem and NotesMIMEEntity objects concurrently.

Hi guys

May be this will save a day to someone.

Let's imagine you need to send email with HTML inside.
In most of cases you would need to use NotesMIMEEntity class and probably some other MIME-related classes to build mail Body. Though it is possible to use the same classes to define Subject, SendTo, CopyTo and other mail headers people often use usual NotesItem-based syntax for the rest simple mail parameters.

However very important point is that as soon as you used NotesMIME-class you can NOT use NotesItem-based syntax until you close all NotesMIME entities.

So, if you write something like below, it will be rather OK

....
Set mailDoc = db.createdocument
mailDoc.Subject ="blablabla"
mailDoc.SendTo ="test@gmail.com"

Set mime = mailDoc.CreateMIMEEntity()
.......
call maiDoc.send(false)

However, if you do it in another order you will reap problems sooner or later

....
Set mailDoc = db.createdocument
Set mime = mailDoc.CreateMIMEEntity()
.......
mailDoc.Subject ="blablabla"
mailDoc.SendTo ="test@gmail.com"
call maiDoc.send(false)

The last example can even work when you try it, but then after some time users may complain about empty mail Body or something else.

If you really need to work with mail NotesItems after you used NotesMIME-classes you have to close all MIME entities first, for example, using method NotesDocument.CloseMIMEEntities.

Actually, everything I said here you can find in description of NotesMIMEEntity class in Usage part that I personally read not carefully enough.

Sunday, May 24, 2015

How to save date in a document item without time part on back-end

Hi

This is not something really tricky but it's nice to know.

Let's imagine you need to save a single date or an array of dates without time part in a NotesDocument item. F.x. you need to do this from an agent so you don't have a form opened in UI with a date-field on it which property "Display time" is disable.

You could write something like

Dim s As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim singleDate As Variant
Dim arrayOfDates(1) As Variant

Set db = s.currentdatabase
Set doc = db.createdocument

singleDate = DateNumber(2015, 5, 22)

arrayOfDates(0) = DateNumber(2015, 5, 12)
arrayOfDates(1) = DateNumber(2015, 6, 8)

Call doc.replaceitemvalue("singleDate", arrayOfDates)
Call doc.replaceitemvalue("arrayOfDates", arrayOfDates)
Call doc.save(True, False)

However if you check the item value you will see that there is a time part near each date value



Thursday, May 21, 2015

How to export Outlook email to Notes mail database

Hi

Here is a working example of my solution which let you export Outlook email to Notes document.

You might see many other similar examples in Internet but my solution handles inline images and attachments. I remember when I was looking for such solution, everything I could find was partly done, so here you probably have the best working example :-)

ypastov.Outlook2Notes.nsf

Few things:
1) Database contains only one agent that does the magic.
2) The agent saves Notes document created from Outlook item in the current database. However the best thing would be to save it into Mail database because it would automatically do some tricks with inline pictures.
3) I didn't implement smart switching between Notes/Outlook windows so if you run solution and see nothing try to switch between Notes/Outlook - probably there is some dialog window waiting for your decision.

Enjoy.

Btw, as you can see this solution start working from Notes client. However recently I developed Outlook Add-in that provided Outlook users with a new button on existing ribbon and let them save email in the Notes Mail database - the same business case but implemented in more native way for Outlook users than clicking some button in some Notes-database.

26.10.2016
Short update.
For months of using my Add-in in production we experienced different issues with fetching SMTPAddress of recipients, senders. I found the way how to fix all issues but decided to not open that code in public since I put there much efforts and time. So, in case you really need to resolve similar issues please contact me privately.

Wednesday, December 17, 2014

How to focus Lotus Notes window (standard version)

Hi guys

Currently I am working on VB.Net Add-in for MS Outlook 2010 that allows to copy Outlook mail item to Lotus Notes mail database. I am almost completed it and though I met many interesting challenges on my way one of the most interesting was about focusing of Lotus Notes window.

Solution architecture was following: Outlook Add-in (a button in Outlook explorer/inspector ribbon) gets ID of selected/opened Mail item, creates OLE object of Lotus Notes, passes that ID to notes.ini and finally calls a NotesAgent that does the rest of a job using lotusscript.

The NotesAgent asked user several questions during its work so I had to switch focus to Lotus Notes window at some point. Native ActivateApp() function didn't work neither in Add-in VB.Net nor in NotesAgent lotusscript. After Googling a little I found a couple of suggestions based on Windows API:

Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdSHow As Long) As Long


hWin = FindWindow("NOTES", &H0) 'I used lpClassName = "NOTES" because it looked logically and
                                                             ' because all examples in Google did the same.
Call ShowWindow(hWin, 3)

I utilized this workaround in my NotesAgent and on first sight it worked well.

Saturday, November 22, 2014

How to find out if PIRC is enabled programmatically

Hi

Need to find out if PIRC is enabled programmatically?
I didn't find any other way as through Domino console output.
At least C API toolkit does not have anything.


You can do something like this:
response = session.Sendconsolecommand(servername, {show dir -pirconly"})
If response <> "" then
If InStr(1, response, targetDb.filepath) > 0  Then
IsPIRCEnabled = "1"
Else
IsPIRCEnabled = "0"
End If
Else
IsPIRCEnabled = "-1"
End if

Wednesday, October 29, 2014

NotesDatabase.Server - returns server name in any format

Hello

Though I work with Lotus Notes as long as I remember myself as a human being I still can be surprised by things which I thought I knew at the level of reflexes.

Did you know that NotesDatabase.Server property may return server name in ANY format?

I didn't. Today I discovered that and after quick research I found this article.

In my case I got NotesDatabase server as a NotesDocument.ParentDatabase property.

So, from this day I will always use explicit name casting, like NotesSession.CreateName(name).Canonical

Monday, August 25, 2014

A bug in NotesDatabase.Search() ?

Hi

I think I have found a bug in NotesDatabase.Search() function.
Or it is a bug in a While statement, not sure.

Let me explain.

If you define 3rd parameter in NotesDatabase.Search() to set a number of documents you want returned and then try to enumerate documents in block While you will see that code will pass through ALL documents  no matter how many documents are in collection.
NotesDatabase.FTSearch() instead works OK.

See example below.

"Delete doc" vs "set doc = nothing"

Hi

Just noticed a funny thing regarding using "Delete doc" against "set doc = nothing".

I always though if you delete a local reference to some object declared inside of sub/function it will not affect on another reference to the same object but in parent sub/function.
It's like a common thing about variables scope.

However it looks like it works differently with objects received from NotesUIWorkspace (and probably NotesSession). May be because NotesUIWorkspace and NotesSession are global objects, not sure.

Look on example below:

Sub Click(Source As Button)
Dim w As New notesuiworkspace
Dim doc As notesdocument

Set doc = w.CurrentDocument.Document

Call mySub()

Msgbox doc.Created <--Error here
End Sub
Sub mySub()
Dim w As New notesuiworkspace Dim note As notesdocument Set note = w.CurrentDocument.Document Delete note
End Sub


Sub Click(Source As Button)
Dim w As New notesuiworkspace
Dim doc As notesdocument

Set doc = w.CurrentDocument.Document

Call mySub()

Msgbox doc.Created <--No error
End Sub
Sub mySub()
Dim w As New notesuiworkspace Dim note As notesdocument Set note = w.CurrentDocument.Document set note = nothing
End Sub


Saturday, July 26, 2014

NotesItem.Type = 256 causes "Variant does not contain a container"

Hi

Today I had to convert a collection of NotesDocuments for some external system.
For one particular document I received an error "Variant does not contain a container".
When I checked it in Domino Debugger I saw that error happened at the line contained following code:

......
if cstr(doc.getitemvalue("itemname")(0)) <> "" then '<---error here
       .....
end if
.....

Code looked pretty simple and completely correct and though this error message was familiar for me I couldn't get why it happened there. I understood what was wrong only after I found that particular document and checked what was in that item.

Thursday, May 29, 2014

You can't have an empty item 'SecretEncryptionKeys' in NotesDocument if there is no encryption enabled field on form

Hello

Probably you know, that item "SecretEncryptionKeys" is used for keeping a list of secret keys which are used for document fields encryption. IBM Lotus Notes creates this item automatically if you enable encryption for any field and select secret key on the last tab of form properties window.


Recently I had to remove such encryption for one application that used it before.

How to create a NotesDocument with creation date in the PAST or in the FUTURE

Hi guys

You may know that UniversalID (as ReplicaID) is relative to the Date-Time when it was generated.
Here I have described my finding regarding it.

However later I discovered even more interesting thing.
As you may know UniversalID property of NotesDocument class is Read/Write and you may assign required UniversalID to existing/new NotesDocument. The most important thing about it is that together with UniversalID you also set an initial creation date-time that was at the moment when your UniversalID was generated.

This is very interesting thing and, honestly speaking, I am not so sure that this is good.
I can't get all consequences of such behavior, especially regarding replication but just imagine - you can create a document with the creation date that is earlier than you have started to work in your company, break something and then say: "sorry, I have no idea what happened but as you see the document was created when I wasn't born yet" :-)

Check screens below

Server agents with "Run as Web user" or "Run on behalf of" property enabled which run on NotesDocuments with READERS fields - IMPORTANT!

Hello guys

I think this will be interesting for you.

If you have a server agent with "Run as Web user" or "Run on behalf of" property enabled and it works with NotesDocuments which have READERS fields inside you always have to do additional validation against empty NotesDocument.Items property.

It is absolutely not obvious but it is a critical thing.

I'll show you.

NotesAgent.Runwithdocumentcontext() - cool thing

Hi guys

I would like to pull your attention to method Runwithdocumentcontext() of NotesAgent class.

I personally missed this method somehow and found out about it just recently though it was released with IBM Lotus Notes 8.5.2.

It finally allows developers to pass a non-saved NotesDocument to a NotesAgent. Let me explain.

I believe all of you had a task where you needed to pass many constants/parameters/fields to a NotesAgent to let the agent to do some work. Earlier (prior LN 8.5.2) we had only two methods for that:

  • NotesAgent.Run(noteid)
  • NotesAgent.RunOnServer(noteid).

Notice, since these two methods work with NoteId it is required to save document to be able to pass it to NoteasAgent.

I usually created a temporary document, put required parameters there, saved document and then passed its NoteId to one of the methods mentioned above depends of what I need to rich.

However...

Tuesday, April 15, 2014

Wrong name of attached file in inbound email: "=?UTF8?Q?=....

Hello guys

Last week I have fought with a very strange issue: from time to time inbound emails from one particular sender contained attachments which names had issues with encoding.

Just to show you I have copied such email with two Excel files attached to my test database.
I know that these two Excel files have non-ASCII characters in their names (they have Ukrainian characters actually) but I have never experienced any issues with sending/receiving files with non-ASCII characters in Lotus Notes.
However, as you can see below, @AttachmentNames returned file names with encoding issues in their names.

Sunday, March 23, 2014

@Text(value; "*") - undocumented parameter "*" for @Text() function

Hi

Recently I needed to work with ReplicaID item from Catalog documents (catalog.nsf) and discovered that ReplicaID item contained Date-Time value instead of 16-character combination of letters and numbers that I used to work with.



Of course, I knew that there is some dependency of ReplicaID/DocumentUniqueID on its creation date-time but I had never focused on that too much.

But now I realized that I would like to know more.

I didn't find too much information about that in Internet though.
What I found out so far:

Friday, January 31, 2014

Comparison of variant value with a number in one step

Hi

Sometimes you may need to compare some field value with a particular number in one step.
F.x. you may have something like this:

if <expression> then

elseif <expression> then

elseif <expression> then

end if

However if a field of a Number type is empty

 then its value has Text type


My suggestion is next

Thursday, January 23, 2014

An issue with Script Debugger - cannot use it for debugging one of my NotesAgents

Hi guys

Today I have experienced a very strange issue with debugger when I tried to debug one of my Notes Agents. The issue is that when script debugger window pops up I can do nothing with it.
Look on my screen:

I have tried to resave the agent and Script Libraries it used but it didn't help.
I do not want to recompile all lotusscripts because I do not want to override signatures of other developers.

Do you have an idea?

Notes 9.0.1


Always do recompile of all lotusscripts after change of any lotusscript constant

Hello guys

At first I wanted to write a post about new issue in LotusScript I found today but after double check with documentation I had to calm down :-) Really, RTFM first.

The case is about using of constants in lotusscript.

Let's imagine that you have two Script Libraries. The first SL has some constant in (Declarations) and the second SL uses the first SL. If you change the constant in the first SL you NEED to resave/recompile the second SL, otherwise the second SL will remember the old value.

Check my screen shots below