Skip to main content
    Country/region select      Terms of use
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

This technique isn't applicable in all situations, but it's a way to make a date or time-based view whose index is only rebuilt when needed, and doesn't require that the date be hardcoded into a design element. The example is intended for use in the Notes mail file, where there's only one user who we're mainly concerned about. It could be used in a shared app context, but in that case it should be set up to use the server's time settings, not the client's as in this example, since different users would be plugging in different formulas and causing constant rebuilds based on their client's settings as opposed to someone else's.
The problem is how to get the view index to be rebuilt only when it is needed, and without "flashing" (i.e. we don't want to open the view and then notice it's out of date). I've been testing this solution and it seems to work.

In the folder, you define a UDC (user-definable column) whose item name is, say "$ZoneDay":

Image:Another way to make an efficient date/based viewImage:Another way to make an efficient date/based view
We use the profile name ColorProfile because the Inbox already contains another UDC with the same profile, and any given view can only use one profile doc for UDCs.

Now, you have to set up the profile document to contain the correct formula for the date-based value you'd like it to display. For this we can use the view's queryopen event, for instance:

Sub Queryopen(Source As Notesuiview, Continue As Variant)
       Dim db As NotesDatabase, sess As New notessession

       Set db = sess.CurrentDatabase

       Dim docPro As NotesDocument, curFormula$, newFormula$, midnight$, gmtMid

       Dim tmpTime As New NotesDateTime("")

       tmpTime.lslocaltime = Today ' which translates to today at midnight.

       gmtMid = tmpTime.LSGMTTime

       midnight = {@ToTime(@Text(@Date(} & Year(gmtMid) & {; } & Month(gmtMid) & {; } & Day(gmtMid) & {; } & Hour(gmtMid) & {; } & Minute(gmtMid) & {; 0)) + " GMT")}

       Set docPro = db.GetProfileDocument("colorprofile")

       curFormula = Replace(docPro.GetItemValue("$ZoneDay")(0), Chr$(13), "")

       newFormula = {todayMid := } & midnight & {;

daysOld := (todayMid-PostedDate) / 86400;

@If(daysOld <= 0; "today"; daysOld <= 1; "yesterday"; "older " + @Text(@Integer(daysOld)))}

       If curFormula <> newFormula Then

               docPro.ReplaceItemValue "$ZoneDay", newFormula

               docPro.Save True, False, True

       End If

End Sub

Some comments about this approach:
  • On the line beginning "midnight =", we represent the date by using the @Date function with six arguments. This is done rather than just hardcoding the time constant [mm/dd/yyyy hh:mm:ss GMT] for instance, because we have no way to know the server's date formatting settings. The formula has to be comprehensible by the server, but this code executes on the client, so we can't just format the date as the client would by default.
  • If performance ends up being a problem and you want to find a way to format the date so the server understands it, you might:
    • try using the @TimeMerge function.
    • see whether the format [yyyy/mm/dd hh:mm:ss am/pm] is interpreted the same by all servers (note, however, that "/" might not be universally used as a date delimiter).
    • I'm trying to get a way of representing date/times that's static across all platforms and settings, e.g. as a hex code. I need it for DXL, but as we can see here there are other applications for it.
  • When it's asked to open the view, the view indexer is smart enough to know that if the profile document (colorprofile in this case) has been modified since the view was last opened, that means that a column formula might evaluate differently for existing documents. So it knows in that case to rebuild the view index rather than refreshing. So don't save changes to the profile doc unless you mean it.
  • This approach is doesn't require Designer access for the end user, only enough authority to edit a shared profile document, which they need anyway to edit their own mail preferences. In other applications where users might not have enough muscle to do this, you might need to make the profile document contain an explicit Authors field to allow this access. It could get tricky, which is why I say this might not be applicable for all apps.
  • If you wanted to use the server's timezone settings to determine the day divisions, instead of the client's settings, you can get rid of the timezone stuff and just use the @Date function (you still can't hardcode the date in [brackets] without knowing how the server formats dates).
  • There's an extra argument to @Now to return the server's current time, and you can use that to determine what the server thinks the date is. This is not 100% obvious how to do; I think you'll have to use @Text in your Evaluate call with certain arguments, to get the time in the server's zone.

Andre Guirard | 23 May 2011 04:50:14 PM ET | Home, Plymouth, MN, USA | Comments (7)


1) Wait... what!?!
Nathan T. Freeman | 5/23/2011 6:14:09 PM

If you have a UDC profile specified for a view, that profile's QueryOpen event fires when opening the View!??!?!

2) Never mind
Nathan T. Freeman | 5/23/2011 7:12:57 PM

Never mind... didn't realize that was the QO on the view itself.

3) Also...
Nathan T. Freeman | 5/23/2011 7:24:57 PM

I'm guessing you can't sort by that column. Have you tried?

4) Wow
Erik Brooks | 5/23/2011 8:08:40 PM

Man, I've been wondering since I first read about color profiles if you could use them to do exactly this. I never bothered trying since we don't really do any thick client work. Definitely cool, though way, way hacktastic.

5) a few other comments about UDCs and dates
Andre Guirard | 5/24/2011 8:03:37 AM

@Nathan: The column values are a regular part of the view index so yes, you can sort by it. I have a folder in my mail named "1 Month" where I drag everything that, if I don't have to refer back to it in a month, I can delete. So I used this technique to categorize the folder into everything older than 30 days, and everything more recent. The formula is executed just the same as any other column formula; it's just that the view indexer retrieves it from the profile document rather than from the design note.

@Eric: I didn't think it was that kludgy. Also note there's no reason you couldn't apply the same technique in an XPages app. There's not as much need there since you have total control over the column values in XPages, but if you did want to sort or select by that value, the view indexer is probably more efficient than post-processing in Java(Script).

I think it's misleading to call them "color profiles". There's nothing about UDCs with any direct connection to colors; that just happens to be the first application they were used for. You could also do this sort of thing to manage keyword translations in a view, for instance.

6) Hmmm...
Erik Brooks | 5/24/2011 10:46:06 PM

I do think it's a clever approach in-theory, but I'm not a fan at all of relying on UI hooks for updating an index.

If you had any lookups relying on this, the risk for the index not being updated is too high for my tastes. And you'd have to duplicate this code on the backend for any scheduled agents that wanted to access this view, and certain web commands like ?OpenView and ?ReadViewEntries obviously wouldn't cause the index to update...

Even if you extended this to work on the web, since each HTTP thread contains its own cache of profile documents I could see things getting really strange and/or out-of-sync from thread-to-thread.

Either way, and especially if you were doing this on the web/XPages, wouldn't you find it easier to simply run some LS/Java code prior to view launch that simply changes the view's selection formula if-needed? The "traditional" approach? It would be running on the server and therefore use the server's OS settings, but otherwise it'd be pretty straightforward and could be invoked identically via client, web, XPages, etc.

 Add a Comment
Comment:  (No HTML - Links will be converted if prefixed http://)
Remember Me?     Cancel

Search this blog 


    About IBM Privacy Contact