Validating a Notes formula from LotusScript

View member feedback to this tip.

This code can be used to validate a Notes formula before using it in an Evaluate() statement or in a call to db.Search(). It will also tell you the offset of any error. I use it in a Web interface to create customized reports to mimic Domino Designer's "Check formula" functionality. It uses functions in the Notes DLL, as documented in the Lotus C API, example code support Win32 (look here for help on using the same code on another platform).

Here's an example:

Dim sFormula as String

sFormula = {SELECT FORM = 
"MyForm" & @IsAvailable(Status_T)}

iRC = 
if iRC(0) = NO_ERROR Then
     Print "Formula is valid!"
     Print "Formula error: " & 
     Print "Error starts at character: " 
& Cstr(iRC(1)) & " and ends at 
character: " & Cstr(iRC(2))
End If

Removing the "@" from the @IsAvailable keyword should give you those results:

Formula error: @Function or operator expected, or @Function does not require an argument. Error starts at character 47 and ends at character 47, which is the last parentheses.

Const NO_ERROR = 0
= &h500 + 1

Declare Function NSFFormulaCompile 
Lib "nnotes.dll" ( _
Byval FormulaName As Long, _
Byval FormulaNameLength As Integer, _
Byval FormulaText As Lmbcs String, _
Byval FormulaTextLength As Integer, _
rethFormula As Long, _
retFormulaLength As Integer, _
retCompileError As Integer, _
retCompileErrorLine As Integer, _
retCompileErrorColumn As Integer, _
retCompileErrorOffset As Integer, _
retCompileErrorLength As Integer _
) As Integer

Declare Sub OSMemFree Lib "nnotes.dll" 
(Byval hHandle As Long)

Declare Function OSLoadString Lib 
"nnotes.dll" ( _
Byval hmodule As Long, _
Byval status As Integer, _
Byval s As String, _
Byval slen As Integer _
) As Integer

' =============================
' CheckSelectionFormulaValid - 
This function uses the Lotus 
C API to check the
syntax of a Notes formula.
' Return Value: Variant - A 3 elements
 array containing:
' Index 0 - The compilation error code 
or NO_ERROR (0) if valid
' Index 1 - The compilation error offset 
in formula or NO_ERROR if valid 
' Index 2 - The compilation error length 
or NO_ERROR if valid
' Note: The compilation error code at 
Index 0 can then be passed to GetAPIError
() to get more info about the error.
' =============================
Function CheckSelectionFormulaValid
(sFormula) As Variant
 Dim iError As Integer
 Dim hFormula As Long
 Dim wFormulaLen As Integer
 Dim iCompileError As Integer
 Dim iCompileErrorLine As Integer
 Dim iCompileErrorColumn As Integer
 Dim iCompileErrorOffset As Integer
 Dim iCompileErrorLength As Integer
 Dim iArray(2) As Integer
 iError = NSFFormulaCompile(0, 0, _
 sFormula, _
 Len(sFormula), _
 hFormula, _
 wFormulaLen, _
 iCompileError, _
 iCompileErrorLine, _
 iCompileErrorColumn, _
 iCompileErrorOffset, _
 If hFormula <> NULLHANDLE Then
  Call OSMemFree(hFormula)
 End If
  iArray(0) = iCompileError
  iArray(1) = iCompileErrorOffset
  iArray(2) = iCompileErrorLength
  CheckSelectionFormulaValid = iArray
  iArray(0) = NO_ERROR
  iArray(1) = NO_ERROR
  iArray(2) = NO_ERROR
  CheckSelectionFormulaValid = iArray
 End If
End Function
' ===============================
' GetAPIError - This function uses the 
Lotus C API to return a Notes error's
text message.
' Return Value: String - The text associated 
with the Notes API error code.
' ================================
Function GetAPIError(iErrorCode As Integer) 
As String
 Dim iRetVal As Integer
 Dim sError As String * 1024
 sError = String(1024, 0)
 iRetVal = OSLoadString(0&, iErrorCode,
 sError, 1023)
 If iRetval <> 0 Then
  GetApiError = Left$(sError, iRetVal)
 End If

End Function


I think this is a great tip! The writer suggested using it prior to any Evaluate() call. I suggest using it to debug any @Formulas you are working with during routine development.

I created a simple form that I put in my utilities database and will use it all the time. The form has one field and one action button. Put something like this in the button:

Sub Click( Source As Button )
 Dim ws As New NotesUIWorkspace
 Dim uiDoc As NotesUIDocument
 Set uiDoc = ws.CurrentDocument
 iRC = CheckSelectionFormulaValid
( uiDoc.FieldGetText("testFormula" ) )
 If iRC(0) = NO_ERROR Then
  Msgbox "Formula is valid!"
  Print "Formula error: " & 
  Print "Error starts at character: " & 
Cstr(iRC(1)) & " and ends at character: " 
& Cstr(iRC(2))
  Msgbox "Error starts at character: " & 
Cstr(iRC(1)) & " and ends at character: " 
& Cstr(iRC(2)), , _
  "Formula error: " & GetAPIError(iRC(0))
 End If
End Sub

You may also want to check out another tip, called Formula debugger. It's very similar to the tip listed above.

—Doug J.

Do you have comments on this tip? Let us know.

This tip was submitted to the SearchDomino.com tip exchange by member Christian Cloutier. Please let others know how useful it is via the rating scale below. Do you have a useful Notes/Domino tip or code to share? Submit it to our monthly tip contest and you could win a prize and a spot in our Hall of Fame.

This was first published in July 2004

There are Comments. Add yours.

TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.