|
|
 | Category: Lotus Notes Domino
|
| Here is a simple example of how to easily achieve Ajax-functionality with Domino and Ext.js. The idea is to, from a page that is opened in a web browser, call a Domino agent asynchronously and in the background to do some work and to provide feedback on it. The page is then updated when the work is done. 1. Download the Ext core (). This is a JavaScript library that among others contains functionality that can be used to achieve Ajax functionality easily. 2. Copy the contents from the JavaScript file 'ext-core.js' 3. In your Lotus Notes database, create a Javascript library named ext-core.js and paste in the copied content from step 2. 4. Create a page with some Pass-Thru HTML. - A button which when clicked on runs a JavaScript function 'runAjax();' - A div-tag in where the result from the Ajax query is displayed <table> <tr><td><input type="button" value="Run" onclick="runAjax();" /></td></tr> <tr><td><div id="results"></div></td></tr> </table> |
5. Add a script tag in the 'HTML Head Content' section of the page to include the JavaScript library to the page. | <script type='text/javascript' src='ext-core.js'></script> |
6. Define the Javascript function 'runAjax()' in the 'JS Header' section of the page. This function calls an url, in this case a Domino agent, which is run. If the agent was run successfully and the call and response was successful we can decide what to do. Here we update a div on the page with the response from the agent, i.e. what the agent prints. function runAjax() { Ext.Ajax.request({ url: 'myController?openagent', method: 'GET', success: function(response, opts) { document.getElementById('results').innerHTML = response.responseText; }, failure: function(response, opts) { alert('server-side failure with status code ' + response.status); } });
} | 7. Create the agent 'myController'. The idea with the agent is to have it run the actual logic and that would be work with Domino data for searching or modifying for example. The agent could just do something with data but also send back information or status to the page that called it. In this example the calling page only runs the agent and the agent only prints a text line as a response or feedback. Sub Initialize() Print "Foo bar" End Sub |
8. Done! Open the page in the web browser and click the button. The text 'Foo bar' should be displayed shortly in the div. Note: This does not work in the Notes client, only in a web browser. |  |
 | Category: Lotus Notes Domino
|
| I wanted to create a simple XPages application for a specific purpose but since I haven't learned that yet and didn't have the extra time to do so either I had to go for the old style version. So I created a web form with some JavaScript and CSS. What I explain below is probably old news for most of you but I wasn't aware of this so I'm sure there are others. I created a form with passthru HTML and added combo boxes to be able to select values from. The values were taken from a DbLookup from a keywords view. This looked fine and also worked fine in Firefox and Google Chrome. But for Internet Explorer (7) the values wasn't passed when clicking save and calling the submit function. So I checked the source code and saw that the options lacked values. For Internet explorer the select box was built like this: <select> <option>Value 1 <option>Value 2 <option>Value 3 </select> |
And hence no values were passed. For Firefox and Chrome however the select box was by default built this way: <select> <option value="value1">Value 1</option> <option value="value2">Value 2</option> <option value="value3">Value 3</option> </select> | The workaround:Since I didn't need to save the values chosen but only needed them to save to other fields I could instead print HTML in a computed text that allowed the select box to print correctly also for IE. Here's the formula code for that: tmp := @DbLookup(Notes:Recache;"":"";"LookupKeywords";"Keyword";"Values"); str := "<select id='someId' class='comboboxCssClass'>"; str := str + @Implode("<option value='" + tmp + "'>" + tmp + "</option>"); str := str + "</select>"; str |
|  |
 | Category: Lotus Notes Domino
|
| I have been taking it slow with Notes and Domino for the past year because of other obligations. Now I got the opportunity to create a webapp and I decided to do it in Lotus Notes and I thought I should go for Notes 8 and XPages to get a nice feeling for the user. I have to develop it in a pretty short time frame as well.
So I need to search and browse through some material for documentation and examples to get started. Do you recommend any special source on documentation, references or examples regarding XPages that I could use?
Any lessons learned or other info that might be good to know about since its been out for some time now?
I have specified some links below that seemed useful to me when Googling it quickly. Appreciate any links on this!
- - - - - |  |
 | Category: Lotus Notes Domino
|
| Add the following parameter to your notes.ini file and then restart the Lotus Notes client: | Window_Title=King of Lotus Notes |
Now you will be able to see the results at the top left of the client window.  Also an excellent opportunity for an administrator to show your power over the users in your organization  I will check if it's the same for version 8 or not or if any of the readers know, you are welcome to post a comment about it. |  |
 | Category: Lotus Notes Domino
