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
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.
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.
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"))
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 #" & Cstr(Erl) & ": " & 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 < 0) Then Exit Function
If (Cstr(newv) = "") Then Exit Function
fV = Ubound(f.Values)
If (v > fV) Then Exit Function
Dim newf () As Variant
Redim newf (fV)
For i% = 0 To fV
If (i% <> v) Then
ewf(i%) = f.Values(i%)
Else
newf(i%) = newv
End If
Next
UpdateValue = newf
Exit Function
ThatIsNotARealRobotMove:
Msgbox "UpdateValue line #" & Cstr(Erl) & ": " & 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 < 0) Then Exit Function
fV = Ubound(f.Values)
If (v > fV) Then Exit Function
Dim newf () As Variant
Redim newf (fV - 1)
j% = 0
For i% = 0 To fV
If (i% <> v) Then
newf(j%) = f.Values(i%)
j% = j% + 1
End If
Next
RemoveValue = newf
Exit Function
ThatIsNotARealRobotMove:
Msgbox "RemoveValue line #" & Cstr(Erl) & ": " & 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
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.
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