Survey about Notes and Domino directions

PSC is doing a community survey about the direction of IBM Notes and Domino. John Head, Director of Enterprise Collaboration at the Chicago-based consulting company PSC Group explains that it's not about gathering data, the (optional) email address collected will only be used to notify about the result.PSC promises to share the full results publically. I am personally looking forward to see the result of the survey. You can take the survey at http://bit.ly/PSCXPagesSurvey.

0 Comments

Lotus Notes at my work threatened by Microsoft bug

  The company I work for is owned by a large multinational corporation, and we are one of the few places not using Outlook/Exchange, but Lotus Notes. We have a substantial investment in custom applications written for the Notes platform, and with the deep integration between applications and email, we want to stay on the platform. However, earlier this year, a threat against Lotus Notes reared it's ugly head. Executives at my company were sent meeting invitations from Outlook by other executives in other companies in the group. Some executives received the invitatiosn fine, and could accept/decline, while other got just a plain text email or even blank email. I was tasked to research this, and it seems to be an issue on the sending side. If the sender have the recipients address in their Outlook contacts, the invitation is sent in one format (rich text), if the recipient is not found, it is sent as MIME. So the mail with the invitation is sent in different format by Exchange, with different MIME types (text/calendar vs. text/plain). It is actually easy to replicate the issue. Send a meeting invitation from Outlook to a Notes user not/never listed in the Outllok contacts. It comes across perfectly: Then add that same address to the Outlook contacts and send another invitation. It comes across as a balnk mail, with only the message disclaimer from Exchange visible: There is an IBM technote about this, but there is no solution listed. IBM simply suggest contacting Microsoft. There is a workaround, but that involves all Outlook users changing the default outgoing mail format from rich text to plain text, or to edit this on each single contact. I even had a couple of users here (who also had Outlook mail accounts) try that. It worked in some cases, but not always. And this is not going to work, thousands of users (or at least several dozen executives) will not make all those changes just to accomodate a small Lotus Notes shop like us... I am continuing to look for a solution, but it has to be one that we can implement on the Domino mail server(s) here. I found a suggestion to add TNEFEnableConversion=1 to notes.ini, I am having my administrator implement that right now, so we will see if that helps. But if that does not fix it, or I can't come up with some way to process the incoming meeting invitations and fix the MIME type, I can see a number of executives working really hard on getting rid of Notes (at least for mail) here. And that will happen soon... So, anyone got any ideas?   Update 08/07/2014: I found out that TNEFEnableConversion=1 was already enabled on our mail server, and had been for several years. It seems to also be related to winmail.dat being attached to incoming Outlook mail. I have opened a support ticket with IBM as well. Update 2 08/07/2014: Within a couple of hours I got the following response from IBM regarding my support ticket (PMR…

7 Comments

Code snippet – DateClass

Here is a small Lotusscript class I wrote some years ago. I use it in a number of other classes where I need to use date functionality of different kind. For example, I have a class that communicates with a FoxPro database, using a COM object. Some of the methods in that class uses XML while other just pass a few arguments to the COM object. The COM object expects the date values to be in ISO 8601 format (yyyy-mm-dd). In addition, sometimes the date comes from a field in a Notes document where they usually are stored in US format (mm/dd/yyyy), sometimes it is the current date. So I decided to create a this class to just make the code cleaner and to avoid having to do the same conversions over and over again. This class can of course be extended with more functionality if you like. I simply put the class in a script library called "Class.Date" and then use that script library in my other classes or agents. Class DateClass Private dt As NotesDateTime Public ErrorMsg As String Public Sub New(value As Variant) Dim datestring As String ' *** Check what data type was passed and take actions. ' *** If value is blank or Nothing, use today's date. Select Case Typename(value) Case "EMPTY" : datestring = Format$(Today(),"Short Date") Case "STRING" : If Fulltrim(value) = "" Then datestring = Format$(Today(),"Short Date") Else datestring = value End If Case "DATE" : datestring = Cstr(value) End Select ' *** Also check that the value is a valid date If Isdate(datestring) = False Then ErrorMsg = "Class.Date:New() - '" & datestring & "' received is not a valid date." Set dt = Nothing Exit Sub End If ErrorMsg = "" Set dt = New NotesDateTime(datestring) End Sub Public Function DateOnly As String ' *** Return date-part only, in format selected by the system DateOnly = dt.DateOnly End Function Public Function DateOnlyISO As String ' *** Return date-part only, in ISO 8601 (big endian) standard format DateOnlyISO = Format$(dt.dateOnly,"yyyy-mm-dd") End Function Public Function DateOnlyUS As String ' *** Return date-part only, in US (middle-endian) format DateOnlyUS = Format$(dt.dateOnly,"mm/dd/yyyy") End Function End Class And this is how I use the class, this is the first few lines of a function in another script library: Public Function GetPolicyData(Byval policynumber As String, Byval lossdate As Variant) As Integer Dim DoL As DateClass Dim result As Integer Set DoL = New DateClass(lossdate) If DoL Is Nothing Then '*** Display message, including error message from DateTime class MsgBox = |Failed to initialize New DateTimeClass with LossDate "| & _ lossdate & |". | & DoL.ErrorMsg Exit Function End If '*** Call COM object with policy number and date of loss in ISO 8601 format result = object.GetPolicyData(policynumber, DOL.DateOnlyISO()) ... There you have it. Easy, isn't it?

0 Comments

Code snippet – Disable agent using external file

Yesterday I was asked to create a way to let us disable agents running on a Domino server in an easy way before the Domino server comes back from a crash. The reason for this request is that for a while we have been having one particular agent crash, taking the whole Domino server down with it. It only happens occasionally, and seems to be related to the document being processed. When the server comes up after a crash like that, a consistence check is done, then the agent manager launches the agent again, causing the server to go down again. I added code to the offending agent, so it would flag the document before processing and un-flag after processing is done. This way, when the agent encounters an already flagged document, it will be skipped as it was processed during a previous crash. For some reason this did not work yesterday morning, when one of those rare corrupted(?) documents was encountered. The logic in the code was faulty, because the document was of a new type, so it was never flagged as being processed. The same document was processed over and over again, taking the server down every time. So I simply created two functions, put them in a global script library where I keep utility functions used in many places, and added 3 lines of code to each agent where I wanted this functionality. The first function is simply to check if a specified file exists. I am using en error handler to catch any error (for example missing directory). Function FileExists(filename As String) As Boolean On Error GoTo errHandler If Dir$(filename)<>"" Then FileExists = True Else FileExists = False End If exitFunction: Exit Function errhandler: FileExists = False Resume exitFunction End Function The second function is the one where I check for the existance of a file named the same as the agent, with an extension of .disabled. If that file does not exist, I check for a file with the extension .enabled. If that file is missing, I simply create a blank file with that name. This way, the first time any agent is executed, the file will be created for us, and I don't have to sit and manually create them all. Function DisableAgent() As Boolean Dim session As New NotesSession Dim agentname As String Dim filename As String agentname = session.CurrentAgent.Name filename = "D:\NotesAgentControlFiles\" + agentname + ".disabled" If FileExists(filename) Then DisableAgent= True Else filename = "D:\NotesAgentControlFiles\" + agentname + ".enabled" If Not FileExists(filename) Then Open filename For Output As #1 Print #1, "" Close #1 Print "Created control file " & filename End If DisableAgent= False End If End Function Finally, in each agent I want to be able to disable like this, I add this code in the beginning: '*** Check if disable-file exists, exit in that case If DisableAgent() Then Exit Sub End If Just a few lines of code, but hopefully it will save someone a few minutes of work. Of course, you…

0 Comments

Code snippet – jQuery

This morning I was working on a web application, and I came up with a pretty neat and simple little solution. So I just wanted to share it, in case anyone else need something similar. I have a webpage with an HTML form. Each input tag has an attribute called notesfield, matching the name of the field in Notes where the value is stored: <div class="col-md-3"> <label>First Name</label> <input class="form-control" type="text" notesfield="FirstName" value="" /> </div> <div class="col-md-2"> <label>Initial</label> <input class="form-control" type="text" notesfield="MiddleInitial" value="" /> </div> <div class="col-md-3"> <label>Last Name</label> <input class="form-control" type="text" notesfield="LastName" value="" /> </div> Then I created a simple function that will call an agent on the Domino server, which will return all the fields on the specified document as JSON. This function is called after the HTML page is fully loaded. function loadNotesFields(docunid) { var notesfieldname = ""; $.ajax({ url: "/database.nsf/ajax_GetNotesFieldFields?OpenAgent", data: {"NotesUNID":docunid}, cache: false }).done(function(data) { $('input[notesfield]').each(function() { notesfieldname = $(this).attr("notesfield"); $(this).val(data[notesfieldname]); }); }); } The function is actually extremely simple, and here you can see the power of jQuery. What I do is to perform an Ajax call to a Domino URL, passing a UNID to the agent to use in the lookup. I set cache to false, to avoid the browser from reusing previously retrieved data (this is a good thing to do if the data retrieved can be suspected to change frequently). The jQuery .ajax() functions returns the JSON in the data object, and when the call is done, the callback function loops through each input element with an attribute of notesfield, reads the value of said attribute and then sets the value of the input element to the corresponding Notes value. The only thing left is to write the agent that will return the JSON. It could look something like this: Dim urldata List As String Sub Initialize Dim session As New NotesSession Dim webform As NotesDocument Dim db As NotesDatabase Dim doc As NotesDocument Dim urlstring As String Dim urlarr As Variant Dim urlvaluename As Variant Dim i As Integer Dim json As String Set webform = session.DocumentContext '*** Remove leading "OpenAgent" from Query_String urlstring = StrRight(webform.Query_String_Decoded(0),"&") '*** Create list of arguments passed to agent urlarr = Split(urlstring,"&") For i = LBound(urlarr) To UBound(urlarr) urlvaluename = Split(urlarr(i),"=") urldata(urlvaluename(0)) = urlvaluename(1) Next Set thisdb = session.CurrentDatabase '*** Create content header for return data Print "content-type: application/json" '*** Get Notes document baed on NotesUIND argument Set doc = db.GetDocumentByUNID(urldata("NotesUNID")) '*** Build JSON for all fields in document except $fields json = "{" + Chr$(13) ForAll item In doc.Items If Left$(item.Name,1)"$" Then json = json + |"| + item.Name + |":"| + item.Text + |",|+ Chr$(13) End If End ForAll '*** Remove trailing comma and line break json = Left$(json,Len(json)-2) json = json + "}" '*** Return JSON Print json End Sub Happy coding!

6 Comments

Happy New Year – My Year in Review

2013 has been a very interesting year for me. It started with a trip to Connect in Orlando that almost did not happen. The company I work at was in a money-saving mode, and denied my request to attend. I had already resigned myself to this and come to terms with the fact that I would be missing Lotusphere for the first time since I stared going in 1997. It was made even harder as I heard several of my friends in the community saying that they feared this would be the last Lotusphere, either for them or for the conference itself, in the shape we knew it. But suddenly out of the blue I was offered a press pass to cover Connect, like I had been doing in the past for a few publications (as well as a blogger, during the now-cancelled blogger attendance program). With the conference fee covered, and with a kind offer from a friend in the community to share his room, I purchased my own airline tickets, requested vacation days at work and headed to Orlando for what I thought might be the last time. Connect 2013 was, despite the name change, better than I expected. It was a great conference, my schedule was full of excellent sessions and I got to meet many of my friends again. There were a few faces missing, but many of the familiar faces and voices were seen and heard during the week. Unfortunately, one voice was silenced forever the Sunday before Lotusphere. Kenneth Kjærbye was killed in a motorcycle accident, during a yearly ride with other attendees and presenters. This of course affected many in the community, but my opinion of IBM increased more than a few notches from hearing how well they responded to the tragedy. This was not the only familiar face in the community that we lost. Rob Wunderlich and Jens Augustiny both passed away, also way too early,  in 2013. You will all be missed. There were also some other emotional farewells at Connect 2013, with long-time attendees being there for the last(?) time. On a more personal level, things changed as well in 2013. I still haven't started working very much with XPages, but with the release of Notes and Domino 9.0 in 2013, it feels like XPages are more solid and ready for prime time. My workplace is still on Notes 8.5.2 Basic client, which limits me to classic Notes development. I use Notes/Domino 9.0 at home, though, and I am very impressed with the stability. I also started on a web application, developed using Bootstrap and jQuery, working with a Domino-based backend. I can't talk too much about this project yet, but it has a lot of potential to help children in need, and I am very happy to be in a position to work on it. I also moved, something that if you know me is a big deal. I don't like to move. I actually loathe moving, which is why I had been living at my apartment for 9 1/2…

2 Comments

Code – Mask text to remove PII

Sometimes you need to remove personal identifiable information (PII) from the data you present in an application or on a web page. In the last couple of weeks this issue popped up twice, including one application which needs to be be HIPAA compliant. One solution is to mask any personal identifiable data so that the recipient can still verify the information, without sending it all in clear. I am sure you all seen this on for example credit card statements, with only the last 4 digits of your credit card number displayed. I wrote a simple  Lotusscript function to do this, and I thought I would share it so others can use it as well. You pass a string to mask, the number of characters to leave un-masked and where the unmasked characters should be displayed ("B" for beginning or "E" for end). MsgBox masktext("TexasSwede",3,"B") This line would display Tex******* MsgBox maskText("1234567890",4,"E") This line would display ******7890 Enjoy!   %REM Function maskText Description: Masks a text with asterisks, leaving the num first or last characters visible. Direction is "B" (beginning) or "E" (end). Created by Karl-Henry Martinsson - texasswede@gmail.com %END REM Function maskText(value As String, num As Integer, direction As string) As String Dim tmp As String Dim i As Integer If Len(value)>num Then If Left$(UCase(direction),1)="B" Then ' Start at the beginning tmp = Left$(value,num) For i = num+1 To Len(value) tmp = tmp + "*" Next Else ' Start at the end tmp = Right$(value,num) For i = Len(value) To num+1 Step -1 tmp = "*" + tmp Next End If Else tmp = value End If maskText = tmp End Function

4 Comments

Late realization…

Today I logged in to IdeaJam (#thanksbruce) and for some reason I decided to look at my own old ideas, something I haven't done in a while. I noticed this post, from december 2010, almost a year before IBM launced the XWork server in October 2011... Perhaps IBM listens sometimes, even if they did not make it free, $1000/year is not a bad price for a powerful server like Domino/XWorks.

0 Comments

Class for Domino Directory lookups

In many of my Notes programs, I need to perform lookups into the Domino Directory (the database formerly known as Name and Address Book or NAB). So my solution was to create a class that handle those lookups for me, and exposes the most common lookups as separate methods. We have a slightly modified version of names.nsf, with a few added fields. One of them is what we call ParallelID, which is the user's ID in a system called (surprise!) Parallel. Since I perform that lookup all the time, I created a separate method for that one called GetParallelID(). Same with manager lookup for a user, I created GetManagerName() for that. The methods you probably will use the most are GetText() and GetValue(). Since I think this class could come in handy for others, here it is. Enjoy! Option Public Option Declare Class NotesAddressBook Private NABdb As NotesDatabase Private server As String Private nabname As String Public silent As Boolean Public Sub New(servername As String) me.silent = false Call LoadNABdb(servername) End Sub Public Function GetNABdoc(personname As String) As NotesDocument Dim NABview As NotesView If NABdb Is Nothing Then Call LoadNABdb("") End If If Not NABdb Is Nothing Then Set NABview = NABdb.GetView("PeopleByFirstname") Set GetNABdoc = NABview.GetDocumentByKey(ShortUserName(personname)) Else Set GetNABdoc = Nothing End If End Function Public Function database() As NotesDatabase If NABdb Is Nothing Then Call LoadNABdb("") End If If Not NABdb Is Nothing Then Set database = NABdb End If End Function Public Function GetValue(personname As String, fieldname As String) As Variant Dim NABdoc As NotesDocument Set NABdoc = GetNABdoc(personname) If NABdoc Is Nothing Then If me.silent = False then Msgbox "No document found for '" & personname & "' in " & nabname & " on " & server & ".",,"NotesAddressBook::GetNABdoc()" End If GetValue = "" Else GetValue = NABdoc.GetItemValue(fieldname) End If End Function Public Function GetText(personname As String, fieldname As String) As String Dim tmp As Variant tmp = GetValue(personname, fieldname) If IsArray(tmp) Then GetText = CStr(tmp(0)) Else GetText = CStr(tmp) End If End Function Public Function GetName(personname As String, fieldname As String) As NotesName Dim tmpValue As String tmpValue = GetText(personname, fieldname) If tmpValue <> "" Then Set GetName = New NotesName(tmpValue) End If End Function Public Function GetNameByParallelID(parallelid As String) As String Dim view As NotesView Dim doc As NotesDocument Dim tmpValue As String Set view = NABdb.GetView("(LookupUserID)") Set doc = view.GetDocumentByKey(parallelid) If doc Is Nothing Then Exit Function End If tmpValue = doc.GetItemValue("FirstName")(0) & " " If doc.GetItemValue("MiddleInitial")(0)<>"" Then tmpValue = tmpValue & doc.GetItemValue("MiddleInitial")(0) & " " End If tmpValue = tmpValue & doc.GetItemValue("LastName")(0) If tmpValue <> "" Then GetNameByParallelID = tmpValue End If End Function Public Function GetCommonName(personname As String, fieldname As String) As String Dim tmpName As NotesName Set tmpName = GetName(personname, fieldname) If Not tmpName Is Nothing Then GetCommonName = tmpName.Common End If End Function Public Function GetManagerName(personname As String) As String GetManagerName = GetCommonName(personname, "Manager") End Function Public Function GetParallelID(personname As String) As String GetParallelID = GetText(personname, "ParallelID") End Function Public…

1 Comment

My IBM Notes project on GitHub

I decided to play around a little, and as an experiment put up one of my Notes projects on the open source repository GitHub. You can see the result here: http://github.com/TexasSwede/Class.MailMerge This is a script library in Lotusscript to create documents based on a source document and a template document. I have blogged about it before, but I added some functionality to it, and thought it would be easier for people to download a complete database.  

0 Comments

jQuery – An Overview

Yesterday my boss asked me about a simple overview/tutorial explaining jQuery, Bootstrap and some other web technologies, and how they work together. I decided to also post the result on my blog, so here is the first part. You may recognize some code from a previous blog entry. jQuery is a currently very popular Javascript framework/library. There are other ones, like Dojo (used by IBM in XPages) and YUI (originally developed by Yahoo), but jQuery is right now at the top when it comes to usage. jQuery contains the plumbing behind the scene, it contains functions to let the different elements on the page talk to each other and interact, for example trigger events on click or change. It also have functions to hide and show elements (either directly or fade in or out). One of the big benefits with jQuery is that many functions are much easier to do than in traditional Javascript. It also addresses browser inconsistency, so you don't have to write different code for Firefox and Internet Explorer. jQuery is Javascript, just packaged in a nice library and simplified. There are also UI components and mobile components, found in jQuery UI and jQuery Mobile. Here are a couple of examples, comparing plain Javascript with jQuery: http://blog.jbstrickler.com/2010/06/vanilla-javascript-vs-jquery/. jQuery ties into the DOM (Document Object model) of the browser/webpage in a very easy-to-use way. The way elements are addressed is identical to how you do it in CSS, using . (dot) for classes and # for individual elements. It is not hard to start with jQuery. You do not even have to host the library on your own server, several companies (including Microsoft and Google) host jQuery (as well as other libraries and frameworks) in what is called a CDN (Content Delivery Network). You simply include a line of code in the head section of your HTML, telling the browser to load jQuery from a specified location, and you are all set: <head> <title>Hello, jQuery</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> </head> Notice that you don't use http: or https: at the start of the URL. This is a trick that makes it work both on a http or a https site. However, if you have the code locally in the file system on your computer (like many do before uploading the html file to a server), you must add http: at the beginning for it to load. Let take a look at our first jQuery example. Below we have a very simple piece of HTML code: <body>     <button id="btnSave">Save</button>     <div id="messageBox"></div> </body> What we want to do is that when the button is clicked, a message should be displayed in the div with ID messageBox. That is done with the following piece of jQuery: $("#btnSave").click( function() { $("#messageBox").html("You clicked the Save button."); }); What this do is to replace everything inside the div with the text/HTML code we specify. The second line is the code to execute when the event specified triggers/fires. You can put triggers on almost any element, and…

1 Comment

IBM Notes/Domino growing in Asia?

Judging from an unscientific survey of postings in the IBM developerWorks forums, and also in the Lotus/Domino related forums on LinkedIn, the adoption of IBM Notes and Domino seems to have increased dramatically in Asia during the last few years. The growth seems to be mainly in India, with China coming in at number two, while Notes jobs in the US seems to be dropping or being stagnant. The indications that they are new or recent adopters are very strong. Many of the questions are very basic in their scope and it is obvious (and sometimes directly admitted) that a number of the posters are new to the Notes/Domino platform. However, as many of the questions relates to older version of Notes/Domino (mostly 6.x and 7.x ), IBM should have a huge opportunity to Notes/Domino 9.0 on that market. It is slightly confusing why all these new adopters are on such old platform, but there might be some logic reason for that... Also, there is a big interest on LinkedIn for certification, there are frequent requests for the answers to the certifications tests, mostly from people located in Asia. It also seems like IBM is pushing Notes harder in the Asian markets, as I even seen IBM employees in that region asking for the test answers.   Note: I am sure this has absolutely nothing to do with US/European companies outsourcing development to those countries...

3 Comments

How to set doctype on Notes forms

When redesigning my website to use Bootstrap, I ran into a problem. The navbar (meny) did not render correctly in Internet Explorer 9, despite looking perfect in Firefox and Internet Explorer 10. There are several discussions about this problem on StackOverflow and other forums, and the solution is simply to add <!DOCTYPE HTML> on the first line of the HTML code. However, IBM Domino automatically adds a different doctype string, and there is no database or form property to change/set the correct value. But there is actually a way, and it is not very complicated. Simply create a computed for display field called $$HTMLFrontMatter. Make it hidden from web browsers, and in it you enter a formula that will give you the desired doctype. I simply put "<!DOCTYPE HTML>" in there, and it worked perfectly. Also make sure "Use Javascript when generating pages" is turned off. This way to modify the HTML generated is documented in the online help. It was added in Domino 8.

2 Comments

Export Notes view to Excel – with multi-value fields

A few days ago, a question was asked on StackOverflow about how to export the content of a Notes view to Excel. The caveat was that some columns contained multiple values, but not on all documents. To solve this, I wrote a Lotusscript class that will export view data as either CSV or as an HTML table, both can then be saved to a file and opened in Excel. I am posting the code below. Enjoy!   %REM Agent View Export Created Mar 27, 2013 by Karl-Henry Martinsson Description: Code to export a specified view as CSV. Copyright (c) 2013 by Karl-Henry Martinsson This code is distributed under the terms of the Apache Licence Version 2. See http://www.apache.org/licenses/LICENSE-2.0.txt %END REM Option Public Option Declare Class RowData Public column List As String Public Sub New() End Sub Public Sub SetColumnHeader(view As NotesView) Dim viewcolumn As NotesViewColumn Dim cnt As Integer ForAll vc In view.Columns Set viewcolumn = vc column(CStr(cnt)) = viewcolumn.Title cnt = cnt + 1 End Forall End Sub Public Sub SetColumnValues(values As Variant) Dim cnt As Integer Dim tmp As String ForAll v In values If IsArray(v) Then ForAll c In v tmp = tmp + c + Chr$(13) End ForAll column(CStr(cnt)) = Left$(tmp,Len(tmp)-1) Else column(CStr(cnt)) = v End If cnt = cnt + 1 End ForAll End Sub End Class Class CSVData Private row List As RowData Private rowcnt As Long %REM Function New Description: Open the view and read view data into a list of RowData objects. %END REM Public Sub New(server As String, database As String, viewname As String) Dim db As NotesDatabase Dim view As NotesView Dim col As NotesViewEntryCollection Dim entry As NotesViewEntry Dim colcnt As Integer Set db = New NotesDatabase(server, database) If db Is Nothing Then MsgBox "Could not open " + database + " on " + server,16,"Error" Exit Sub End If Set view = db.GetView(viewname) If view Is Nothing Then MsgBox "Could not access view " + viewname + ".",16,"Error" Exit Sub End If Set col = view.AllEntries() rowcnt = 0 Set entry = col.GetFirstEntry() Set row("Header") = New RowData() Call row("Header").SetColumnHeader(view) Do Until entry Is Nothing rowcnt = rowcnt + 1 Set row(CStr(rowcnt)) = New RowData() Call row(CStr(rowcnt)).SetColumnValues(entry.ColumnValues) Set entry = col.GetNextEntry(entry) Loop End Sub %REM Function CSVArray Description: Returns a string array of CSV data by row %END REM Public Function CSVArray() As Variant Dim rowarray() As String Dim textrow As String Dim cnt As Long ReDim rowarray(rowcnt) As String ForAll r In row textrow = "" ForAll h In r.column textrow = textrow + |"| + Replace(h,Chr$(13),"\n") + |",| End ForAll rowarray(cnt) = Left$(textrow,Len(textrow)-1) cnt = cnt + 1 End ForAll CSVArray = rowarray End Function %REM Function HTMLArray Description: Returns a string array of HTML data by row %END REM Public Function HTMLArray() As Variant Dim rowarray() As String Dim textrow As String Dim cnt As Long ReDim rowarray(rowcnt) As String ForAll r In row textrow = "" ForAll h In r.column textrow = textrow +…

36 Comments

And I am up and running!

Downloaded the Notes client with Domino Designer and Administrator, installed it on top of the public beta from December in a viritual machine (with 1GB memory). Install went without any problems, and the client starts up fine. All settings and bookmarks were preserved from the beta. It just works.

7 Comments

Notes 9.0 available for download

When I woke up this morning, I could finally start downloading the release of IBM Notes and Domino 9.0 Social Edition. And the filenames is actually (mostly) descriptive! Interesting enough, the Notes/Domino Fix List does not show the product released yet: Perhaps someone need to implement a better workflow solution. I know a good product for that. ;-)

3 Comments

Notes 9.0 – MIA

I thought I would download IBM Notes/Domino 9.0 overnight, but after I logged in to Passport Advantage and went to the downloads, I can see that the files have (supposedly) been uploaded, but they are not available to select. If I expand the previous version, all the files for that version shows up... Hopefully IBM have this sorted out in the morning. Scott?

6 Comments

Track your application changes/updates

A while back I created a little tool for my own use, to keep track of my Notes templates and their version numbers. I also developed a tracking database where we track not only changes to Notes applications, but also other changes to our environment. Things like modifications to Domino Directory and Active Directory, as well as other meta data changes, configuration changes, etc. I decided to merge those two applications, and create one focused on tracking changes in Notes templates/applications. I thought perhaps other developers could use this application, so feel free to download the template. This is what the application looks like: After you download the template, use it to create a new Database. In the new database, open the Applications Settings document and enter the application name (should be "Change Tracking"). Also modify the list of systems, this is where the dropdown box in the actual form get its categories from. The only required is one called "System (IBM/Lotus)", but I also suggest to create one called "System (your company name)". You can see an example of the configuration document below. You can now go ahead and load the list of local Notes templates. This is done in the System/Tools section as well. The next step is to open all templates not containing a version field and update them. Go to the section called "No Version"  and open the view, then open each template and select the correct system and enter the application name. Then create the version field using the Template action menu, where you find the action 'Create VersionField'. Enter your initial version number (major, minor, release and build), then save the template document. Now when you have all your templates updated with version numbers, you can start tracking changes using the "Add New Entry" button. Hopefully the application is fairly self-explanatory. The template is using ODS 51, so you need Notes 8.5 or higher to open it. There is also one known issue that I haven't had time to fix yet. If you have the setting "Auto-increase build when adding entry" to "Yes", you have to close and reopen the template document to see the new entry. If it is set to "No", it shows up immediately. If anyone fixes this, let me know and I will update the template on my side too. Update: I have fixed the issue. It was as easy as removing the line  uidoc.EditMode = False  in the 'Add New Entry' action on the 'Template' form. The download has been updated.  Update 2: I have also modified the template to use DateTime fields in a few places where I used regular text fields. Thanks Kenneth for pointing that out!

6 Comments

End of content

No more pages to load