|
| Sometimes it is nice to send an invitation of some kind in an email instead of a regular Notes meeting invitation. You might want the invitation to have a more party feeling for example. In this case it could be handy to add one or several buttons in the Notes email that you send for different functionality purposes. When clicking one of these buttons an email could be sent or an appointment or meeting could be booked in the recipient's calendar or maybe both.  Here's some example code to put on a button that creates an appointment in the calendar of the user that clicks on it. As you can see this code is added to the button's Click Sub. Sub Click(Source As Button) Dim s As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Dim dt1 As NotesDateTime Dim dt2 As NotesDateTime mail = Evaluate("@MailDbName") Set db = s.GetDatabase(mail(0), mail(1)) Set doc = New NotesDocument(db) Set dt1 = New NotesDateTime("2009-06-03 18:00:00 PM") Set dt2 = New NotesDateTime("2009-06-03 22:00:00 PM") doc.Form = "Appointment" doc.Subject = "Project kick-off" doc.AppointmentType = "0" doc.Body = "Welcome to this project's kick-off. It will be held... bla bla bla" Set doc.CalendarDatetime = dt1 Set doc.StartDatetime = dt1 Set doc.StartDate = dt1 Set doc.StartTime = dt1 doc.Logo = "StdNotesLtr28" doc.MeetingType = "1" doc.Location = "Restaurant Three Barrels" doc.duration=6 Set doc.EndDateTime = dt2 Set doc.EndDate = dt2 Set doc.EndTime = dt2 doc.From = s.UserName doc.ExcludeFromView = "D" doc.ORGTABLE = "C0" doc.Broadcast = "" doc.Categories = "" doc.BookFreetime = "" Call doc.AppendItemValue("$BusyName", s.UserName) Call doc.AppendItemValue("$BusyPriority", "1") Call doc.AppendItemValue("$NoPurge", dt2) Call doc.AppendItemValue("$PublicAccess", "1") Call doc.AppendItemValue("_ViewIcon", 160) Call doc.Save(True, False) Msgbox "An appointment regarding this event has been added to your calendar!"
End Sub |
If you would like an email to be sent to you as well when the button is pressed you can add the following to the code above. Dim mailDoc As NotesDocument Set mailDoc = New NotesDocument( db ) mailDoc.Form = "Memo" mailDoc.SendTo = "me@mail.com" mailDoc.Subject = "I'll be there!!" mailDoc.Body = "Wow, that sounds really nice, count me in!" Call mailDoc.Send( False ) |
One thing to note is that you need Domino designer installed since this is LotusScript or else you will only be able to create buttons with simple actions. Either you can create it directly in a Notes memo by clicking Create -> Hotspot -> Button. Or you can do it in Domino designer and copy it into the email. So if you are a user with only the standard Lotus Notes client, maybe you can ask a colleague with designer access to help you. All she need to do is to customize the buttons for you and then email them to you. However, this will only work if you send Notes mails within the organization. The buttons dissapear if you try to send them to an Internet address via MIME. |  |
 | Category: Lotus Notes Domino
|
| If I want to copy a number of cells from Excel and put in Notes but still editable, preferably in a regular Lotus Notes table, how do I do that? The first impulse might be to copy and paste as is. The cells become an image in the Notes document this way though. A better option is to use the "Paste special" option in the 'Edit' menu. Here you can choose to paste the Excel cells into the Notes document as for example an embedded Excel area, pure text or HTML. I would suggest HTML as the best choice for this purpose.  All you have to do after this paste is to modify the Notes table with the table properties, for example the border size and color and so on. Below, see the before and after looks of the pasted excel cells after working a bit with the Lotus Notes table properties.  |  |
 | Category: Lotus Notes Domino
|
| There has always been a limit on how many documents it is possible to copy manually from a Lotus Notes view (with for example CTRL-C). This limit is 2335 documents. If you need to copy more documents you need to do it several times or manage it programatically.  However, in version 8 of Lotus Notes this limit seems to have been considerably improved. I can copy up to 49999 documents the same way. When I try to copy documents above that number no warning or error message is raised. Instead an irrational behaviour occurs, which means that it starts copying 4013 documents or something similar. Do anyone know anything about this limit? Is it just my Notes client that stops at 49999 documents or is this the official limit?  By the way I really appreciate that this limit has been increased since it happens now and then that I need to copy more than 2335 documents from one view to another. Another great improvement is that it is possible to select a range of documents. Select a document, scroll down the view, hold the SHIFT button and click on the mouse. Like in Windows explorer this causes all the documents within this range to be selected. |  |
 | Category: Lotus Notes Domino
|
| This tip is very basic. Nevertheless I have come to understand that its not common knowledge of either basic users or developers.
Say that you have a document in one view among many other thousands. Another view in the same database is structured in a hierarchy with parent and response documents for example. Now, you would like to find the selected document in the first view in the other parent-response view with a single click. Here's how to do it.
1. Select the document (in the first view) 2. Hold the CTRL-button 3. Click the other view
If the document is listed in the other view, the view will open with that document selected. |  |
 | Category: Lotus Notes Domino
|
| You can access Lotus notes documents from outside Lotus Notes either using an Internet url (if your Lotus Notes database is web enabled) or you can access and open up a specific Lotus Notes document in the Lotus Notes client from for example Excel or Word in other ways. has some on this. One of the tips is to get the document's Notes url and paste it in as a hyperlink in Excel. To accomplish that you need to find the document's UNID. Or you can use the Sametime client for some translation. Create a document link for the Lotus Notes document to which you want to create a link to. Paste this into a Sametime chat window. As you can see the document link is translated into a Notes URL. Now, simply paste it in as the hyperlink address in excel and you have a funtional Notes link. When you paste the document link into a Sametime chat window it will be translated into a Notes URL, looking something like this, which can be accessed from outside Lotus Notes. Be aware of access though, these rules still apply. | notes://DOMINOSERVER/C1257465003C1F7D/BF25AB0F47BA5DD785256 |
|  |
 | Category: Lotus Notes Domino
|
| If you for instance have Lotus Notes version 7 and would like to install version 8 on the side, i.e. you want to keep both installations on one computer. Then you have a good description of doing so . According to the instructions you have to make copies and rename at some places. But you can also do it another way that takes a little bit longer time but really don't require more than one change on one installation window.
So let's say you have version 7 and you want to install version 8.5. Start the executable for Lotus Notes 8.5. Go through the installation process. When you come to the point where the wizard asks for the location of where to install the program - change the path from <path>/notes and <path>/notes/data to <path>/notes8 and <path>/notes8/data or if there are other similar change them.
Now Lotus Notes 8 will be installed in a new directory. However your 7 version will not work. If you install the 7 version again now though without making any changes you will have two versions that should be fully functional. I don't think you should run them concurrently though,
The 7 version kept the Teamstudio toolbar buttons, workspace and so on. But you will have to adjust this for the new 8.5 version howver. |  |
 | Category: Lotus Notes Domino
