Archive for the 'LotusScript' Category

Max and Min

I don’t know which is worse: that I haven’t needed a Max() and Min() function yet, or that there isn’t
one built in to LotusScript. @Formula has them.

Function Max(x As Double, y As Double) As Double
 
	If (x > y) Then
		Max = x
	Else
		Max = y
	End If
 
End Function
 
 
Function Min(x As Double, y As Double) As Double
 
	If (x < y) Then
		Min = x
	Else
		Min = y
	End If
 
End Function

Notes and XML

I have been playing around with NotesDXLImporter and NotesDXLExporter. The code to export documents from a Notes database to XML is less than 50 lines. Importing takes a bit more, but it’s still less than 50 lines. That’s pretty damn slick.

Design Element- Prohibit design refresh or replace

Occassionally we need our clients to upload a copy of their Notes database to us for support. Sometimes we get them and they’ve clicked this pesky “Prohibit design refresh or replace to modify” check box on the design elements. That prevents the changes we’ve made in the templates we send them from taking affect. If it’s just one or two design elements it’s no sweat to unclick that option. But one time I got a db with most of the design elements set that way, and I wasn’t going to go through it manually.

On the notes.net sandbox I found a Notes application that would let you pick another Notes database and it would tell you the names of all the design elements in the database. I did some research and found out about the almighty $Flags field, and what it’s contents meant, specifically the P flag. I copied the existing form in the database I got from notes.net and changed it to only display the design elements that have the P flag. That means it only shows you the design elements with the “Prohibit design refresh or replace to modify” option checked. Very cool. Then I made a copy of that and modified the code to uncheck that option. It not only tells you which design elements have the option checked,
but it removes them, too.

You can download the application here.

Popup Select from View

I had a situation where each field had a button next to it that allowed the user to pick a value from a view. The value went into the field. Rather than repeat the code for the button a half dozen times, I wrote a generic function for it.

Function popup(field As String, view As String) As String
	On Error Goto Oops
 
	Dim w As New NotesUIWorkspace
	Dim db As NotesDatabase
 
	popup = ""
	Set db = w.CurrentDatabase.Database
 
 
	title$ = "Select a " & field
	prompt$ = "Please select a " & field
 
	f = w.PickListStrings(PICKLIST_CUSTOM, False, db.Server, db.FilePath, view, title$, prompt$, 1)
	If (Isempty(f)) Then Exit Function
 
	popup = Cstr(f(0))
 
	Exit Function
 
 
Oops:
	Msgbox Error$ & " on line #" & Cstr(Erl)
	Exit Function
 
End Function

And here’s how I used it.

Dim w As New NotesUIWorkspace
Call w.CurrentDocument.FieldSetText("CallerOrgCode", popup("Org Code", "COCNUMV"))

List Field Functions

Here’s the situation. We have sets of fields which represent items. For example, for each task on a form you have a task name, an amount of work effort, whether the work effort is hours or days, and a bunch of people who are assigned to this task. The way we do it here, we have four fields, each one accepts multiple values. So TaskName(3) + WorkEffort(3) + WorkEffortType(3) + Assignees(3) all make up the fourth (count from 0) task on this form. And so on.

Now, the hard part is adding, removing, and updating to these fields. You need to make sure it’s all done correctly because if you screw up one of the lists the whole thing is … well, screwed. The code to handle this appears over and over again throughout an application and we could just have one script library for it. So I wrote one.

Function AddValue(f As NotesItem, v As Variant) As Variant
On Error Goto ThatIsNotARealRobotMove
'v is the value to append to the list
AddValue = ""
 
' some error checking and whatnot
If (f Is Nothing) Then Exit Function
 
AddValue = Arrayappend(f.Values, v)
Exit Function
 
ThatIsNotARealRobotMove:
Msgbox "AddValue line #" &amp; Cstr(Erl) &amp; ": " &amp; Error$
Exit Function
 
End Function
 
Function UpdateValue(f As NotesItem, v As Integer, newv As Variant) As Variant
On Error Goto ThatIsNotARealRobotMove
'v is the INDEX of the value to be updated
'newv is the new value
 
