<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>lotusscript &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://wordpress.com/tag/lotusscript/</link>
	<description>Feed of posts on WordPress.com tagged "lotusscript"</description>
	<pubDate>Thu, 21 Aug 2008 16:53:45 +0000</pubDate>

	<generator>http://wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[A (different) document security model]]></title>
<link>http://quintessens.wordpress.com/?p=172</link>
<pubDate>Sat, 16 Aug 2008 14:19:41 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/?p=172</guid>
<description><![CDATA[One of the reasons why everyone in my company says I am a lovable chap is because I give technical s]]></description>
<content:encoded><![CDATA[<p>One of the reasons why everyone in my company says I am a lovable chap is because I give technical support on an important HR application. In this application HR keeps track of the top-level functions in our organisation (Position), who is currently on a function (Successor) and who are marked as possible follow-ups (High Potential).</p>
<p>Since I am one of the few people who can read all information in the database occassionaly I receive the question if I have seen one's name listed. Well try again next time if you see me in the pub. Maybe if you offer me a beer you might have more luck then, is my reply. Unfortunately this has not resulted (yet) in any free drinks...</p>
<p>The security model in this application works like this:</p>
<ul>
<li>people in the a higher level in the organisation may read all documents underneath their own level</li>
<li>people in a lower level in the organisation may not read any documents above their own level</li>
</ul>
<p>I must also mention how application security is distributed in our organisation:</p>
<ul>
<li>The Domino directory contains for each application a default set of usergroups. These groups represent the level people get in the ACL (reader, author, editor, designer)</li>
<li>For server related groups their is a group for editor and manager access</li>
<li>For each role a separate usergroup is listed</li>
</ul>
<p>The naming of a usergroups is as followed:</p>
<ul>
<li>filename_typeofuser_accesslevel</li>
</ul>
<p>Examples of groupnames are:</p>
<ul>
<li>SA01232_Users.Author</li>
<li>SA01232_Users.Designer</li>
<li>SA01232_Server.Manager</li>
<li>SA01232_Roles.Admin</li>
</ul>
<p>There is a routine running that creates for each role a group in the Directory and an application administrator can assign users to a group by assigning a user a role.</p>
<p>This works all fine BUT there is a limitation how many roles an ACL may contain (75 according to the Help).</p>
<p>My HR application is from a pre-standards age and has a slightly different security model that is based on individual usergroups that represent an organisational structure like in:</p>
<ul>
<li>filename_typeofuser_accesslevel_orglevel1_orglevel2... up till orglevel6</li>
</ul>
<p>Therefor every position document in the application will get its unique usergroup reference and also all the usergroups of positions higher in the organisation.</p>
<p>For example the position document for the manager of Acme\Europe\Sales\Invoice also get the usergroups of Acme\Europe\Sales, Acme\Europe and Acme so the head of Sales, Europe can nominate and see who are in the pool of potentials for following up the head of Invoice, Sales, Europe.</p>
<p>Nothing to worry about except that the write access to the Domino directory is (wisely) restricted for normal users. So everytime someone thinks a usergroup needs to be updated a request has to be send to an administrator, and the updating is still then a manual task...</p>
<p>Well why would I worry? My worries came in the picture as soon as the application that is being used to administrate user access did not any longer display proper information about who has access to what level.</p>
<p>Since this an application with a one of a kind security model I could not expect any support from the administrators, they were more than happy to emphasize that it was about time that I write the security model to the model we have as standard.</p>
<p>Due to the limitation of userroles in an ACL I was forced to look for alternatives and one is to maintain the usergroup in the application itself and not care about having the usergroups any more in the Domino directory. This would also give me the opportunity to apply some new features like applying a mechanism to update the usergroups by the application administrator.</p>
<p>This all sounded nice, but a lot of work on uncovered terrain untill the sun started to shine outside when I discovered Ulriche Krause's posting '<a title="Go to Eknori's place" href="http://www.eknori.de/2008-04-27/is-user-a-member-of-a-nested-group/" target="_blank">Is User A Member Of A (Nested) Group ?</a>'.</p>
<p>This function allowed to copy the usergroups into my application and do the calculation from within. As a result I will get an array with usernames which I then could apply in Readers and Authors fields on each document.</p>
<p>I know this is data overhead (usernames stored in stead of usergroups) for something normally the Domino directory takes care of but for my application I consider it the best solution. Or am I wrong?</p>
<p>Note: I have added a scheduled routine that sets a flag on an updated usergroup. For each updated usergroup document the following routine runs:</p>
<p>Sub Initialize<br />
 <br />
 Dim ses As New NotesSession<br />
 Dim luView As NotesView<br />
 Dim groupView As NotesView<br />
 Dim groupDoc As NotesDocument<br />
 Dim dc As NotesDocumentCollection <br />
 Dim doc As NotesDocument<br />
 <br />
 Set db = ses.CurrentDatabase <br />
 Set groupView = db.GetView("luGroup")<br />
 Set luView = db.GetView("luDocsByGroup")<br />
 Set groupDoc = groupView.GetFirstDocument<br />
 <br />
 Do Until groupDoc Is Nothing<br />
  If groupDoc.Tx_GroupUpdated(0) = "1" Then<br />
   'Group document updated - update all position and successor documents containing the group<br />
   Set dc = luView.GetAllDocumentsByKey(groupDoc.ListName(0), True)<br />
   Set doc = dc.GetFirstDocument<br />
   Do Until doc Is Nothing<br />
    Call UpdateDocumentAccess(doc)<br />
    Set doc = dc.GetNextDocument(doc)<br />
   Loop<br />
  End If<br />
  groupDoc.Tx_GroupUpdated = "0"<br />
  Call groupDoc.save(True,False,False)<br />
  Set groupDoc = groupView.GetNextDocument(groupDoc)<br />
 Loop<br />
 <br />
End Sub</p>
<p>View luGroup contains all the usergroup documents, View luDocsByGroup contains all documents (Position, Successor, High Potential) that might need to be updated.</p>
<p>To 'monitor' if an usergroup is updated I use:</p>
<p>Sub Postopen(Source As Notesuidocument)<br />
 membersPO = Join(source.Document.Members, "##")<br />
End Sub</p>
<p>and</p>
<p>Sub Postsave(Source As Notesuidocument)<br />
 <br />
 Dim groupChanged As String<br />
 Dim membersPS As Variant<br />
 membersPS = Join(source.Document.Members, "##")<br />
 If membersPO &#60;&#62; membersPS Then<br />
  source.Document.Tx_GroupUpdated = "1"<br />
  Call source.Document.Save(True,True,True)<br />
 End If<br />
 <br />
End Sub</p>
<p>That's for now, I go out cause the sun has started shining again!</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Lotusscript : Json formatter... enjoy]]></title>
<link>http://pierrekoerber.wordpress.com/?p=87</link>
<pubDate>Mon, 28 Jul 2008 17:36:14 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=87</guid>
<description><![CDATA[Hello, the following class allows you to format easily your return to your AJAX requests in JSON.
]]></description>
<content:encoded><![CDATA[<p>Hello, the following class allows you to format easily your return to your AJAX requests in JSON.</p>
<p>--------------------------------------------------</p>
<p>Calling code</p>
<p>--------------------------------------------------</p>
<p><span style="font-family:sans-serif;font-size:x-small;">Dim sJson As New cJSON</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;">Call sJson.addItem("myParameter1", True)</span><br />
<span style="font-family:sans-serif;font-size:x-small;">Call sJson.addItem("myParameter2", "this is a value")</span><br />
<span style="font-family:sans-serif;font-size:x-small;">Call sJson.addItem("myNumericPara", 2324)</span><br />
<span style="font-family:sans-serif;font-size:x-small;">Call sJson.addItem("myJSONStruct", sJson)</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;">Msgbox sJson.getJSONWithHeader()</span></p>
<p>--------------------------------------------------</p>
<p>class code</p>
<p>--------------------------------------------------<br />
<span style="font-family:sans-serif;font-size:x-small;">'/**------------------------------------------------------------------------------------------</span><br />
<span style="font-family:sans-serif;font-size:x-small;">' * Object         cJSON</span><br />
<span style="font-family:sans-serif;font-size:x-small;">' * @author         Pierre Koerber</span><br />
<span style="font-family:sans-serif;font-size:x-small;">' * @version         1.0 - 24.07.2008</span><br />
<span style="font-family:sans-serif;font-size:x-small;">' * History :</span><br />
<span style="font-family:sans-serif;font-size:x-small;">' */------------------------------------------------------------------------------------------ </span><br />
<span style="font-family:sans-serif;font-size:x-small;">Class cJSON </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Private lstItem List As String </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Private newLine As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Sub new</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> newLine = Chr(13) &#38; Chr(10)</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Sub</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Public Function getRandomString() As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> getRandomString = Replace(Cstr(Rnd(1)), ".", "")</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Function</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Public Function addItem(sName As Variant, vValue As Variant) As Variant</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Dim sJson As String </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = &#124;%1:%2&#124;</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%1", sName)</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Select Case Typename(vValue) </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Case "CJSON":</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%2", vValue.getJSON())</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Case "STRING"</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%2", &#124;"&#124; + Cstr(vValue) + &#124;"&#124;)</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Case "BOOLEAN"</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> If vValue = True Then</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%2", "true")</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Else</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%2", "false")</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End If</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Case Else</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sJson = Replace(sJson, "%2", Cstr(vValue))</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Select</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> lstItem(getRandomString) = sJson</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Function</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Public Function getJSON() As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Dim i As Integer</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Dim sRes As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> i = 0 </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRes = "{"</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Forall x In  lstItem</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> If i=0 Then</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRes = sRes + x</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Else </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRes = sRes + "," + x</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End If</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> i = i + 1</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Forall</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> getJSON = sRes + "}"</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Function</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Public Function getJSONWithHeader() As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> Dim sRet As String</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRet = &#124;Content-Type: text/javascript; charset=UTF-8&#124; + newLine</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRet = sRet + &#124;Cache-Control: no-cache&#124; + newLine</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> sRet = sRet + getJSON() </span><br />
<span style="font-family:sans-serif;font-size:x-small;"> getJSONWithHeader = sRet</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> End Function</span><br />
<span style="font-family:sans-serif;font-size:x-small;"> </span><br />
<span style="font-family:sans-serif;font-size:x-small;">End Class</span></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Lotus Notes Domino and Web Application Development - Tips for Programmers]]></title>
<link>http://debbiesmatth.wordpress.com/?p=7</link>
<pubDate>Mon, 14 Jul 2008 00:30:00 +0000</pubDate>
<dc:creator>debbiesmatth</dc:creator>
<guid>http://debbiesmatth.wordpress.com/?p=7</guid>
<description><![CDATA[Beginning with songster edition R4 it has combining with the Web, and the computer itself becomes a ]]></description>
<content:encoded><![CDATA[<p>Beginning with songster edition R4 it has combining with the Web, and the computer itself becomes a HTTP-server. The incoming releases of songster Web-server add newborn functionality (for warning servlet managers, based JVM versions upgrade, etc).  To wage you generalized represent and abstracting from info we’ll speech most digit earth songster Web-server functions:</p>
<p>1.      songster Web-server is the full-featured HTTP-server.  In another words, it crapper wage noise (or conditionally static) files as the state to HTTP-browser’s requests (including HTML, image, JavaScript, applets, etc);</p>
<p>2.      During the browser’s requests to songster impulsive resources by restricted URL, the computer crapper create in expiration HTML-pages, making the songster goal visible.</p>
<p>For sure, it is fairly simplified support (we mentioned that, for example, songster Web-server supports servlet technology), but this support allows to handle the earth issues in creation of Web-applications based on Lotus songster technology.  Following the earth problems are:</p>
<p>•        in Domino-based Web-applications creation developer is strongly restricted to ingest built-in aggregation languages’ possibilities. Thus, from 380 integral @-commands of @-formulas module nearly 40 are based in Web. LotusScript is based exclusive in threesome types of Web-agents, etc;</p>
<p>•        covering section problems. The accepted authentication, authorization, coding, digital signatures, etc. mechanisms are simplified in Web or do not work. So SSL + x.509, etc. certificates are to be utilised in such cases;</p>
<p>•        applications efficiency. HTML-pages procreation in expiration sure takes the computer resources, so if the covering is poorly constructed, it haw drive the computer failure. For example, if the prototypal tender of the place is generated by an agent, then concurrent letter from kinda bounteous sort of users haw drive the assist unfortunate situation.   Developers are to verify tending themselves for weight equilibrise swing into assorted parts ofttimes denaturized and more noise data;</p>
<p>•       termination of HTML-pages procreation in expiration from songster resources is not every instance obvious. Often such a machine issues attendance in generated tender ซadditionalป by developer saucer of analyse tags (for ex., <P>, <BR>, <UL>, etc). As a consequence, most developers place on songster exclusive those features which crapper not compel themselves. If countenance finished the codes of full-blown Web-sites, fashioned on songster technology, then, for example, in songster forms we wager exclusive fields, every physician organisation is based on DHTML.</p>
<p>It is not so bad.  There are a aggregation of sites, activity super sort of users, accessing songster data. songster profession from promulgation to promulgation offers newborn possibilities for Web-design (for ex. JSP bespoken attach library, integral HTML-editor, etc). The communicator himself utilised songster to create portals with requests with more than 2000 visitors per a day. Summarizing the possess and my colleagues undergo in songster Web-design field, I crapper propose the following:</p>
<p>•	Before creation of Web-project on songster it is needed to appraise the full songster stock in inclose of objective organization. If the songster stock at this consort is on inaugural or initial stage, than Web-design based on songster is scarce appropriated. The fact that songster Designer is the surround for fast covering utilization (RAD), including Web- applications, crapper not be the think to create  Web-projects on Domino;</p>
<p>•	as farther as doable allowing to songster designate in expiration exclusive objects, which crapper not be or scarce implemented by using another Web-technologies (so-called  HTML-design is to be matured by programmers). The communicator thinks that, if a place needs to control with songster data, then to analyse them it is needed to refrain the ingest of accepted address employed with songster objects. In this housing mercantilism of accumulation between place and songster crapper be finished by using some combining technologies based by songster (ex., XML, CORBA, JDBC, etc). In another words, songster module endeavor a persona of accumulation hardware and their watch is to be finished by another mechanisms. Implicitly, the supply is addicted by IBM. In R6 songster Don't earmark address unstoppered feature haw be appointed to databases , so the practice of accepted address songster is fortified in Web-applications;</p>
<p>•	attention needs to be paying to  Web-application security.  Even when your place does not earmark non-authorized admittance to aggregation via Internet, you crapper wait hackers discover there hard your web-site security;</p>
<p>•	only the proven by weight technologies are to utilised in Web-applications;</p>
<p>•	minimize as such as doable the reciprocation Web-server  browser. In Web-design the supply is to be thoughtful that cyberspace channels are commonly narrower than topical channels songster  Lotus.</p>
<p>Good phenomenon in your grouping environment up and occurrence us for some support in USA: 1-866-528-0577, Germany: (0177) 8349 806! help@albaspectrum.com</p>
<p>P.Gottmann is a theoretical illustrator in Ronix Systems ( http://www.ronix-systems.com ) the dweller division of Alba Spectrum Technologies ( http://www.albaspectrum.com ), IBM and Microsoft Business Solutions Partner, bringing clients in Chicago, Miami, New York, Los Angeles, San Francisco, Denver, Phoenix, Houston, Atlanta, Germany, UK, Australia, South Africa, Brazil, Moscow.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Designer 8.5 (I)]]></title>
<link>http://jalemanyf.wordpress.com/?p=408</link>
<pubDate>Sun, 01 Jun 2008 14:54:31 +0000</pubDate>
<dc:creator>jalemanyf</dc:creator>
<guid>http://jalemanyf.wordpress.com/?p=408</guid>
<description><![CDATA[(NOTE :YOU CAN TRANSLATE THIS POST CLICKING AT TOP RIGHT OF THIS PAGE. AT LINK: ENGLISH VERSION)
La ]]></description>
<content:encoded><![CDATA[<p><em><strong>(NOTE :YOU CAN TRANSLATE THIS POST CLICKING AT TOP RIGHT OF THIS PAGE. AT LINK: ENGLISH VERSION)</strong></em></p>
<p>La espera llega a su fín... después de mucho, mucho tiempo, ya tenemos aquí la primera versión pública del Lotus Designer basado sobre Eclipse!!!</p>
<p>Los desarrolladores hemos visto como el cliente se mejoraba a marchas forzadas cambiando el aspecto y las funcionalidades de Notes hasta limites que jamas hubieramos imaginado cuando apostamos por esta plataforma pero... ya era hora que algunas de esas mejoras repercutieran directamente sobre nuestro entorno de trabajo puesto que, aunque cumple su cometido, nuestro querido Designer se había quedado obsoleto comparado con otros IDEs.</p>
<p>Sin más preámbulos, voy a empezar...</p>
<p>Está es la página inicial del Designer</p>
<p><a href="http://jalemanyf.files.wordpress.com/2008/06/1paginainicial1.jpg"><img class="alignnone size-full wp-image-410" src="http://jalemanyf.wordpress.com/files/2008/06/1paginainicial1.jpg" alt="" width="460" height="329" /></a></p>
<p>Como podeis apreciar se nota la profunda influencia de Eclipse, pero teniendo en cuenta que es uno de los mejores entornos de desarrollo (si no el mejor) para Java, no debería asustarnos sino ver todo lo que puede aportarnos. Algunas de las nuevas características que se nos indica en la página de bienvenida son:</p>
<ul>
<li>Podemos ajustar el entorno de trabajo como deseemos (hacer más grane un frame u otro) sólo se tiene que ajustar con Drag &#38; Drop y si queremos volver al principio con resetear la perspectiva bastará.</li>
</ul>
<ul>
<li>Cada una de las ventanas se pueden maximizar y minimizar.</li>
</ul>
<ul>
<li> Se pueden agrupar bases de datos y mostrar u ocultar los grupos. Todo ello desde un icono en el navegador.</li>
<li>El nuevo elemento de diseño XPages que permite llevar a nuestro Notes a la web 2.0.</li>
<li>Casi todo puede ser calculado! Allí dónde veais un pequeño icono en forma de diamante azul, sólo debereis hacer click para que se habrá el editor de código.</li>
<li>Las funciones arroba ahora están disponibles desde Javasrcipt.</li>
<li>Las solapas de eventos ahora permiten escribir Javascript desde el lado del cliente o del Servidor.</li>
</ul>
<p>Vamos a profuncizar un poquito más (aunque este artículo será sólo un preliminar de otros más a fondo). Como desarrollador, me preocupa si encontraré de manera fácil y cómoda todo aquello que ya he desarrollado y si me encontraré estraño en este nuevo designer...</p>
<p><a href="http://jalemanyf.files.wordpress.com/2008/06/4editor.jpg"><img class="alignnone size-full wp-image-416" src="http://jalemanyf.wordpress.com/files/2008/06/4editor.jpg" alt="" width="460" height="345" /></a></p>
<p>Como se aprecia en esta imagen el entorno es muy parecido a nuestro designer de toda la vida salvo por un par de ventanas más que he coloreado en rojo transparente para que destacasen sobre el resto. Se ha mejorado mucho el aspecto de los iconos y tambien el de las solapas pero hay elementos como el editor principal que se mantienen con el aspecto antiguo. La verdad es que eso se mantiene en unos cuantos controles dónde se mezcla la interfaz moderna con la antigua...</p>
<p><a href="http://jalemanyf.files.wordpress.com/2008/06/5lotusscriptold.jpg"><img class="alignnone size-full wp-image-417" src="http://jalemanyf.wordpress.com/files/2008/06/5lotusscriptold.jpg" alt="" width="460" height="345" /></a></p>
<p>Del mismo Eclipse heredamos editores de CSS, XML y HTML mucho más adecuados...</p>
<p><a href="http://jalemanyf.files.wordpress.com/2008/06/7editorcss.jpg"><img class="alignnone size-full wp-image-418" src="http://jalemanyf.wordpress.com/files/2008/06/7editorcss.jpg" alt="" width="460" height="345" /></a></p>
<p>Ahora quiero comentaros algunas de las nuevas características (aunque será sólo por encima en este primer artículo de toma de contacto):</p>
<ul>
<li>XPages: Una Xpage (el nombre no es el más acertado... lo se) es un nuevo elemento de diseño que va a permitir realizar páginas Web 2.0 basadas en la tecnologís JSF. Las XPages eliminarán la barrera para programar soluciones web en Domino. Sus principales funcionalidades son:</li>
</ul>
<ol>
<li>Permiten hacer AJAX refrescando sólo una parte de la página web en lugar de toda entera.</li>
<li>Soporte total para cambiar el estilo a traves de CSS.</li>
<li>Biblioteca de web control avanzada: eso es por que se han incluído partes de Dojo permitiendonos hacer unas interfaces más ricas e interactivas.</li>
<li>Totalmente ampliable mediante el uso de los <em>custom controls</em> (Los custom controls son colecciones de controles almacenados como un sólo objeto, algo así como los subformularios de siempre. Cuando un custom control se actualiza, este se actualiza en todas las páginas dónde se hubiera usado).</li>
</ol>
<ul>
<li>Themes: los temas son otro de los nuevos elementos de diseño y, se podría decir que son como las tipicas "skins" que vemos en algunos otros productos pero para nuestras bases de datos. Pueden ser usados conjuntamente con las XPages para customizar el <em>look and feel</em> de cualquier aplicación. Los temas podrán ser aplicados globalmente a todas las aplicaciones de un servidor o bien sólo a una aplicación y diferentes temas podrán ser aplicados en función del contexto.</li>
</ul>
<p>Espero que esta primera entrega os haya apasionado tanto como a mi. En estos momentos aún no somos capaces de vislumbrar todas las maravillas que los desarrolladores serán capaces de hacer con todos estos avances pero por fin Lotus está en el buen camino...</p>
<p>Pronto, la segunda entrega!</p>
<p>Josep Alemany</p>
<p>PS: Para todos aquellos que quieran enviarme sugerencias de como mejorar la relación de IBM con los Bussiness Partners, podéis enviarmela al mail jalemanyf@gmail.com. Recordad que los días 10 y 11 voy a presentarles todas vuestras sugerencias...</p>
<p><a href="http://jalemanyf.files.wordpress.com/2008/06/m1entorno.gif"> </a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Performance basics for IBM Lotus Notes developers - Some additions?]]></title>
<link>http://quintessens.wordpress.com/?p=161</link>
<pubDate>Sat, 17 May 2008 18:11:44 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/?p=161</guid>
<description><![CDATA[Andre Guirard wrote a nice interesting piece of document regarding considerations for application de]]></description>
<content:encoded><![CDATA[<p>Andre Guirard wrote a nice interesting piece of document regarding considerations for application development. The document you can <a title="download the document" href="http://www.ibm.com/developerworks/lotus/documentation/d-ls-notesperformance/" target="_blank">download here</a>.</p>
<p>Recently I have asked to write down some 'best practices' from a developer perspective. I see a lot of Andre's writing return in this, also since most of my work was 'just' a collection of documents / papers / hints &#38; tips I have collected the past years.</p>
<p>I will wrote some additional performance considerations which I did not find back in Andre's work:</p>
<p><strong>Use @trim in all translation events for fields type text, this avoids that you later have to use it in view columns</strong></p>
<blockquote><p>@Trim(@ReplaceSubstring(@ThisValue; @Char(9):@Newline; " "))</p></blockquote>
<p>----</p>
<p><strong>Make sure when using subforms something is written in Globals of the subform, it dus not matter what (Notes only)</strong></p>
<blockquote><p>Dim loadfaster As Integer<br />
loadfaster =True</p></blockquote>
<p>The more subforms you have the more effect code in Globals has.</p>
<p>----</p>
<p><strong>Don't use "Print" so much (LotusScript)</strong></p>
<p>Minimize the use of the Print statement when performing actions in long loops. Printing a lot of messages to the status bar or console uses a surprising amount of memory, and it can have a noticible impact on an otherwise fast-running loop. Specifically, the memory used by each Print statement is not released until the entire agent is finished.</p>
<p>----</p>
<p><strong>Avoid large or complex tables</strong></p>
<p>Large or complex tables can greatly affect the speed with which a form can be rendered (both in the client and in the browser). In particular, avoid tables with a huge number of rows, a lot of nesting, or a large number of hide-when conditions.</p>
<p>----</p>
<p><strong>For agents: avoid Reader fields when possible</strong></p>
<p>Using Reader fields can slow down all of your document processing code across the board, because the database has to evaluate the reader fields for each document before it can even attempt to do anything with them. This is especially true when the agent signer doesn't have access to a large number of documents in the database, because the documents that aren't visible still have to be evaluated before they can be skipped.</p>
<p>----</p>
<p><strong>Share NotesView References</strong></p>
<p>If you need to use a reference to a view multiple times in your code, get the view only once and share the reference (either using a global or static variable, or by passing a NotesView object as a parameter in functions/subs/methods). Accessing views using getView is a very expensive operation.</p>
<p>----</p>
<p><strong>Use @Function Agents For Simple Document Modifications</strong></p>
<p>If you just need to modify, add, or delete one or several [non rich-text] fields in all or selected documents in a view, it is much faster to use an agent with simple @Functions (rather than LotusScript or Java) that runs against all or selected documents. </p>
<p>----</p>
<p><strong>Resize Arrays Infrequently</strong></p>
<p>ReDim your arrays as infrequently as possible. However, if you have to append data to an array quite often, Redim Preserve is MUCH more efficient than many calls to ArrayAppend</p>
<p>---</p>
<p><strong>Default view</strong></p>
<p>Whenever your application is opened, your default view is opened. Always be sure that this is a view that opens quickly.</p>
<p>----</p>
<p><strong>Use buttons and picklists instead of drop-down lists</strong></p>
<p>In some cases, there are so many drop-down lists, and they’re so large and used so frequently, that the only reasonable solution is to stop using them on the main form. The line of reasoning to use is to ask yourself the following questions:</p>
<ul>
<li>How many times will a document be read in its life?</li>
<li>How many times will a document be edited?</li>
<li>Of the times it’s edited, how many times will these lookups be required?</li>
</ul>
<p>----</p>
<p><strong>Use DigestSearch Method</strong></p>
<p>For searching server-based databases from a Notes client, DigestSearch is twice as fast as any other search method available, outperforming both full-text search and LotusScript's GetDocumentByKey method. You call DigestSearch using this LotusScript command:</p>
<blockquote><p>Set doc=FastSearchByKey(db, "searchword")</p></blockquote>
<p>Like I said before, this is 'collected work' so I take no responsibility if it would not increase performance. See it as food for thought =)</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Perfect pagination style using CSS]]></title>
<link>http://quintessens.wordpress.com/?p=140</link>
<pubDate>Sun, 20 Apr 2008 17:16:37 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/?p=140</guid>
<description><![CDATA[One of the blogs I often read is the one from Antonio Lupetti who is a Web developer, not a Notes ]]></description>
<content:encoded><![CDATA[<p>One of the blogs I often read is the one from <a title="link to the blog" href="http://woork.blogspot.com/" target="_blank">Antonio Lupetti</a> who is a Web developer, not a Notes developer. Especially his article about pagination caught my attention since it remembered me about the idea to rewrite Bob Obringers 'ultimate view navigator'.</p>
<p>Bob uses in his approach for the pagination a table to display the page numbers where a list should be more suitable.</p>
<p>As the image below shows with Antonio's approach it is pretty easy to make the pagination more compatible with examples seen on other well known sites. Here is a Flickr alike pagination for a Domino view:</p>
<p><img src="http://quintessens.files.wordpress.com/2008/04/webnav.jpg" alt="Flickr alike domino view pagination" width="595" height="248" /></p>
<p>Anything new under the sun? Not really, but for the 'purists' under us more esthetic solution.</p>
<p>Ofcourse a <a title="link to the download" href="http://www.divshare.com/download/4299831-8d1" target="_blank">working example can be found here</a>.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Capturando errores]]></title>
<link>http://jalemanyf.wordpress.com/?p=379</link>
<pubDate>Thu, 27 Mar 2008 08:15:14 +0000</pubDate>
<dc:creator>jalemanyf</dc:creator>
<guid>http://jalemanyf.wordpress.com/?p=379</guid>
<description><![CDATA[Los errores en el código son uno de los peores quebraderos de cabeza para cualquier desarrollador. ]]></description>
<content:encoded><![CDATA[<p>Los errores en el código son uno de los peores quebraderos de cabeza para cualquier desarrollador. Notes tiene las típicas funciones para su captura (On error..., resume, resume next, etc...) pero a veces no son suficiente. Afortunadamente existe un proyecto que viene a suplir algunas de estas deficiencias: <i><a href="http://lserror.sourceforge.net/index.html" target="_blank">LS-ERROR</a></i></p>
<p>LS-ERROR es una librería programada en LotusScript completamente Open Source. De hecho, para instalarla uno se baja el código fuente directamente. Es muy fácil de instalar e implementar y sólo le faltaría un poco más de documentación para mi gusto (aunque uno puede abrir el código y entender lo que hace).</p>
<p>Como siempre, espero que os resulte útil ;)</p>
<p>Josep Alemany</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[How to display in lotus administrator the server tasks options...]]></title>
<link>http://pierrekoerber.wordpress.com/?p=62</link>
<pubDate>Mon, 18 Feb 2008 17:20:53 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=62</guid>
<description><![CDATA[When working with your server tasks in the lotus notes administrator client, sometimes you don]]></description>
<content:encoded><![CDATA[<p>When working with your server tasks in the lotus notes administrator client, sometimes you don't remember the options you've got on a special task.</p>
<p>You can right click on the task and a pop-up menu appears and then you can display a pop-up dialog box to choose the desired command... very handy ! just try it...</p>
<p><a href="http://pierrekoerber.wordpress.com/files/2008/02/tellamgr.gif" title="tellamgr.gif"><img src="http://pierrekoerber.wordpress.com/files/2008/02/tellamgr.gif" alt="tellamgr.gif" /></a></p>
<p><a href="http://www.pierre-koerber.ch"> http://www.pierre-koerber.ch</a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[How to get your lotusscript projects documented...]]></title>
<link>http://pierrekoerber.wordpress.com/?p=60</link>
<pubDate>Sun, 17 Feb 2008 18:29:42 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=60</guid>
<description><![CDATA[As a professional your project should be documented&#8230; I&#8217;m a fan of lotusnotes but we shou]]></description>
<content:encoded><![CDATA[<p>As a professional your project should be documented... I'm a fan of lotusnotes but we should agree that the lotus notes designer is a poor tool for that. (it is a poor tool to develop  object in lotus script)</p>
<p>Have a look on this link to get your lotus script classes well documented...</p>
<p><a href="http://www.lsdoc.org">http://www.lsdoc.org</a></p>
<p><a href="http://www.pierre-koerber.ch">http://www.pierre-koerber.ch</a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[How to change the creation date in lotus notes... $created]]></title>
<link>http://pierrekoerber.wordpress.com/?p=57</link>
<pubDate>Sat, 16 Feb 2008 17:03:38 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=57</guid>
<description><![CDATA[I have found in a forum this little trick.
Just add a field in the document named $Created, the docu]]></description>
<content:encoded><![CDATA[<p>I have found in a forum this little trick.</p>
<p><font color="blue" size="3">Just add a field in the document named $Created, the document will show the date in this field for the formula @created in views... nice and useful !    </font></p>
<p><font color="blue" size="3">/* Created date, if specified overrides UNID created date for @Created */<br />
#define   FIELD_CREATED   "$Created"</font></p>
<p><a href="http://www.pierre-koerber.ch">http://www.pierre-koerber.ch</a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[How to run instantly an lotus notes agent...]]></title>
<link>http://pierrekoerber.wordpress.com/?p=58</link>
<pubDate>Wed, 13 Feb 2008 18:00:16 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=58</guid>
<description><![CDATA[ Here an original piece of code to launch instantly an agent without to schedule it every5 minutes. ]]></description>
<content:encoded><![CDATA[<p> Here an original piece of code to launch instantly an agent without to schedule it every5 minutes. This is an original tip.</p>
<p>Here a summary of the Amgr command which allows to launch an agent directly from the notes server console.  (from the lotus notes designer help file)</p>
<table border="1" width="100%">
<tr valign="top">
<td width="24%"><font face="sans-serif" size="1">Tell Amgr Run</font></td>
<td width="75%"><font face="sans-serif" size="1">Runs the agents that you designate with these arguments:</font><font face="sans-serif" size="1">"db name" 'agent name' </font><font face="sans-serif" size="1">Example: Tell Amgr Run "DatabaseName.nsf" 'AgentName'</font></td>
</tr>
</table>
<p>Ok, the next idea is to use the notessession <font face="sans-serif" size="2">SendConsoleCommand() which allows to send a console command directly to a server.</font></p>
<p><font face="sans-serif" size="2">So if we put all together we can invoke directly an agent from our code... nice !</font></p>
<p><font face="sans-serif" size="2"></font><br />
<font face="sans-serif" size="2">Dim se as new notessession</font><br />
<font face="sans-serif" size="2">Dim sCmd As String</font><br />
<font face="sans-serif" size="2">        </font><br />
<font face="sans-serif" size="2">sCmd = &#124;tell amgr run "%1" '%2'&#124;</font><br />
<font face="sans-serif" size="2">sCmd = Replace(sCmd, "%1", "databasePath\file.nsf")</font><br />
<font face="sans-serif" size="2">sCmd = Replace(sCmd, "%2", "agentName")</font><br />
<font face="sans-serif" size="2">Call se.SendConsoleCommand("yourServerName", sCmd)</font></p>
<p><a href="http://www.pierre-koerber.ch">http://www.pierre-koerber.ch</a></p>
<p><font face="sans-serif" size="2"></font></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[LotusScript - Obscure Features Primer For Beginners]]></title>
<link>http://brainflush.wordpress.com/?p=11</link>
<pubDate>Wed, 13 Feb 2008 02:50:40 +0000</pubDate>
<dc:creator>Matthias</dc:creator>
<guid>http://brainflush.wordpress.com/?p=11</guid>
<description><![CDATA[I am currently programming for Lotus Notes, version 7 and I am struggling with the LotusScript langu]]></description>
<content:encoded><![CDATA[<p>I am currently programming for <a href="http://en.wikipedia.org/wiki/Lotus_notes" target="_blank">Lotus Notes</a>, version 7 and I am struggling with the <a href="http://en.wikipedia.org/wiki/LotusScript" target="_blank">LotusScript</a> language which is the language of choice for Lotus Notes agent programming. I am coming from the Java camp and although I have been coding in various scripting languages like JavaScript, Python and Perl, LotusScript is a completely different beast, as it's a <a href="http://en.wikipedia.org/wiki/BASIC_programming_language" target="_blank">BASIC</a> dialect. I don't consider BASIC to be a well designed language already, but LotusScript actually makes things worse because it misses some language constructs people are used to from VisualBasic and introduces some new subtleties making programming LotusScript even less intuitive. Here is a list of some of the more obscure language characteristics which may irritate people new to LotusScript.</p>
<h3>To Dim or not to Dim</h3>
<p>For a reason I can't quite put my hands on, in LotusScript variables are not declared using a unified syntax. Sometimes you have to use the Dim keyword, and sometimes you don't. I think Dim actually means "declare a variable with local scope", which means, local to the body of a procedure (a procedure in LS is a function, a sub or a method) or local to a module. But then again, you do not use Dim to declare member variables of classes, although they are local to that class. So just remember: No Dim in class bodies, but in modules and procedures. You do not use Dim for constants by the way, just for variables. For constants, use the Const keyword.</p>
<h3>Implicit declarations</h3>
<p>This is one of the language "features" I simply consider bad design. Unlike e.g. JavaScript, in LS you can bring a variable to life merely by referencing it. No declaration or definition required at all. In JavaScript, referring to a variable without it being declared results in a runtime error. The LS runtime however will happily accept that code using a best effort strategy and simply treat everything it doesn't know as a variable of type Variant. Get this:</p>
<p>[sourcecode language="vb"]<br />
Sub foo<br />
    messagebox bar<br />
End Sub[/sourcecode]<br />
Merely by referencing the undefined symbol "bar", LS will treat it as a Variant with value Nothing instead of issuing an error. This can lead to bugs which are very difficult to track down, because a typo in an identifier will still make your code run; it just won't do what you expect. As I cannot think of any situation where one would want to access a variable without defining it first to actually carry some value, I can only flag this behavior flawed design. As user Papa pointed out in the comments section, you can fortunately force the compiler to reject references to undefined symbols by putting "Option Explicit" somewhere in your declarations section. I strongly suggest doing so when setting up a new project.</p>
<h3>Calling procedures</h3>
<p>Even after programming for several weeks, I still can't get used to the completely awkward and inconsistent rules for how you call procedures. For example, you may call subs using the Call keyword. If you do that, you can decide whether you want to omit the parentheses when the sub does not take any arguments. However, without Call, it is forbidden to use parentheses if the sub doesn't take any arguments! Moreover, Call cannot be used for assigning a function's return value to some variable, so you will have to use the "normal" syntax in these cases. BUT! Of course there is an exception, namely that when assigning from the sub, you now may use empty parentheses when the function takes no arguments (just don't you dare to use Call!) So why use Call at all? I don't know! It's completely useless. Find below the Call insanity summarized in all its glory:</p>
<p>[sourcecode language="vb"]<br />
Call f2<br />
Call f2()<br />
f2<br />
f2() 'illegal!<br />
x = f2<br />
x = f2()<br />
x = Call f2 'illegal!<br />
x = Call f2() 'illegal![/sourcecode]<br />
Nice huh? There is another catch related to how arguments are passed to procedures. LotusScript provides two semantically different ways: Passing by value and passing by reference. Get this:<br />
[sourcecode language="vb"]<br />
Dim x as new SomeClass<br />
foo(x)[/sourcecode]<br />
This code won't compile, because it very likely does NOT do what you think it does. Here we declare a variable x pointing to an object of class SomeClass. Next, we pass it as an argument to procedure foo, <i>but we pass it by value</i>, which is illegal for objects. The catch in this example is that you have to read the parentheses around x as being part of the argument to foo, and not (as you probably expected) as part of the call syntax. Parentheses around a single argument is simply LotusScript's way to explicitly say: "Pass this argument by value".  However, be careful: There is another catch. When using the Call keyword instead to invoke the function above, the parentheses are in fact now part of the call statement itself, which means, x will be passed by reference, which is fine. So in order to produce the same error when using Call, you would have to alter the code to look like this:<br />
[sourcecode language="vb"]<br />
Dim x as new SomeClass<br />
Call foo((x))[/sourcecode]<br />
Gotcha!</p>
<h3>NULL Is Not NOTHING</h3>
<p>In Java, if you do not assign an object reference to an object, its value is intially NULL. In LS, it's not. If you do not define an object reference to point to some object, its value is NOTHING instead (this is similar to JavaScript's undefined, just that NOTHING is a keyword which you can use in your code). This means, checking object references for NULL always returns false. Okay, this wouldn't be that bad, if the inconsistencies wouldn't start here, because: Variants can be NULL. However, Variants are variant, hence their name, which especially means they can point to objects. Which for the isNull() argument in turn means (taken from the LS reference manual):</p>
<blockquote><p>Any expression except an object reference or a Variant that contains an object reference.</p></blockquote>
<p>Which, of course, you may not even know in advance, otherwise you wouldn't have used a Variant, no? (Okay, except for the case where the language forces you to use them, see below!)</p>
<h3>Using Arrays</h3>
<p>Working with arrays in LS is the most tedious and irritating thing I have seen so far. In LS, there are two kinds of arrays: Fixed and dynamic ones. With the exception that the latter aren't really dynamic: Their only "dynamics" are that you can omit the dimensionality when declaring them. As soon as you work with them however, you have to Redim them for the correct dimensionality you need. No array.push(). What's even weirder is that you cannot assign something to a variable declared as an array -- only to its components. For example, it is perfectly fine to do this:</p>
<p>[sourcecode language="vb"]<br />
Dim arr(5) as Integer<br />
arr(0) = 1[/sourcecode]<br />
However, you can't do this:<br />
[sourcecode language="vb"]<br />
Dim arr() as Integer<br />
arr = functionReturningArray() 'illegal<br />
arr() = functionReturningArray() 'illegal, works in VB<br />
Set arr = functionReturningArray() 'illegal<br />
Set arr() = functionReturningArray() 'illegal[/sourcecode]<br />
So how you assign an array you ask? You have to declare the array as Variant, in both the function returning it and the variable receiving it:<br />
[sourcecode language="vb"]<br />
Dim arr as Variant<br />
arr = functionReturningArrayDeclaredAsVariant()[/sourcecode]</p>
<h3>User defined types</h3>
<p>Functions in LS may return a reference to a class instance, but not to a user defined type. Why? I don't know. The practical implication is that no one uses user defined types but simply abuses the class concept to create data structures. So just remember, don't use UDTs if you plan to use them as return values from functions; use classes instead.</p>
<h3>Lists are no lists</h3>
<p>You also wondered about the List type? Me too, mainly because it's not a list type. It's actually an associative array (a "map" in Java terminology) so don't get too confused.</p>
<h3>The bottom line</h3>
<p>Okay, this is it so far; my revised version of what initially started as a rant about LotusScript... I hope it helps those people who are new to LotusScript programming (and who maybe come from more popular languages like Java) to cope with some of the not-so-intuitive things about the LotusScript language.</p>
<p>Happy coding!</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Kill notes... use NotesKiller !]]></title>
<link>http://pierrekoerber.wordpress.com/?p=56</link>
<pubDate>Tue, 12 Feb 2008 17:59:07 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/?p=56</guid>
<description><![CDATA[Even the bests are fallible&#8230; when your notes is letting you down&#8230; go and try the NotesKi]]></description>
<content:encoded><![CDATA[<p>Even the bests are fallible... when your notes is letting you down... go and try the NotesKiller</p>
<p><a href="http://www.madicon.de/noteskiller/screenshots/">http://www.madicon.de/noteskiller/screenshots/</a></p>
<p>Enjoy !</p>
<p><a href="http://www.pierre-koerber.ch">http://www.pierre-koerber.ch</a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Manipulating windows Registry by lotusscript]]></title>
<link>http://bnoutash.wordpress.com/2008/01/31/manipulating-windows-registry-by-lotusscript/</link>
<pubDate>Thu, 31 Jan 2008 15:02:50 +0000</pubDate>
<dc:creator>noutash</dc:creator>
<guid>http://bnoutash.wordpress.com/2008/01/31/manipulating-windows-registry-by-lotusscript/</guid>
<description><![CDATA[I have seen many posts in Lotus Notes 6 and 7 forum and other places asking how to add or remove val]]></description>
<content:encoded><![CDATA[<p>I have seen many posts in Lotus Notes 6 and 7 forum and other places asking how to add or remove values in windows registry using lotusscript. The solutions suggested usually involve many lines of code and knowledge of windows APIs. After some thought, I found a simpler way to achieve the same thing and I thought I would share it here.</p>
<p>The solution is simple; just use windows built-in REG command. Below is an example, where I enable font smoothing through the registry in the postopen even of my database:</p>
<p>Dim intResult as Integer<br />
intResult = Shell ({REG ADD "HKCU\Control Panel\Desktop" /v FontSmoothing /t REG_SZ /d 2 /f})</p>
<p>The code above should be self-explanatory. It changes the value of FontSmoothing key in HKEY_CURRENT_USER\ControlPanel\Desktop to value of 2.</p>
<p>Using the same method, you can do anything with the registry. Simply go to your command prompt and type “REG /?” without quotes to get a list of available commands.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Lotus Domino : Log Analyzer and more...]]></title>
<link>http://pierrekoerber.wordpress.com/2007/11/10/lotus-domino-log-analyzer-and-more/</link>
<pubDate>Sat, 10 Nov 2007 08:10:53 +0000</pubDate>
<dc:creator>pierrekoerber</dc:creator>
<guid>http://pierrekoerber.wordpress.com/2007/11/10/lotus-domino-log-analyzer-and-more/</guid>
<description><![CDATA[Lotus Domino est un bon serveur qui loggue un maximum d&#8217;information. Cependant même en tant q]]></description>
<content:encoded><![CDATA[<p>Lotus Domino est un bon serveur qui loggue un maximum d'information. Cependant même en tant qu'administrateur fullTime, il est difficile d'avoir le temps de parcourir le log.</p>
<p>Pour ce faire je vous conseille la mise en place de log Analyzer qui vous permet de faire des recherches agendées sur un ensemble de mots clé sur votre base de log. Une fois mis en place, c'est un soulagement dans le quotidien.</p>
<p><a href="http://www.virtualobjectives.com.au/notesdomino/notesdomino-index.htm">http://www.virtualobjectives.com.au/notesdomino/notesdomino-index.htm</a></p>
<p>Profitez de ce site qui contient plein d'autres utilitaires incontournable.</p>
<p><a href="http://www.pierre-koerber.ch">http://www.pierre-koerber.ch</a></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Principal Suspect]]></title>
<link>http://dominoeffect.wordpress.com/2007/11/01/principal-suspect/</link>
<pubDate>Thu, 01 Nov 2007 06:10:22 +0000</pubDate>
<dc:creator>Patrick</dc:creator>
<guid>http://dominoeffect.wordpress.com/2007/11/01/principal-suspect/</guid>
<description><![CDATA[Given a scenario when your database is supposed to send out email notifications which when replied t]]></description>
<content:encoded><![CDATA[<p>Given a scenario when your database is supposed to send out email notifications which when replied to would automatically send it to a given email account, I've always thought the straightforward use of the Principal would suffice. That is, the given code should do the trick:</p>
<blockquote><p>doc.Principal = "johndoe@acme.com"</p></blockquote>
<p>But it doesn't. If you have that LS code within a design element, say a button on a form, and a certain Jane Doe does the clicking, the email sent still shows Jane Doe's name in the <strong>From</strong> field. Now that's bad.</p>
<p>The first thing for me to try was to set every Memo field where <em>Jane Doe</em> appears to <em>johndoe@acme.com</em>. Tough luck though as Jane Doe's email address still shows up in the notifications' <strong>From</strong> field. Unfortunately, setting the <strong>From</strong> field manually didn't do it because from inspection of the design of 6.5 mail databases from where I am, the said field is computed when composed!</p>
<p>Next was to rummage through the forums hoping that something would eventually pop up there. A little over half an hour it did!</p>
<p>The first thing I encountered was the <a href="http://www.ibm.com/developerworks/lotus/library/ls-Troubleshooting_agents_ND5_6/" target="_new">Agent Troubleshooting Guide</a> by Julie Kadashevich. In that long list of helpful tips, there's a section, <strong>How can I change the apparent sender of agent generated mail?</strong>, discussing three ways to programmatically set a notification's entry for the Sender.</p>
<p>Apparently there are three ways to set the <strong>Principal</strong> field in emails. From the Guide, these are:</p>
<ol>
<li>doc.Principal="Joe User/Org@NotesDomain" where Joe User/Org has a Person record with an InternetAddress of your choosing. (Note that the string @NotesDomain must be present.)</li>
<li>doc.Principal="CN=Joe User/O=Org" where Joe User/Org has a Person record with an InternetAddress of your choosing.</li>
<li>doc.Principal=User@acme.org@NotesDomain . (Note that the string @NotesDomain must be present.)</li>
</ol>
<p>But any method there still didn't get it done though. Other mail clients still continue to display <em>Jane Doe</em> in the <strong>From</strong> field.</p>
<p>Fortunately then, <a href="http://www-10.lotus.com/ldd/nd6forum.nsf/55c38d716d632d9b8525689b005ba1c0/f92e2a43a982c1738525714f00408c88?OpenDocument" target="_new">this forum response</a> points me to somewhere I should've looked at before. In his blog entry, Notes/Domino hotshot <a href="http://codestore.info/store.nsf/unid/BLOG-20060321" target="_new">Jake Howlett writes in his blog</a> about the lines of code that would eventually work for me:</p>
<p align="left">
<blockquote><p>doc.Principal = "John Doe &#60;johndoe@acme.com@NotesDomain&#62;"<br />
doc.InetFrom = "John Doe &#60;johndoe@acme.com&#62;"</p></blockquote>
<p>I never bothered to check there before in the first place because troubles with the field was the last thing I would expect from Jake. What more about a reason to find time to write about something supposedly easy?</p>
<p>Anyway I would recommend reading that blog entry as it clears up a lot of <strong>Principal</strong>-related stuff from the guide.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[One line @ReplaceSubString for lotusscript]]></title>
<link>http://rndnotes.wordpress.com/2007/10/30/one-line-replacesubstring-for-lotusscript/</link>
<pubDate>Tue, 30 Oct 2007 15:55:54 +0000</pubDate>
<dc:creator>Tomas Ekström</dc:creator>
<guid>http://rndnotes.wordpress.com/2007/10/30/one-line-replacesubstring-for-lotusscript/</guid>
<description><![CDATA[[Update: Read the comments,  for a much better solution!]
Had this problem removing single characte]]></description>
<content:encoded><![CDATA[<p>[Update: Read the comments,  for a much better solution!]</p>
<p>Had this problem removing single characters in a string. I don't like the idea to use strRight() and strLeft() since they can only handle a single entry of the search string.</p>
<p>There are a lot of different solution for this. I have also made my own lotusscript function for @replaceSubString, as every one else. All to complex since Release 6.</p>
<p>Some split and join will do the trick. This is my one liner:<br />
<code><u>resultStr </u>= join( split( <u>sourceStr</u>,  <u>fromStr </u>), <u>toStr</u> )</code></p>
<p>The replace is case sensitive.</p>
<p>Example replacing word:<br />
<img src="http://rndnotes.wordpress.com/files/2007/10/replacesubstring1.gif" alt="ReplaceSubString Example1" /></p>
<p>Button code:</p>
<blockquote><p><code>Dim ui As New NotesUIWorkspace<br />
Dim uidoc As NotesUIDocument<br />
Dim doc As NotesDocument<br />
Set uidoc = ui.CurrentDocument<br />
Set doc = uidoc.Document<br />
doc.result = Join(Split(doc.text(0),doc.Replace(0)),doc.replacewith(0))</code></p></blockquote>
<p>Example removing character:<br />
<img src="http://rndnotes.wordpress.com/files/2007/10/replacesubstring2.gif" alt="ReplaceSubString Example2" /></p>
<p>Or make a function out of it to make it more readable:</p>
<blockquote><p><code>Function replaceSubString(sourceStr As String, fromStr As String, toString As String) As String<br />
</code></p>
<blockquote><p><code> replaceSubString = Join(Split(sourceStr,fromStr),toString)</code><br />
<code></code></p></blockquote>
<p><code> End Function</code></p></blockquote>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Stamp It All In]]></title>
<link>http://dominoeffect.wordpress.com/2007/10/29/stamp-it-all-in/</link>
<pubDate>Mon, 29 Oct 2007 13:57:07 +0000</pubDate>
<dc:creator>Patrick</dc:creator>
<guid>http://dominoeffect.wordpress.com/2007/10/29/stamp-it-all-in/</guid>
<description><![CDATA[Just a question: How do you code the part of the WQS agent which implements changes in a given field]]></description>
<content:encoded><![CDATA[<p><a href="http://dominoeffect.wordpress.com/files/2007/10/stamp2.jpg" title="stamp2.jpg"><img src="http://dominoeffect.wordpress.com/files/2007/10/stamp2.jpg" alt="stamp2.jpg" align="left" border="0" hspace="5" /></a>Just a question: How do you code the part of the WQS agent which implements changes in a given field from the current document to the response documents under it?</p>
<p>Never realized how practical (or surprising) that question turned out to be early this month. I'm talking about <a href="http://www.codestore.net/store.nsf/unid/BLOG-20071001" target="_blank">Jake's dedicated entry</a> for a neat, single line of code he learned from a client. His initial take on the situation, (how to get Readers field changes reflect on response documents,) was how I'd handle the situation as well.</p>
<p>Anyway here's the neat "trick":</p>
<blockquote><p><span class="TPkeyword1">Call </span>Web.Document.Responses.StampAll<span class="TPbracket">(</span><span class="TPstring">"DocReaders"</span>, Web.Document.DocReaders<span class="TPbracket">)</span></p></blockquote>
<p>Just another welcome addition to my bread and butter I guess.</p>
<pre></pre>
<p><em>The image was taken from <a href="http://www.sxc.hu/photo/181554" target="_blank">here</a> btw.</em></p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Get keyword function]]></title>
<link>http://quintessens.wordpress.com/2007/10/04/get-keyword-function/</link>
<pubDate>Thu, 04 Oct 2007 06:08:12 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/2007/10/04/get-keyword-function/</guid>
<description><![CDATA[Here a simple LotusScript function that I use quite a lot to get keyword values:
Function Get_Keywor]]></description>
<content:encoded><![CDATA[<p>Here a simple LotusScript function that I use quite a lot to get keyword values:</p>
<p>Function Get_Keyword(dbCurrent As NotesDatabase, sKey As String) As NotesDocument<br />
 Dim viewKeywords As NotesView<br />
 Dim docReturn As NotesDocument<br />
 Set viewKeywords = dbCurrent.GetView("v-keywords")<br />
 Set docReturn = viewKeywords.GetDocumentByKey(sKey)<br />
 Set Get_Keyword = docReturn<br />
End Function</p>
<p>Usage:</p>
<p>Set keyword = Get_Keyword(dbCurrent, "keyword_key")</p>
<p>where keyword_key is the first fieldvalue in the view to search for...</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Demo 'collapse embedded view by default']]></title>
<link>http://quintessens.wordpress.com/2007/09/29/demo-collapse-embedded-view-by-default/</link>
<pubDate>Sat, 29 Sep 2007 18:16:17 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/2007/09/29/demo-collapse-embedded-view-by-default/</guid>
<description><![CDATA[Today it was here very rainy so I hate plenty of time to do those things you wtill wanted/needed/wer]]></description>
<content:encoded><![CDATA[<p>Today it was here very rainy so I hate plenty of time to do those things you wtill wanted/needed/were asked to do. For example I receive frequently question to send a working example for collapsing an embedded view by default. I have explained the principles in <a target="_blank" href="http://quintessens.wordpress.com/2006/10/29/collapse-a-categorized-embedded-view-by-default/" title="link to the entry">a previous writing</a>.</p>
<p>Therefor I keep this blog entry short with just remaining a reference to the location where you can <a target="_blank" href="http://www.divshare.com/download/2158175-8ae" title="link to the download">download a working-example</a>.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Export to Excel wizard]]></title>
<link>http://quintessens.wordpress.com/2007/09/27/export-to-excel-wizard/</link>
<pubDate>Thu, 27 Sep 2007 04:01:28 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/2007/09/27/export-to-excel-wizard/</guid>
<description><![CDATA[I was asked to take a look at an existing application, and come up with suggestions to improve perfo]]></description>
<content:encoded><![CDATA[<p>I was asked to take a look at an existing application, and come up with suggestions to improve performance.</p>
<p>In a first look I found that most of the views, especially the default to be opened view, were set to refresh the index automatically... you can imagine how much the users love to start working with this application which has readers fields on all documents (NOT!).</p>
<p>When I asked were all the views were needed for, I got as reply: to have it in a format we want to make graphics in Excel.</p>
<p>Okej, why not delete these 'views to be exported for Excel' and replace them with an export functionality?</p>
<p><img src="http://quintessens.wordpress.com/files/2007/09/exp_startbutton.jpg" alt="export start button" /></p>
<p>So what where the needs?</p>
<ol>
<li>a set of fields for different types of forms that should be manageble by the application manager</li>
<li>an export-mechanism to Excel which should be easy to understand for end-users and give them the opportunity to create customizable exports.</li>
</ol>
<p>1) Export profiles</p>
<p>In order to create so-called Export profiles for different Notes forms I needed an additional form (ExcelFormExport) where the administrator can:</p>
<ul>
<li>select the desired form for export (FieldA)</li>
<li>select the form-fields that should be available for export (FieldB)</li>
</ul>
<p>This last field is being calculated when FieldA is being exited:</p>
<p>Sub Exiting(Source As Field)<br />
 Dim workspace As New NotesUIWorkspace<br />
 Dim uidoc As NotesUIDocument<br />
 Set uidoc = workspace.CurrentDocument <br />
 fieldvalue = Lcase(uidoc.FieldGetText("Tx_FormSelected"))<br />
 Dim doc As NotesDocument<br />
 Set doc = uidoc.document<br />
 If fieldvalue &#60;&#62; "" Then<br />
  Dim session As New NotesSession<br />
  Dim db As NotesDatabase<br />
  Set db = session.CurrentDatabase  <br />
  Forall form In db.Forms<br />
   If Lcase(form.Name) = fieldvalue Then<br />
    If Isempty(form.Fields) Then<br />
     Messagebox form.Name &#38; " has no fields..."<br />
    Else<br />
     'collecting the form fields<br />
     Dim arrFieldNames() As String<br />
     Dim iCount As Integer<br />
     iCount = 0     <br />
     Redim arrFieldNames(0)<br />
     Forall field In form.Fields      <br />
      Redim Preserve arrFieldNames(iCount)<br />
      arrFieldNames(iCount) = field<br />
      iCount = iCount + 1<br />
     End Forall     <br />
     Call doc.ReplaceItemValue("Tx_FormFields", BubbleSort(arrFieldNames))     <br />
     Call uidoc.Refresh()     <br />
    End If<br />
    Exit Sub<br />
   End If<br />
  End Forall<br />
  Messagebox "The form """ &#38; formNameIn &#38; """ does not exist"<br />
 End If<br />
End Sub</p>
<p>Bubblesort is a function which sorts the array with fieldnames:</p>
<p>Function BubbleSort(vtList As Variant) As Variant<br />
 Dim tmpValue As Variant<br />
 Dim x As Integer, y As Integer <br />
 If Ubound(vtList) = 1 Then<br />
  BubbleSort = vtList<br />
  Exit Function<br />
 End If <br />
 For x = 0 To Ubound(vtList)<br />
  For y = (x + 1) To Ubound(vtList)<br />
   On Error Resume Next<br />
   If vtList(x) &#62; vtList(y) Then<br />
    tmpValue = vtList(x)<br />
    vtList(x) = vtList(y)<br />
    vtList(y) = tmpValue<br />
   End If<br />
  Next<br />
 Next <br />
 BubbleSort = vtList <br />
End Function</p>
<p>Luckily I could make use of a solution from <a target="_blank" href="http://rndnotes.wordpress.com/" title="link to Tomas blog">my colleague Tomas Ekström</a> (his so-called 'tablewalker') which made the selection of fields and giving them for the end-user understandable 'labels' in the wizard:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/09/exp_profileform.jpg" alt="export profile form" /></p>
<p>The next step was creating a dialog between the available 'Export profiles' and the <a target="_blank" href="http://www-10.lotus.com/ldd/sandbox.nsf/ecc552f1ab6e46e4852568a90055c4cd/807dd94ea530733800256bd8003a4e36?OpenDocument" title="Download the solution at Sandbox">Export to Excel solution</a> written by Ken Pespisa.</p>
<p> <img src="http://quintessens.wordpress.com/files/2007/09/exp_source.jpg" alt="dialog for selection source" /></p>
<p>In order to display the 'Export profiles' in the dialoglist I had to re-write Ken's solution a bit. I advice you to use Ken's standard solution in stead.</p>
<p>Well, the rest of this export wizard is just following Ken's work.</p>
<p> <img src="http://quintessens.wordpress.com/files/2007/09/exp_wizard.jpg" alt="select fields for export dialog" /></p>
<p>What I tried to achieve with this solution is:</p>
<ul>
<li>having an easy way for an administrator to define 'Export profiles' based upon information on Notes forms.</li>
<li>presenting an understandable interface for the end-user that enables to create customizable exports to Excel</li>
<li>get rid of a large set of nasty Notes views!</li>
</ul>
<p>A demo you can <a target="_blank" href="http://www.divshare.com/download/2118057-bd4" title="link to the demo">download here</a>.</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[Newsletter profile]]></title>
<link>http://quintessens.wordpress.com/2007/09/06/newsletter-profile/</link>
<pubDate>Thu, 06 Sep 2007 08:38:40 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/2007/09/06/newsletter-profile/</guid>
<description><![CDATA[Currently I am working on a function where users can create a profile for a newsletter. In the profi]]></description>
<content:encoded><![CDATA[<p>Currently I am working on a function where users can create a profile for a newsletter. In the profile the user can specify a search query and some options.</p>
<p>It all begins with a simple View Action button:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/09/profile_button1.jpg" alt="profile form" /></p>
<p>The button will check if for the current user already a profile document exists, if so the document will be opened in edit mode, otherwise the form will be opened (the client requested to make all profiles public...)</p>
<p>varUser:=@Name([Abbreviate];@UserName);</p>
<p>@If(<br />
 @IsError(@DbLookup("":"NoCache";"";"v-userprofiles";varUser;"Tx_DocID"));<br />
  @Do(<br />
   @Command([Compose];"F-PU")<br />
  );<br />
  @Do(<br />
   @Command([OpenView];"v-userprofiles";varUser);<br />
   @Command([OpenDocument];"1")<br />
  )<br />
 )</p>
<p>The form itself is pretty plain and simple. The user can add more criteria to the search query via 'AND' or 'OR' options. Default we search on only one type of document.</p>
<p>While specifying the criteria, the user sees what he/she is adding to the query:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/09/profile_form.jpg" alt="the profile form" /></p>
<p>The code behind the 'ADD' button is this:</p>
<p>varForm:= "Document";<br />
varField:=Tx_Fields;<br />
varValues:=@Implode("\"" + Tx_Values + "\"" ;":");</p>
<p>@If(Tx_Option="AND";<br />
 @Do(<br />
  varConstructor:= " &#38; " +  varField + " = " + varValues;<br />
  @SetField( "Tx_Query" ; Tx_Query + varConstructor );<br />
  @SetField( "Tx_LastValue" ; varConstructor )<br />
 );</p>
<p> @Do(</p>
<p> @If(@Left(@GetField( "Tx_LastValue" );")")="";<br />
  @Do(<br />
   varPrevValue:= @Right(@GetField( "Tx_LastValue" );"&#38; ");<br />
   varConstructor:=  " &#38; ( " + varPrevValue + " &#124; " +  varField + " = " + varValues + " )"<br />
  );<br />
 @Do(<br />
  varPrevValue:= @LeftBack(@GetField( "Tx_LastValue" );")");<br />
  varConstructor:=  varPrevValue + " &#124; " +  varField + " = " + varValues + " )"<br />
 ));<br />
 varNewQuery:= @ReplaceSubstring( Tx_Query; Tx_LastValue ; varConstructor );<br />
 @SetField( "Tx_Query" ; varNewQuery );<br />
 @SetField( "Tx_LastValue" ; varConstructor )<br />
));</p>
<p>@SetField( "Tx_Fields" ; "");<br />
@SetField( "Tx_Values" ; "");<br />
@SetField( "Tx_Options" ; "")</p>
<p>I also added a button so the user can check if the specified query results in any usefull document collection. The code behind this button is:</p>
<p>Sub Click(Source As Button) <br />
 Dim workspace As New NotesUIWorkspace<br />
 Dim session As New NotesSession<br />
 <br />
 Dim db As NotesDatabase<br />
 Set db = session.CurrentDatabase<br />
 <br />
 Dim uidoc As NotesUIDocument<br />
 Set uidoc = workspace.CurrentDocument <br />
 <br />
 searchFormula$ = uidoc.FieldGetText( "Tx_Query" )<br />
 Dim collection As NotesDocumentCollection <br />
 Set collection = db.Search(searchFormula$, Nothing, 0)<br />
 numDocs% = collection.count<br />
 If numDocs% = 0 Then<br />
  Messagebox "There are no matching documents" , , "Search Result"<br />
  Exit Sub<br />
 Else<br />
  answer% = Messagebox ( (numDocs% &#38; " document(s) match this query. "), MB_OKCANCEL + MB_ICONQUESTION, "Search Result")<br />
 End If<br />
End Sub</p>
<p>Because the Newsletter function has to run on a scheduled basis I added some additional options:</p>
<ul>
<li>How often a Newsletter should be sent</li>
<li>The number of document links in the Notes Newsletter</li>
<li>How old corresponding documents may be</li>
</ul>
<p>Note: in the timestamp you can add for a search Notes uses the modified date, so this is the date the document has been modified (nice if you working on a test environment with a copy so all the documents ARE modified). You can also add this option as criteria in your search formula ofcourse.</p>
<p>On the bottom of the form I added a button where the user can instantly receive a Notes Newsletter with everything he/she has specified. The code for the button is:</p>
<p>Sub Click(Source As Button) <br />
 Dim workspace As New NotesUIWorkspace<br />
 Dim session As New NotesSession<br />
 <br />
 Dim db As NotesDatabase<br />
 Set db = session.CurrentDatabase<br />
 <br />
 Dim uidoc As NotesUIDocument<br />
 Set uidoc = workspace.CurrentDocument  <br />
 Dim doc As NotesDocument<br />
 Set doc = uidoc.Document<br />
 <br />
 searchFormula$ = uidoc.FieldGetText( "Tx_Query" ) <br />
 maxListSize = uidoc.FieldGetText( "Tx_QueryMax" )<br />
 daysAdjust = doc.Tx_QueryDays(0) <br />
 Dim dateTime As New NotesDateTime( Now )<br />
 Call dateTime.AdjustDay( -daysAdjust )<br />
 <br />
 Dim collection As NotesDocumentCollection<br />
 Set collection = db.Search(searchFormula$, dateTime, Cint(maxListSize))<br />
 numDocs% = collection.count<br />
 If numDocs% = 0 Then<br />
  Messagebox "There are no matching documents" , , "Search Result"<br />
  Exit Sub<br />
 Else<br />
  answer% = Messagebox ( (numDocs% &#38; " document(s) found. Creating a Newsletter..."), MB_OKCANCEL + MB_ICONQUESTION, "Search Result")<br />
  <br />
  Dim newsletter As NotesNewsletter<br />
  Set newsletter = New NotesNewsletter( collection )  <br />
  newsletter.DoSubject = True<br />
  newsletter.SubjectItemName = "Tx_Title"  <br />
  Dim newsletterdoc As NotesDocument<br />
  Set newsletterdoc = newsletter.FormatMsgWithDoclinks( db )  <br />
  newsletterdoc.Form = "Memo"<br />
  newsletterdoc.Subject = "Business Intelligence Newsletter - Your results"<br />
  Call newsletterdoc.Send( False, uidoc.FieldGetText( "Tx_UserName" ))  <br />
  <br />
 End If<br />
End Sub</p>
<p>Some parts of the code above I will re-use in the scheduled agent that sends out the Newsletters on a scheduled base.</p>
<p>Wrap-up: a simple handy function that might save you creating some additional views...</p>
]]></content:encoded>
</item>
<item>
<title><![CDATA[(User) Profile documents &amp; mandatory fields]]></title>
<link>http://quintessens.wordpress.com/2007/08/30/user-profile-documents-mandatory-fields/</link>
<pubDate>Thu, 30 Aug 2007 13:56:32 +0000</pubDate>
<dc:creator>quintessens</dc:creator>
<guid>http://quintessens.wordpress.com/2007/08/30/user-profile-documents-mandatory-fields/</guid>
<description><![CDATA[It has been a while since I wrote here something so I will just write something I did today. Right n]]></description>
<content:encoded><![CDATA[<p>It has been a while since I wrote here something so I will just write something I did today. Right now I am doing some prototyping for a demo-application (web) which generally will be an ordering system.</p>
<p>The application uses currently (user) profile documents. It was a bit hard to find code to copy &#38; paste, because most examples where not so detailed (just words, no code) or they used actual Notes documents, not profile documents.</p>
<p>So how does it work? When opening the form via an url (form_name?OpenForm) a WebQueryOpen Agent is initiated which runs the following simplified code:</p>
<p>Sub Initialize<br />
 Dim s As New NotesSession<br />
 Dim db As NotesDatabase<br />
 Dim profiledoc As NotesDocument<br />
 Set db = s.CurrentDatabase<br />
 Set profiledoc = db.GetProfileDocument("UserProfile", s.UserName) <br />
 Dim currentdoc As NotesDocument<br />
 Set currentdoc = s.documentcontext <br />
 currentdoc.Tx_UserLanguage = profiledoc.Tx_UserLanguage(0)<br />
 currentdoc.Tx_UserCostCenter = profiledoc.Tx_UserCostCenter(0)<br />
 currentdoc.Tx_UserGLAccount = profiledoc.Tx_UserGLAccount(0) <br />
 currentdoc.Tx_UserTechName = profiledoc.Tx_UserTechName(0)<br />
 currentdoc.Tx_UserTechPhone = profiledoc.Tx_UserTechPhone(0)<br />
 currentdoc.Tx_UserDeliveryStation = profiledoc.Tx_UserDeliveryStation(0) <br />
End Sub</p>
<p>So basically it picks (when available) the profiledoc and copies values from it to the opened form. I could have used IsProfile to check if we actually working with a profile document...</p>
<p>In the WebQuerySave event I run a different code which writes away information entered in the form to the profile document:</p>
<p>Sub Initialize<br />
 Dim s As New NotesSession<br />
 Dim db As NotesDatabase<br />
 Dim profiledoc As NotesDocument<br />
 Set db = s.CurrentDatabase<br />
 Set profiledoc = db.GetProfileDocument("UserProfile", s.UserName) <br />
 Dim currentdoc As NotesDocument<br />
 Set currentdoc = s.documentcontext <br />
 profiledoc.Tx_UserLanguage = currentdoc.Tx_UserLanguage(0)<br />
 profiledoc.Tx_UserCostCenter = currentdoc.Tx_UserCostCenter(0)<br />
 profiledoc.Tx_UserGLAccount = currentdoc.Tx_UserGLAccount(0) <br />
 profiledoc.Tx_UserTechName = currentdoc.Tx_UserTechName(0)<br />
 profiledoc.Tx_UserTechPhone = currentdoc.Tx_UserTechPhone(0)<br />
 profiledoc.Tx_UserDeliveryStation = currentdoc.Tx_UserDeliveryStation(0) <br />
 Call profiledoc.Save( True, False )<br />
End Sub</p>
<p>Later I think will use a similar functionality to write information back to the profile document, that hasn't been entered before in the user profile, from any sensible point in the application (like in a final order form)...</p>
<p>The first 'problem' i faced was that a 'normal' JavaScript submit would give me a 'form processed' message.  Since I had a nice 'update' button in mind so the user should stay in the form opened I was 'forced' to use a common known Domino 'work around'.</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/updatebuttons.jpg" alt="updatebuttons" /></p>
<p>The reference under the 'Save Setting' link inititates a JS function which actually initiates the function under a Notes button, that is being stored in a hidden &#60;div&#62;</p>
<p>function submitForm(){<br />
 document.all.MySaveButton.onclick();<br />
}</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/hidebutton.jpg" alt="hidebutton" /></p>
<p>So the JS function initiates the @Command([FileSave]) function which initiates the WebQuerySave event and thereby the user profile is being updated on the background.</p>
<p>Since the document will be re-opened due to a refresh (don't ask me why what forces this) the WebQueryOpen events initiates again and the saved information is being re-placed on the refreshed form...</p>
<p>So far so good, where is the news?</p>
<p>I wanted to make visible which fields are supposed to be mandatory and highlight them like in the next example:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/mandatoryempty.jpg" alt="mandatory empty" /></p>
<p>Here you have 'normal' fields with a gray border, and 'normal' entry fields that are supposed to be also 'mandatory'. So for these fields I add both classnames.</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/fieldprops.jpg" alt="field properties" /></p>
<p>On the JS onload event I initiate the following function:</p>
<p>checkISValid();</p>
<p>The code for this function is pretty basic and contains (in this example) no actualy validation, just a check if the field is empty or not:</p>
<p>function checkISValid(){<br />
 var checkFields = new Array();<br />
 checkFields = getElementsByClassName(document, "input", "mandatoryField")<br />
 for (x in checkFields){  <br />
  if (checkFields[x].value != "" ){<br />
   checkFields[x].className = "entryField"; <br />
  }<br />
 }<br />
}</p>
<p>So if the field with classname mandatoryField is empty it will get the mandatoryField class 'removed' (overwritten) and it will look like this:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/mandatoryfilled.jpg" alt="mandatory field entered" /></p>
<p>I think in this way it is pretty clear for the user which information is still missing...</p>
<p>Here is the 'getElementsByClassName' function borrowed from <a target="_blank" href="http://www.dustindiaz.com/getelementsbyclass" title="link to the source">this site</a>:</p>
<p>function getElementsByClassName(node,tag,searchClass) {<br />
 var classElements = new Array();<br />
 if ( node == null )<br />
  node = document;<br />
 if ( tag == null )<br />
  tag = '*';<br />
 var els = node.getElementsByTagName(tag);<br />
 var elsLen = els.length;<br />
 var pattern = new RegExp("(^&#124;\\s)"+searchClass+"(<a href="///s&#124;$">\\s&#124;$</a>)");<br />
 for (i = 0, j = 0; i &#60; elsLen; i++) {<br />
  if ( pattern.test(els[i].className) ) {<br />
   classElements[j] = els[i];<br />
   j++;<br />
  }<br />
 }<br />
 return classElements;<br />
}</p>
<p>Ps. for some nice JS onFocus effect like this:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/onfocus.jpg" alt="on focus effect" /></p>
<p>You could add something like this:</p>
<p><img src="http://quintessens.wordpress.com/files/2007/08/onfocuscode.jpg" alt="on focus JS code" /></p>
<p>Don't forget to reset coloring on the onBlur event ;-)</p>
]]></content:encoded>
</item>

</channel>
</rss>