|
| I have just for educational purposes created a simple web service consumer with Lotus Domino Designer 8.5 Beta 2. So I thought I'd share and perhaps make someone happy. For this example I found a web service on which was kind of funny. It is called and let's you get biblic information by book, chapter and verse. The address to the WSDL-file can be found . 1. Create a web service consumer element. Name it and point to the WSDL-file either local or the url. The web service consumer gets created for you. Copy the class name that gets created, i.e. 'BibleWebserviceSoap_n0'. %INCLUDE "lsxsd.lss" Const n0 = "http://www.webserviceX.NET" Class BibleWebserviceSoap_n0 As PortTypeBase Sub NEW Call Service.Initialize ("HttpWwwWebserviceXNETBibleWebservice", _ "BibleWebservice.BibleWebserviceSoap", "http://www.webservicex.net/BibleWebservice.asmx", _ "BibleWebserviceSoap_n0") End Sub Function GetBibleWordsByChapterAndVerse(BookTitle As XSD_STRING, chapter As Long, _ Verse As Long) As XSD_STRING Set GetBibleWordsByChapterAndVerse = Service.Invoke("GetBibleWordsByChapterAndVerse", BookTitle, chapter, Verse) End Function Function GetBibleWordsbyKeyWord(BibleWords As XSD_STRING) As XSD_STRING Set GetBibleWordsbyKeyWord = Service.Invoke("GetBibleWordsbyKeyWord", BibleWords) End Function Function GetBookTitles() As XSD_STRING Set GetBookTitles = Service.Invoke("GetBookTitles") End Function Function GetBibleWordsByBookTitleAndChapter(BookTitle As XSD_STRING, chapter As Long) As XSD_STRING Set GetBibleWordsByBookTitleAndChapter = Service.Invoke("GetBibleWordsByBookTitleAndChapter", BookTitle, chapter) End Function End Class |
2. Create an agent. Add "Use 'web service consumer name' " in 'Options'. 3. Set target as 'None' in the agent properties, 4. Add this code in the 'initialize' section Dim bible As New BibleWebserviceSoap_n0 Dim bookTitles As XSD_STRING Dim session As New NotesSession Dim inputStream As NotesStream Dim domParser As NotesDOMParser Dim domDoc As NotesDOMDocumentNode Dim domNodeList As NotesDOMNodeList Dim domNode As NotesDOMNode Set inputStream = session.CreateStream Set bookTitles = bible.GetBookTitles() Call inputStream.WriteText(bookTitles.getValueAsString()) Set domParser = session.CreateDOMParser(inputStream) Call domParser.Process Set domDoc = domParser.Document Set domNodeList = domDoc.GetElementsByTagName("BookTitle") Set domNode = domNodeList.GetItem(1) ' Now get the text in the tag and prompt it to the user (or something else) msgbox domNode.FirstChild.NodeValue |
5. Run the agent So this agent will, when run, display the name of the first book in a message box to you which is 'Genesis'. |  |
 | Category: Lotus Notes Domino
|
| The other day I needed to calculate how much space, i.e. size in Bytes, that all attachments took up in X specific Lotus Notes databases. So I googled some and found a very good already made by . Using this you will get a good coverage on how many attachments there are per database and how much space it corresponds to in Bytes. Since this takes some time to run you can easily modify the script to loop through only a subset of predefined databases instead if you are only interested in a few and not all. I modified the initialize sub in agent ''ScanForSize" this way: Sub Initialize Dim s As New NotesSession Dim db As NotesDatabase Dim curDB As NotesDatabase Dim serverName As String Dim DbArr(7) As String Dim db1, db2, db3, db4, db5, db6, db7, db8 As String
Set db = s.CurrentDatabase
' Server serverName = "Server1/Acme"
' Database file paths db1 = "Path\Filename1.nsf" db2 = "Path\Filename2.nsf" db3 = "Path\Filename3.nsf" db4 = "Path\Filename4.nsf" db5 = "Path\Filename5.nsf" db6 = "Path\Filename6.nsf" db7 = "Path\Filename7.nsf" db8 = "Path\Filename8.nsf" ' File array with the database file paths DbArr(0) = db1 DbArr(1) = db2 DbArr(2) = db3 DbArr(3) = db4 DbArr(4) = db5 DbArr(5) = db6 DbArr(6) = db7 DbArr(7) = db8 Forall dbItem In DbArr Set curDB = s.GetDatabase(serverName, dbItem) Print "Working on " & curDB.FilePath Call countThis(curDB, db) End Forall
Msgbox "Run completed" End Sub |
Another suggestion is to modify the 'countThis' sub to show statistics for everything regardsless if the database has attachments or not. I.e. comment the if-statement. 'If curSize.AttachmentCount > 0 Then Call curSize.save(reportDB) 'End If |
A thing to be aware of is the error message "Execution time limit exceeded by Agent", which means that the execution time of agents, i.e. how long agents are allowed to run has been exceeded. So you have to adjust this parameter for a long agent run or else it will suddenly stop run.  A tip is to schedule the agent to run on the server instead of pressing the button. Your client will not hang so you can continue to work and it will also process faster. |  |
 | Category: Lotus Notes Domino