UpdateValue = ""
 
' some error checking and whatnot
If (f Is Nothing) Then Exit Function
If (v &lt; 0) Then Exit Function
If (Cstr(newv) = "") Then Exit Function
fV = Ubound(f.Values)
If (v &gt; fV) Then Exit Function
 
Dim newf () As Variant
Redim newf (fV)
 
For i% = 0 To fV
  If (i% &lt;&gt; v) Then
    ewf(i%) = f.Values(i%)
  Else
    newf(i%) = newv
  End If
Next
 
UpdateValue = newf
 
Exit Function
 
ThatIsNotARealRobotMove:
Msgbox "UpdateValue line #" &amp; Cstr(Erl) &amp; ": " &amp; Error$
Exit Function
 
End Function
 
Function RemoveValue(f As NotesItem, v As Integer) As Variant
On Error Goto ThatIsNotARealRobotMove
'v is the INDEX of the value to be removed
 
RemoveValue = ""
 
' some error checking and whatnot
If (f Is Nothing) Then Exit Function
If (v &lt; 0) Then Exit Function
fV = Ubound(f.Values)
If (v &gt; fV) Then Exit Function
 
Dim newf () As Variant
Redim newf (fV - 1)
j% = 0
For i% = 0 To fV
  If (i% &lt;&gt; v) Then
    newf(j%) = f.Values(i%)
    j% = j% + 1
  End If
Next
 
RemoveValue = newf
 
Exit Function
 
ThatIsNotARealRobotMove:
Msgbox "RemoveValue line #" &amp; Cstr(Erl) &amp; ": " &amp; Error$
Exit Function
 
End Function
 
Function FindIndex(f As NotesItem, v As Variant) As Integer
' will return the index of v in f.Values
 
pos = Arraygetindex(f.Values, v)
If (Isnull(pos)) Then
  FindIndex = -1
Else
  FindIndex = Cint(pos)
End If
 
End Function

Here’s an example of how I used it.

' use a dialog box to gather information
d.Steps1 = AddValue(d.GetFirstItem("Steps1"), popupd.tmpTaskName(0))
d.WorkEffort1 = AddValue(d.GetFirstItem("WorkEffort1"), Cstr(popupd.tmpWE(0)))
d.WorkEffortType1 = AddValue(d.GetFirstItem("WorkEffortType1"), popupd.tmpWET(0))
d.Assignees1 = AddValue(d.GetFirstItem("Assignees1"), assignees$)
' refresh the document

Prohibit design refresh or replace to modify

The problem I had was that a database sent to us by a client had almost every design element marked “Prohibit design refresh or replace to modify.” That meant that applying the new database template for testing wouldn’t work, because all these old design elements would be sitting around screwing things up. Now, you can uncheck that option, but you have to do it manually and that’s tedious. I wanted a way to do it programmatically.

I found out about this tool (Lotus Notes database application) that you could download which would tell you all of the design elements in a database. That got me started. After some more research on (what used to be) notes.net I found out the field that I need to look for to see if that option was check, and what value it would contain if it was checked.

So I modified the free tool. I made a copy of the default example form, and changed it so that instead of showing all of the design elements in a specified database, it would only show those flagged with that “Prohibit” junk.

The next step was to make a copy of that one and change it so that it actually changed the flags so that the design element was no longer marked to “Prohibit” modifications. When that worked, I was pretty excited.

You can download that Lotus Notes Database here, and enjoy it all you want, but I make no promises or guarantees. Use it at your own risk.

LotusScript Progress Bar

Here’s a function I use when I have an agent processing a LOT of documents.

Function progressBar(sofar As Double, total As Double) As String
	' this function returns a string progress bar
 
	percent# = sofar / total
	pint% = Cint(percent# * 100)
 
	pBar$ = "["
	For i% = 0 To 100 Step 10
		If (i% < pint%) Then
			pBar$ = pBar$ & "#"
		Else
			pBar$ = pBar$ & " "
		End If
	Next
	pBar$ = pBar$ & "]"
	pBar$ = pBar$ & " " & Cstr(sofar) & " / " & Cstr(total)
	progressBar = pBar$
 
End Function