|
| I needed to create a simple Lotus Notes Web Service. Since this is version 7 we are talking about it is a provider. The consumer comes in version 8 although there are very good ways to mimic the behaviour. These tutorials on creating web services in Lotus Notes by Julian Robichaux are great: - - - As I wrote there are good ways of creating a web service consumer even in version 7. See by Joachim Dagerot for more on this. If you have version 8 it is even more . Anyway, to the core of this blog entry. I created a simple web service by first writing a lotusscript class with a couple of simple methods in it. I set the adjustments on the web service to 'RPC' as programming model and 'Doc/literal' as SOAP message format, since 'Doc/literal' was what the consumer wanted for some reason: Class test2 Private session As NotesSession Private db As NotesDatabase Public Sub New () Set session = New NotesSession Set db = session.CurrentDatabase End Sub Public Function PutAndGetModString (txt As String) As String PutAndGetString = txt + "_mod" End Function
Public Function GetDbName () As String GetDbName = db.Title End Function
Public Function GetTest () As String Bla = "Response string" End Function End Class |
I exported the WSDL-file by pressing the button 'Export WSDL'. In (an extraordinary free application to test web services by the way) I created a project and imported this WSDL-file. Requests to try out are created by default. Double-click on one to open a new window and run it to send the request and receive the response. I had some initial problems that the address to connect to (specified in the wsdl-file) was set to localhost. This is easily fixed by editing the url in the request window. The address should be the web-address to the webservice, i.e. 'http://domainname/aFolder/database/webServiceName?WSDL'. Using this the SOAP-request looks like this: <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:DefaultNamespace"> <soapenv:Header/> <soapenv:Body> </soapenv:Body> </soapenv:Envelope> |
This brings the problem that calling the method GetDbName or GetTest returns the same response, i.e. from the GetDbName method. The reason for this is that the method is not defined in the SOAP-request and therefore the first one is chosen. What I did that made it work was simply to replace 'Doc/literal' as the SOAP message format to 'RPC/encoded'. Maybe someone knows how to adjust something so that the correct WSDL-file is created from Lotus Notes when using 'Doc/literal' for this to work. Exporting the WSDL-file with this setting makes the SOAP-request look like this instead. You can see that the method name is specificed in the body.: <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:DefaultNamespace"> <soapenv:Header/> <soapenv:Body> <urn:GETDBNAME soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </soapenv:Body> </soapenv:Envelope> |
See how the web service is represented in SoapUI with all the methods.  And how the request window looks like for a method.  Finally here is the code for a lotusscript class with methods to return some statistics about a database. Download the WSDL-file or generate it yourselves if you'd like: Class DatabaseStats Private session As NotesSession Private db As NotesDatabase Private nc As NotesNoteCollection Public Sub New () Set session = New NotesSession Set db = session.CurrentDatabase' End Sub ' Return database name Public Function GetDbName () As String GetDbName = db.Title End Function ' Return server name Public Function GetServerName () As String GetServerName = db.Server End Function ' Returns number of documents in the database Public Function GetNumDocuments () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectDocuments = True Call nc.BuildCollection GetNumDocuments = Cstr(nc.Count) End Function ' Returns number of forms in the database Public Function GetNumForms () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectForms = True Call nc.BuildCollection GetNumForms = nc.Count End Function ' Returns number of views in the database Public Function GetNumViews () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectViews = True Call nc.BuildCollection GetNumViews = nc.Count End Function ' Returns number of agents in the database Public Function GetNumAgents () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectAgents = True Call nc.BuildCollection GetNumAgents = nc.Count End Function ' Returns number of shared fields in the database Public Function GetNumSharedFields () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectSharedFields = True Call nc.BuildCollection GetNumSharedFields = nc.Count End Function ' Returns number of pages in the database Public Function GetNumPages () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectPages = True Call nc.BuildCollection GetNumPages = nc.Count End Function ' Returns number of outlines in the database Public Function GetNumOutlines () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectOutlines = True Call nc.BuildCollection GetNumOutlines = nc.Count End Function ' Returns number of actions in the database Public Function GetNumActions () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectActions = True Call nc.BuildCollection GetNumActions = nc.Count End Function ' Returns number of folders in the database Public Function GetNumFolders () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectFolders = True Call nc.BuildCollection GetNumFolders = nc.Count End Function ' Returns number of script libraries in the database Public Function GetNumScriptLibraries () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectScriptLibraries = True Call nc.BuildCollection GetNumScriptLibraries = nc.Count End Function ' Returns number of profile documents in the database Public Function GetNumProfileDocuments () As Integer Set nc = db.CreateNoteCollection(False) nc.SelectProfiles = True Call nc.BuildCollection GetNumProfileDocuments = nc.Count End Function End Class |
|  |
 | Category: Lotus Notes Domino
|
| I was debugging some code the other day and I needed to look at a field value before and after it had been set for a document. But it was not possible since there seems to be a limitation of how many fields that are displayed for a document in the debugger. In this case the number of items for a document. The form that the document is based on contains 318 fields but the debugger can only list 256 items. After that it displays "..." to indicate that there is more. Ok, good to know, but I'd like to look at all fields. I assume that the same limitation goes for other objects in the debugger output listing.  |  |
 | Category: Lotus Notes Domino
|
| If I open many databases in Domino Designer they all come up as bookmarks on the left-hand side. Sometimes If they are more than up to about 4 or 5 I cant expand the ones below, i.e. on the 5th position or more. I have to move them up so that they are on the 1-4th position. This morning when I started Notes I didn't have this problem at all as I could easily expand all 7 seven bookmarks. Why does this happen?  This could not be a special thing for just me since I have experienced it for as long as I remember on different machines and notes installations. Anyone agree or maybe have a good explanation? |  |
 | Category: Lotus Notes Domino
|
| I wanted to know how many fields there were in a Lotus Notes database. So here's a small lotuscript for this. It counts all "real" fields (i.e. not Computed for display fields) on all forms and prompts the result. It doesn't count unique fields however so if you make a copy of form A which have 10 fields 10 times the result is 100. Sub Initialize On Error Goto ErrorHandler Dim session As New NotesSession Dim ws As New NotesUIWorkspace Dim db As NotesDatabase Dim dbInfo As Variant Dim sDbServer As String Dim sDbPath As String Dim countFields As Long dbInfo = ws.Prompt(13, "Choose database", "Choose a database") sDbServer = dbInfo(0) sDbPath = dbInfo(1) Set db = session.GetDatabase(sDbServer, sDbPath) countFields = 0 Forall form In db.Forms Forall field In form.Fields countFields = countFields + 1 End Forall End Forall Msgbox Cstr(countFields) Exit Sub ErrorHandler: Msgbox Error$ & " on line " & Cstr(Erl) & " in " & Lsi_info(12) Exit Sub End Sub |
|  |
 | Category: Lotus Notes Domino
|
| I attended Lotusphere 2006 when i was working at an animal insurance company in Sweden who uses Lotus Notes. I came there alone both as a developer, administrator and a company representative (well I actually knew a few people). And was I impressed? Wow, it was really, really good and I was amazed.
Cool general opening sessions, very good technical sessions all days long To be able to talk to experts/developers and people around you all over the place that have something in common, good arrangements and great dinner and parties at night.
I was suppose to go in 2007 as well but I changed employer so unfortunately I couldn't and unfortunately I don't think I will be able to go for a couple of years now either. But for all of you that have not been there and are going I congratulate you, you will have lots of fun and learn many new things and of course make new friends and perhaps new colleagues.
This is probably not new information to anyone on but for anyone else that might land on this blog, here is a link to the site on IBM about where you can read about it and register.
did some calculation on his and stated that it would cost about 29000 swedish crowns. GAAAH! Not something I am doing with my own checkbook. But I also realize that for a great event like this it has to cost although a great part of it actually is the travel and staying. |  |
 | Category: Lotus Notes Domino
|
| It's easy to validate an email address for a web application in JavaScript with the help of since JavaScript follow the standards. When you need to do the same for a notes application you are either stuck with the -formula or a to be able to use it in lotusscript (with evaluate) or by creating a VBScript RegEx object (I haven't looked into this myself but it seems to be ). Apart from this the regular expression functionality in lotusscript actually except the which do have some of the basic functionality of regular expressions but not enough for more advanced checks - like email validation. One way of accomplishing it rather painless is to create a java agent that does the check since also Java support the standards of regular expressions. What you need is basically the . In my application I have created a Java script library with different methods to use for washing data but I will present only this function here in a simple Java agent to demonstrate. Remember that if you really must use lotusscript to run the code and the check you can call java objects from lotuscript. I haven't tried it myself yet but here is a . Just paste the following code into a new java-agent, select "None" as runtime-target and run and you'll see the result in the Java Debug Console. import lotus.domino.*; import java.util.regex.Matcher; import java.util.regex.Pattern;
public class JavaAgent extends AgentBase {
/** * Constant regular expressions. * The separation of the string below is only for the blog entry to display correct. * You will of course not need it when running the code. */ public final static String EMAIL_REGEX = "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*" + "+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
/** * @param Regular expression * @param Pattern to check against the regular expression * @return True if the pattern is valid against the regular expression and else false */ public boolean isValidString(String sRegEx, String sCheckPattern) { Pattern p = Pattern.compile(sRegEx); Matcher m = p.matcher(sCheckPattern); return m.matches(); }
public void NotesMain() {
try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); if (isValidString(EMAIL_REGEX, "an.address@test")) { System.out.println("Valid email address!"); } else { System.out.println("Invalid email address!"); }
} catch(Exception e) { e.printStackTrace(); } } }
|
This is compared to other solutions a small amount of code and pretty easy to understand and besides this it covers 99,99% of all email addresses in actual use today according to . The ultimate and fail-proof official standard (RFC 2822) is extremely long and complex. but you're recommended not to use it. Read more about this on the provided link above to regular-expressions.info. |  |
 | Category: Lotus Notes Domino
|
| A small trick that maybe not everyone know, especially not ordinary users, is that there are ways to open hidden views in the notes client without having to bribe the developer or gain access to Domino designer. If you don't have a frameset with an outline or navigator, the views are listed in the left frame when opening a database - only visible views though. To list hidden views press Ctrl-Shift when double-clicking the database on the workspace or when clicking Open in the open database dialogue box. If the view listing are disabled due to an outline you can list the views using "View -> Go To...". The default is also here that only visible views are listed. Press Ctrl-Shift and click on this menu choice to include hidden views in this dialogue box as well. Another trick (can't think of a reason to use it right now but nevertheless) is to create a toolbar button with the following formula code. As you see, you will have to hard code the view name in this example. But it works for both hidden and visible views. | @Command([OpenView]; "(hidden testview)") |
|  |
 | Category: Lotus Notes Domino
|
| At the moment I am looking over a large Notes application and therefore I need to know some statistics about the databases and the design elements in them. Here is a script for displaying the field names on a form and the number of fields. The names of the fields comes in a non-alpabetical order. Assume we have a form 'showFields' with two fields 'numFields' and fieldNames''. Both fields are text fields and field 'fieldNames' are set to "Allow multiple values". Multi-value options on tab 3 of the field properties box are set to comma for separating values and new line as they way of displaying separate values. Dim session As New NotesSession Dim ws As New NotesUIWorkspace Dim db As NotesDatabase Dim uidoc As NotesUIDocument Dim form As NotesForm Dim dbInfo As Variant Dim sDbServer As String Dim sDbPath As String Dim countFields As Integer dbInfo = ws.Prompt(13, "Choose database", "Choose a database") sDbServer = dbInfo(0) sDbPath = dbInfo(1) Set db = session.GetDatabase(sDbServer, sDbPath) Set form = db.GetForm(Inputbox("Name of form?"))
Set uidoc = ws.ComposeDocument ( "", "", "showFields" ) countFields = 0 Forall fld In form.Fields Call uidoc.FieldAppendText("fieldNames", fld) Call uidoc.FieldAppendText("fieldNames", ",") countFields = countFields + 1 End Forall
Call uidoc.FieldSetText("numFields", Cstr(countFields)) Call uidoc.Save |
Nice, but if we have a large form with many fields it becomes hard to read and find fields. So it would be nice to sort the values in alphabetical order before displaying them. I searched the developerWorks forum and found a post by where he posted a script with the Shell-Metzner sort algorithm. It is really fast and I complemented the above code the following way to get the same result but sorted. Create a new script library with the following code and add it to your agent or code with the Use-command. Function SortSM (Array$()) 'The sort algorithm used here is the Shell-Metzner, a binary sort 'Hence, the function name. Short for Sort-Shell-Metzner
Dim MaxElement%, MidPoint%, I%, J%, Done%
MaxElement% = Ubound(Array$)
Select Case MaxElement%
Case 0 Exit Function
Case 1 If Array$(0) > Array$(1) Then Swap Array$(0), Array$(1) End If
Case Else MidPoint% = MaxElement% While MidPoint% > 0 MidPoint% = MidPoint% \ 2 Do Done% = True For J% = 0 To MaxElement% - MidPoint% I% = J% + MidPoint% If Array$(J%) > Array$(I%) Then Swap Array$(J%), Array$(I%) Done% = False End If Next Loop Until Done% Wend
End Select End Function
Function Swap (A$, B$) Temp$ = A$ A$ = B$ B$ = Temp$ End Function |
Then modify the existing code to look like this. Dim session As New NotesSession Dim ws As New NotesUIWorkspace Dim db As NotesDatabase Dim uidoc As NotesUIDocument Dim form As NotesForm Dim dbInfo As Variant Dim sDbServer As String Dim sDbPath As String Dim countFields As Integer Dim arrFields() As String dbInfo = ws.Prompt(13, "Choose database", "Choose a database") sDbServer = dbInfo(0) sDbPath = dbInfo(1) Set db = session.GetDatabase(sDbServer, sDbPath) Set form = db.GetForm(Inputbox("Name of form?"))
Set uidoc = ws.ComposeDocument ( "", "", "showFields" ) countFields = 0
Forall fld In form.Fields Redim Preserve arrFields(countFields) arrFields(countFields) = fld countFields = countFields + 1 End Forall Call SortSM(arrFields) Forall f In arrFields Call uidoc.FieldAppendText("fieldNames", f) Call uidoc.FieldAppendText("fieldNames", ",") End Forall Call uidoc.FieldSetText("numFields", Cstr(countFields)) Call uidoc.Save |
|  |
 | Category: Lotus Notes Domino
|
| wrote a blog entry a couple of years ago with a solution on how to delete deletion stubs for a Lotus Notes database. Take a look at his code to accomplish that, very nice! I have modified it just a little bit to be able to first choose which database to work on and then to choose if you only want to count or if you want to count and delete them (Options):Option Public Const wAPIModule = "NNOTES" ' Windows/32 |
(Declarations):Declare Private Sub IDDestroyTable Lib wAPIModule Alias "IDDestroyTable" _ ( Byval hT As Long) Declare Private Function IDScan Lib wAPIModule Alias "IDScan" _ ( Byval hT As Long, Byval F As Integer, ID As Long) As Integer Declare Private Function NSFDbOpen Lib wAPIModule Alias "NSFDbOpen" _ ( Byval P As String, hDB As Long) As Integer Declare Private Function NSFDbClose Lib wAPIModule Alias "NSFDbClose" _ ( Byval hDB As Long) As Integer Declare Private Function NSFDbGetModifiedNoteTable Lib wAPIModule Alias "NSFDbGetModifiedNoteTable" _ ( Byval hDB As Long, Byval C As Integer, Byval S As Currency, U As Currency, hT As Long) As Integer Declare Private Function NSFNoteDelete Lib wAPIModule Alias "NSFNoteDelete" _ ( Byval hDB As Long, Byval N As Long, Byval F As Integer) As Integer Declare Private Function OSPathNetConstruct Lib wAPIModule Alias "OSPathNetConstruct" _ ( Byval NullPort As Long, Byval Server As String, Byval FIle As String, Byval PathNet As String) As Integer Declare Private Sub TimeConstant Lib wAPIModule Alias "TimeConstant" _ ( Byval C As Integer, T As Currency) Dim Db As NotesDatabase
|
Initialize:Sub Initialize Dim Session As New NotesSession Dim ws As New NotesUIWorkspace Dim dbInfo As Variant Dim sDbServer As String Dim sDbPath As String Dim retVal As Integer dbInfo = ws.Prompt(13, "Choose database", "Choose a database") sDbServer = dbInfo(0) sDbPath = dbInfo(1) Set db = session.GetDatabase(sDbServer, sDbPath) retVal = ws.Prompt (PROMPT_YESNOCANCEL, _ "Delete or just count?", _ "Do you want to delete all of the deletion stubs in this database [Yes] or just count them [No]")
Select Case retVal Case 1 : Call countAndDeleteStubs(db, 1) Case 0 : Call countAndDeleteStubs(db, 0) Case -1 : Msgbox "Operation cancelled" End Select End Sub |
countAndDeleteStubs:Sub countAndDeleteStubs(db As NotesDatabase, choice As Integer) Dim ever As Currency, last As Currency Dim hT As Long, RRV As Long, hDB As Long With db np$ = Space(1024) OSPathNetConstruct 0, db.Server, db.FilePath, np$ End With NSFDbOpen np$, hDB TimeConstant 2, ever NSFDbGetModifiedNoteTable hDB, &H7FFF, ever, last, hT n& = 0 done = (IDScan(hT, True, RRV) = 0) While Not done If RRV < 0 Then If (choice = 1) Then NSFNoteDelete hDB, RRV And &H7FFFFFFF, &H0201 End If n& = n& + 1 End If done = (IDScan(hT, False, RRV) = 0) Wend IDDestroyTable hT NSFDbClose hDB If (choice = 1) Then Msgbox "Deleted " & Cstr(n&) & " stubs in database " & db.FilePath & " on server " & db.Server Else Msgbox "Database " & db.FilePath & " on server " & db.Server & " contains " & Cstr(n&) & " stubs" End If End Sub |
And here are the results when running the count...  and the delete option for a database.  |  |
 | Category: Lotus Notes Domino
|
| Now and then it's time for a new computer and when that time comes it's also time to install new programs. If you are an employée of a larger company these installations are most likely done for you but nevertheless you might still have to take care of some of your personal stuff.
Your local notes stuff could be stored on disk and in that case it shouldn't be a problem but many times these local files are stored locally on your computer and it this case you have to make backups if you don't want to loose some things you have built up and used for years.
This is my recommended list of what you should backup before throwing your old computer in the garbage. Please feel free to add more recommendations with explanations if you have any:
# bookmark.nsf (all you bookmarks. Some people use them heavily, some don't use them at all. If you are a roaming user bookmark.nsf is stored on the server for you and you don't have you make a backup of it).
# journal.nsf (Some people do use it. It's a personal simple document library. Works the same way as bookmarks regarding roaming)
# names.nsf (Your personal address book. Same as above regarding roaming users)
# Your id-file (Some organizations have the id's left in the address book but some remove it. If you are a roaming user the id-file is double encrypted in the personal address book listed above. In this case the name of it must be "user.id". Otherwise it can be named almost anything. There is also a recommended admin function that e-mails the id-file for each user when there is a change to it. However to be sure, make a backup of your id-file.
# user.dic (If you use a dictionary and have added words)
# notes.ini (The heart of settings. I usually don't backup this, but you might need it)
# Your desktop-file named desktop6.ndk or desktop5.dsk. If you use your workspace, this is the file to copy, The bookmarks on the workspace are not stored in bookmark.nsf but in this file.
# Archives. Have you created any archives locally that you would like to keep?
# Self-created databases. If you are a developer you have most likely one or several local databases and it's worth looking into if you want to keep any.
Have a look at the recommended files to backup from IBM as well: - - |  |
 | Category: Lotus Notes Domino
|
| When looking at performance for a notes application or just doing some inventory check it can be useful to get the number of different design elements for a lotus notes database. Here is an example script which can be run as an agent. When starting it a prompt displays with the database dialogue. You choose a database at some server and when clicking ok, the number of design elements are calculated and presented to the user in a message box. Sub Initialize Dim session As NotesSession Dim ws As New NotesUIWorkspace Dim db As NotesDatabase Dim nc As NotesNoteCollection Dim dbInfo As Variant Dim sDbServer As String Dim sDbPath As String Dim iForms As Integer Dim iViews As Integer Dim iAgents As Integer Dim iPages As Integer Dim iOutlines As Integer Set session = New NotesSession dbInfo = ws.Prompt(13, "Choose database", "Choose a database") sDbServer = dbInfo(0) sDbPath = dbInfo(1) Set db = session.GetDatabase(sDbServer, sDbPath) Set nc = db.CreateNoteCollection(False) If Not nc Is Nothing Then ' Forms nc.SelectForms = True iForms = countElements(nc) ' Views nc.SelectViews = True iViews = countElements(nc) ' Agents nc.SelectAgents = True iAgents = countElements(nc) ' Pages nc.SelectPages = True iPages = countElements(nc) ' Outlines nc.SelectOutlines = True iOutlines = countElements(nc) ' Print results Msgbox "Forms: " + Cstr(iForms) + Chr(13)_ + "Views: " + Cstr(iViews) + Chr(13)_ + "Agents: " + Cstr(iAgents) + Chr(13)_ + "Pages: " + Cstr(iPages) + Chr(13)_ + "Outlines: " + Cstr(iOutlines) + Chr(13)_ End If End Sub
|
Function countElements that is referenced in the above sub looks like this: Function countElements(nc As NotesNoteCollection) As Integer Dim elements As Integer
Call nc.BuildCollection elements = nc.Count Call nc.SelectAllNotes(False)
countElements = elements End Function |
There are many different properties of the that you can use to count other designElements, documents etc. Here are the properties: * Count * LastBuildTime * Parent * SelectACL * SelectActions * SelectAgents * SelectDatabaseScript * SelectDataConnections * SelectDocuments * SelectFolders * SelectForms * SelectFrameSets * SelectHelpAbout * SelectHelpIndex * SelectHelpUsing * SelectIcon * SelectImageResources * SelectionFormula * SelectJavaResources * SelectMiscCodeElements * SelectMiscFormatElements * SelectMiscIndexElements * SelectNavigators * SelectOutlines * SelectPages * SelectProfiles * SelectReplicationFormulas * SelectScriptLibraries * SelectSharedFields * SelectStyleSheetResources * SelectSubforms * SelectViews * SinceTime |
And here are the methods: * Add * BuildCollection * ClearCollection * GetFirstNoteID * GetNextNoteID * Intersect * Remove * SelectAllAdminNotes * SelectAllCodeElements * SelectAllDataNotes * SelectAllDesignElements * SelectAllFormatElements * SelectAllIndexElements * SelectAllNotes |
For example use nc.SelectDocuments the same way to get the number of all documents in the database. But you might have to modify the 'countElements' function in that case to return a value of type Long instead of Integer in case the database contains a lot of documents. The result could look something like this if you add some more blocks to the above code:  You need to have at least reader access to the database though to get this information. |  |
 | Category: Lotus Notes Domino
|
| Let's say that you for some reason have a form with an embedded view that lists a bunch of documents. You would like to mark one of the documents in the embedded view and get a grip of this document and do something with it. Sounds easy but could be a bit tricky! This is how I have solved it (with some help form the ). Step 1In the view that is embedded in the form, add the following formula code to "Target Frame (single click)": | @SetEnvironment( "eViewSelection"; @Text(@DocumentUniqueID)) |
What happens here is that an environment variable named 'eViewSelection' is set when clicking on a document in the view with the text value of the document unique id. In more detail this means that a row is added or updated in notes.ini that looks something like this: | $eViewSelection=00C2635582348362C125737F003C09AD |
Step 2When you somewhere else on the form need to get a hold of the document (to get a value from it or mail it as reference or something else), perhaps using lotusscript on a button, you can access it by first get the value of the environment variable that was set when clicking the document in the view and later on to use it. Here's an example: Sub Click(Source As Button) On Error Goto ErrorHandler Dim session As New NotesSession Dim db As NotesDatabase Dim selectedDocID As NotesDocument Dim selectedDocIDString As String
Set db = session.CurrentDatabase selectedDocIDString = session.GetEnvironmentString("$eViewSelection", False)
If(selectedDocIDString <> "") Then Set selectedDocID = db.GetDocumentByUNID(selectedDocIDString) Else Msgbox "You have to select a document!" Exit Sub End If
' ' Do something really cool with this document if that is possible ;-) '
' Set environment variable to empty string to be ready for next run Call session.SetEnvironmentVar("$eViewSelection", "" )
Exit Sub ErrorHandler: ' Log error Msgbox "An error occurred" Exit Sub End Sub |
|  |
 | Category: Lotus Notes Domino
|
| Assuming you have an xml-structure that you for some reason need to get data from. Then you could either do it the hard way by reading one character after the other and looking at it - not a pretty solution... Or you could use a predefined parser which makes the amount of code much smaller and easier to read. Here is one way of doing a simple parse in Lotus Notes using the CreateDOMParser object. Look in the Domino Designer help for more information. Let's pretend we have the following xml-structure: <DataSet> <Library> <Book>18</Book> <BookTitle>Some really good poetry book</BookTitle> <Chapter>3</Chapter> <Verse>14</Verse> <Words>These are the words of a poet.</Words> </Library> </DataSet> |
The above xml-structure is in some way stored into the variable 'xmlStruct' below. We want to get the text stored in the 'Words' tag. use the following LotusScript code in a agent or behind a button in a form perhaps. Dim xmlStruct As New XSD_STRING() Set xmlStruct = "Receive_an_xml-structure_through_web-services_or_some_other_way".
Dim inputStream As NotesStream Dim domParser As NotesDOMParser Dim domDoc As NotesDOMDocumentNode Dim domNodeList As NotesDOMNodeList Dim domNode As NotesDOMNode Set inputStream = session.CreateStream Call inputStream.WriteText(xmlStruct.getValueAsString()) Set domParser = session.CreateDOMParser(inputStream) Call domParser.Process Set domDoc = domParser.Document Set domNodeList = domDoc.GetElementsByTagName("Words") Set domNode = domNodeList.GetItem(1) ' Now get the text in the tag and prompt it to the user (or something else) msgbox domNode.FirstChild.NodeValue |
|  |
 | Category: Lotus Notes Domino
|
| A replication conflict occurs when two or more users edit the same document and save the changes in different replicas between replications. A save conflict occurs when two or more users open and edit the same document at the same time on the same server, even if they're editing different fields. When these conditions occur, Domino stores the results of one editing session in a main document and stores the results of additional editing sessions as response documents. These response documents have the title Replication or Save Conflict. Sometimes Lotus Notes users notice that there are conflict documents in an application and then you as a developer need to find out why. For these occasions it can be a good thing to list all conflict documents in a database. This can be easily done by creating a conflict documents view. Follow these steps:1. Create a view. 2. Modify the default column to show some field or use a default value like @Created or whatever. This doesn't really matter, it's for you to see some difference between the documents when they are displayed in the view. Add additional columns if needed. 3. Modify the view selection formula to the following: | SELECT @IsAvailable($Conflict) |
5. Uncheck "Show response documents in a hierarchy" in view properties, 2nd tab 4. Save and open view. What happens in the formula above is that all documents in the database are checked if they have a field named '$Conflict'. In this case @IsAvailable will return true and that document will be displayed in the view. Handle conflicts:One way to deal with save conflict would be to use document locking. This way there can only be one person at a time that edits a document. But documents can still be modified in the backend. In this case you can also handle it the way specified by Thomas Adrian hosting |
|