OpenNTF.org - EnhancedItem class with valida
My Links (Not logged in)
Code Bin Search
 
Hosted by Prominic.NET
Rate This Code
5 - brilliant stuff
4 - very nice
3 - average
2 - needs work
1 - bad
   OpenNTF Code Bin
About This Code
Brief Description:
EnhancedItem class with validation . . . 
Rating:
Not Rated Yet 
Contributor:
Dallas Gimpel 
Category:
Lotusscript 
Type:
Miscellaneous 
Notes Version:
R6.x, R7.x 
Last Modified:
30 Jan 2007 
OpenNTF Disclaimer

All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.

Code / Description

'// These three constants are for use with the EnhancedItem class below.
Public Const DTYPE_TEXT = 1
Public Const DTYPE_NMBR = 2
Public Const DTYPE_DATE = 3

Public Class EnhancedItem
'// AUTHOR:
'// Dallas Gimpel
'//
'// DATE OF CREATION:
'// 04/01/2002
'//
'// DESCRIPTION:
'// This is sort of a wrapper class for the NotesItem class with a few tweaks. It was
'// written mostly for reading data as opposed to writing it. It allows a way of
'// packaging a field together with its values, a text form of its values, a specified
'// minimum, a specified maximum, and a label. The most useful functionality is
'// that of the Validate method which allows standard validation to be applied to
'// required fields for any of the three defined datatypes.
'//
'// NOTE:
'// This class has no error handling - errors are effectively "thrown"

Private docSrc As NotesDocument
Private varValues As Variant
Private varMin As Variant
Private varMax As Variant
Private intDataType As Integer
Private strName As String
Private strLabel As String
Private strTextValue As String

'+++ CONSTRUCTOR +++
Public Sub New(pdocSrc As NotesDocument, pvarValues As Variant, pintDType As Integer, pvarMin As Variant, pvarMax As Variant, pstrName As String, pstrLabel As String, pstrTxtVal As String)
Set Me.docSrc = pdocSrc
Me.strName$ = pstrName$
Me.strLabel$ = pstrLabel$
Call Me.SetDataType(pintDType%)
Me.varMin = Null
Me.varMax = Null

If Len(pstrTxtVal$) = 0 Then
Me.strTextValue$ = Me.DEFAULT_TEXT_VALUE
Else
Me.strTextValue$ = pstrTxtVal$
End If

If Isarray(pvarValues) Then
Me.varValues = pvarValues
Else
Me.varValues = pdocSrc.GetItemValue(pstrName$)
End If

'// if we get numeric or date values for min & max, use them
Select Case True
Case Isnumeric(pvarMin)
Me.varMin = Val(pvarMin)
Case Isdate(pvarMin)
Me.varMin = Cdat(pvarMin)
End Select

Select Case True
Case Isnumeric(pvarMax)
Me.varMax = pvarMax
Case Isdate(pvarMax)
Me.varMax = Cdat(pvarMax)
End Select
End Sub

'+++ DESTRUCTOR +++
Public Sub Delete()
Set Me.docSrc = Nothing
Me.varValues = Null
End Sub

'+++ PUBLIC PROPERTIES +++
Public Property Get CLASS_NAME As String
CLASS_NAME$ = {"} & Typename(Me) & {" class}
End Property

Public Property Get DATATYPE_TEXT As Integer
DATATYPE_TEXT% = DTYPE_TEXT
End Property

Public Property Get DATATYPE_NUMERIC As Integer
DATATYPE_NUMERIC% = DTYPE_NMBR
End Property

Public Property Get DATATYPE_DATE As Integer
DATATYPE_DATE% = DTYPE_DATE
End Property

Public Property Get UNKNOWN_DATATYPE As Integer
UNKNOWN_DATATYPE% = 7501
End Property

Public Property Get DEFAULT_TEXT_VALUE As String
DEFAULT_TEXT_VALUE$ = "{No Value}"
End Property

Public Property Get SourceDocument As NotesDocument
Set SourceDocument = Me.docSrc
End Property

Public Property Get GetValues As Variant
Dim varTmp(0) As Variant
If Isempty(Me.varValues) Then
If Me.docSrc Is Nothing Then
Me.varValues = varTmp
Else
If Me.strName$ = "" Then
Me.varValues = varTmp
Else
Me.varValues = Me.docSrc.GetItemValue(Me.strName$)
End If
End If
End If
GetValues = Me.varValues
End Property

Public Property Get GetDataType As Integer
GetDataType% = Me.intDataType%
End Property

Public Property Get GetMin As Variant
GetMin = Me.varMin
End Property

Public Property Get GetMax As Variant
GetMax = Me.varMax
End Property

Public Property Get GetName As String
GetName$ = Me.strName$
End Property

Public Property Get GetLabel As String
GetLabel$ = Me.strLabel$
End Property

'+++ PRIVATE METHODS +++
Private Sub joinValues(pstrDelimiter As String)
Me.strTextValue$ = ""
Forall valu In Me.varValues
Me.strTextValue$ = Me.strTextValue$ & valu & pstrDelimiter$
End Forall
Me.strTextValue$ = Left$(Me.strTextValue$, Len(Me.strTextValue$) - Len(pstrDelimiter$))
End Sub

'+++ PUBLIC METHODS +++
Public Function GetTextValue() As String
Const ERR_TYPE_MISMATCH = 13
Const DELIMITER = "; "
Dim intErrCount As Integer
On Error ERR_TYPE_MISMATCH Goto catchTypeMismatch

If Strcompare(Me.strTextValue$, Me.DEFAULT_TEXT_VALUE, 5) = 0 Then
Me.strTextValue$ = ""
If Isarray(Me.GetValues) Then
Me.strTextValue$ = Join(Me.varValues, DELIMITER)
End If
End If
functionExit:
GetTextValue$ = Me.strTextValue$
Exit Function

catchTypeMismatch:
If intErrCount% > 0 Then
Error Err, Error$ '// throw the 2nd error (just a precaution to prevent an infinite loop)
End If
intErrCount% = intErrCount% + 1
Call Me.joinValues(DELIMITER) '// this is about as close as I could come to a try/catch
Resume functionExit
End Function

Public Function AppendValue(pvarNewVal As Variant) As Variant
'// DESCRIPTION:
'// This method allows values to be appended to the item's values. Note, however, that
'// the value is NOT written to the source document.

AppendValue = Arrayappend(Me.GetValues, pvarNewVal)
Me.varValues = AppendValue
End Function

Public Function SetDataType(pintNewDataType As Integer) As Boolean
Select Case pintNewDataType%
Case Me.DATATYPE_TEXT, Me.DATATYPE_NUMERIC, Me.DATATYPE_DATE
SetDataType = True
Me.intDataType% = pintNewDataType%
Case Else
Error Me.UNKNOWN_DATATYPE, "An undefined new datatype (" & pintNewDataType% & ") was encountered"
End Select
End Function

Public Function Validate(pstrMsgOut As String) As Boolean
'// DESCRIPTION:
'// This method applies generic validation to the EnhancedItem's values based on the
'// attributes of this instance of the class (provided to the constructor).

Const DATE_FORMAT = "mm/dd/yyyy"
Const NL = {
}

Validate = False
'// Attempt to ensure that we have an array in the varValues variable - get one as necessary.
If Not(Isarray(Me.varValues)) Then
If Me.docSrc Is Nothing Then '// can't validate field because we have no values & no document
pstrMsgOut$ = pstrMsgOut$ & NL & "Unable to validate field " & Me.strName$
Goto functionExit
End If
Me.varValues = Me.docSrc.GetItemValue(Me.strName$)
End If

'// Determine the datatype and apply generic validation.
Select Case Me.intDataType%
Case Me.DATATYPE_DATE
If Not(Isarray(Me.varValues)) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must contain a valid date}
Goto functionExit
End If

Forall dateVal In Me.varValues
Select Case True
Case Not(Isdate(dateVal))
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" contains an invalid date}
Goto functionExit
Case Isdate(Me.varMin)
If Cdat(dateVal) < Me.varMin Then
If Isdate(Me.varMax) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" may only contain dates falling between } & Format(Me.varMin, DATE_FORMAT) & " and " & Format(Me.varMax, DATE_FORMAT)
Else
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" may only contain dates falling on or after } & Format(Me.varMin, DATE_FORMAT)
End If
Goto functionExit
End If
Case Isdate(Me.varMax) '// here, varMin has already been determined to be a non-date so no need to check again
If Cdat(dateVal) > Me.varMax Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" may not contain dates falling after } & Format(Me.varMax, DATE_FORMAT)
Goto functionExit
End If
End Select
End Forall
Case Me.DATATYPE_NUMERIC
If Not(Isarray(Me.varValues)) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" is a required numeric field - it cannot be empty}
Goto functionExit
End If

Forall num In Me.varValues
Select Case True
Case Isempty(num), Isnull(num), Len(Trim$(num)) = 0
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" is a required numeric field - it cannot be empty}
Goto functionExit
Case Not(Isnumeric(num))
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" contains non-numeric character(s)}
Goto functionExit
Case Isnumeric(Me.varMin)
If Val(num) < Me.varMin Then
If Isnumeric(Me.varMax) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must be a number between } & Me.varMin & " and " & Me.varMax
Else
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must be greater than or equal to } & Me.varMin
End If
Goto functionExit
Elseif Isnumeric(Me.varMax) Then
If Val(num) > Me.varMax Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must be a number between } & Me.varMin & " and " & Me.varMax
Goto functionExit
End If
End If
Case Isnumeric(Me.varMax) '// here, varMin has already been determined to be a non-numeric so no need to check again
If Val(num) > Me.varMax Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must be less than or equal to } & Me.varMax
Goto functionExit
End If
End Select
End Forall
Case Me.DATATYPE_TEXT
If Len(Me.GetTextValue()) = 0 Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" is a required text field - it cannot be empty}
Goto functionExit
End If

If Isnumeric(Me.varMax) Then
If Len(Me.GetTextValue()) > Me.varMax Then
If Isnumeric(Me.varMin) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must contain between } & Me.varMin & " and " & Me.varMax & " characters"
Else
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" exceeds the maximum number of characters (} & Me.varMax & ") for the field"
End If
Goto functionExit
End If
Elseif Isnumeric(Me.varMin) Then
If Len(Me.GetTextValue()) < Me.varMin Then
If Isnumeric(Me.varMax) Then
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" must contain between } & Me.varMin & " and " & Me.varMax & " characters"
Else
pstrMsgOut$ = pstrMsgOut$ & NL & {Field labeled "} & Me.strLabel$ & {" requires a minimum of } & Me.varMax & " characters for the field"
End If
Goto functionExit
End If
End If
Case Else '// treat as an error
Error Me.UNKNOWN_DATATYPE, "Validation failed - an undefined internal field datatype (" & Me.intDataType% & ") was encountered"
End Select

Validate = True
functionExit:
Exit Function
End Function
End Class

Usage / Example
This is sort of a wrapper class for the NotesItem class with a few tweaks I needed for the purposes of a project a few years ago. It was written mostly for reading data as opposed to writing it. It allows a way of packaging a field together with its values, a text form of its values, a minimum & maximum, and a label. The nicest feature, however, is the standard validation logic that can be applied to a given field. I have found it very easy to use this class with a list or array when I want to validate a set of required fields. See sample usage below.

Public Properties:
CLASS_NAME
    Return value: String constant, name of this class (mostly for use in error handling).

DATATYPE_TEXT
    Return value: Integer constant, indicates a datatype of text (string).

DATATYPE_NUMERIC
    Return value: Integer constant, indicates a datatype of numeric.

DATATYPE_DATE
    Return value: Integer constant, indicates a datatype of datetime.

UNKNOWN_DATATYPE
    Return value: Integer constant, error number used to indicate an unknown datatype.

DEFAULT_TEXT_VALUE
    Return value: String, default value used for initializing class.

SourceDocument
    Return value: NotesDocument, a handle to the underlying source document.

GetValues
    Return value: Variant array, a snapshot of the values of the field specified.

GetDataType
    Return value: Integer, the datatype that has been specified for the current instance of the class.

GetMin
    Return value: Variant, the minimum value for the current instance. For a datatype of:
    • DATATYPE_TEXT, this specifies a minimum length of each value
    • DATATYPE_NUMERIC, this specifies a minimum numeric value for each value
    • DATATYPE_DATE, this specifies a minimum date value for each value

GetMax
    Return value: Variant, the maximum value for the current instance of the class. For a datatype of:
    • DATATYPE_TEXT, this specifies a maximum length of each value
    • DATATYPE_NUMERIC, this specifies a maximum numeric value for each value
    • DATATYPE_DATE , this specifies a maximum date value for each value

GetName
    Return value: String, the underlying field name from which to obtain values for the current instance.

GetLabel
    Return value: String, the field label by which the field name is to be referred to for this instance.

Constructor:
New(pdocSrc As NotesDocument, pvarValues As Variant, pintDType As Integer, pvarMin As Variant, pvarMax As Variant, pstrName As String, pstrLabel As String, pstrTxtVal As String)
    Description: class contructor
      Parameters:
        pdocSrc - NotesDocument, source document from which to obtain values for the current instance
        pvarValues - Variant, values for the current instance (specifiy Null to force them to be set in the class)
        pintDType - Integer, one of the three defined datatypes
        pvarMin - Variant, minimum for the current instance (specify an empty string for none)
        pvarMax - Variant, maximum for the current instance (specify an empty string for none)
        pstrName - String, field name from which to obtain values
        pstrLabel - String, label by which the current instance is to be referred
        pstrTxtVal - String, a text version of the values to be used in the current instance
Note:
    A minimum can be specified without a maximum and a maximum can be specified without a minimum.

Public Methods:
Sub Delete()
    Description: class destructor, executes by default when a given instance of the class is dereferenced
      Parameters:
        none

Function GetTextValue() As String
    Description: returns a string constructed by concatenating the values for the current instance
      Parameters:
        none
      Return:
        String, concatenated values for the current instance

Function AppendValue(pvarNewVal As Variant) As Variant
    Description:
      Parameters:
        pvarNewVal - Variant, value to be appended to the current values (not written to the source document)
      Return:
        Variant array, an in-memory (temporary) version of the current values including the newly appended value

Function SetDataType(pintNewDataType As Integer) As Boolean
    Description:
      Parameters:
        pintNewDataType - Integer, new dataype to be used
      Return:
        Boolean - true if the datatype is one of the three supported, otherwise false

Function Validate(pstrMsgOut As String) As Boolean
    Description: applies generic validation based on the datatype and the way the current instance was constructed
      Parameters:
        pstrMsgOut - String, receives the validation failure message in the event that validation fails
      Return:
        Boolean - true if validation succeeds, otherwise false
Private Methods:
Sub joinValues(pstrDelimiter As String)
    Description: Attempts to concatenate the values for the current instance using the delimiter specified. Only called when "join" fails.
      Parameters:
        pstrDelimiter - String, the delimiter to be used for concatenation
Sample usage:
    Dim docSrc As NotesDocument
    Dim blnIsDocValid As Boolean
    Dim strMsgTxt As String
    Dim eiFldsLst(0 to 2) As EnhancedItem

    'set NotesDocument, etc . . .

    set eiFldsLst(0) = New EnhancedItem(docSrc, Null, DTYPE_DATE, "", "", "OrderDate", "Order Date", "")
    set eiFldsLst(1) = New EnhancedItem(docSrc, Null, DTYPE_TEXT, "", "", "Name", "Ordered By", "")
    set eiFldsLst(2) = New EnhancedItem(docSrc, Null, DTYPE_NMBR, 1, 5, "Quantity", "Order Quantity", "")

    Forall f In eiFldsLst
      If Not(f Is Nothing) Then '// apply generic validation for all fields
        If Not(f.Validate(strMsgTxt$)) Then
          blnIsDocValid = False
        End If
      End if
    End Forall

    If Not(blnIsDocValid) Then
      '// disallow document save, etc,
      Msgbox "Document may not be saved: " & strMsgTxt$, , "Document may not be saved . . ."
    End If
 Comments
Posted by Joe Jester on 01/30/2007 04:00:10 PMum.... incomplete?
the code is not here
Posted by Dallas Gimpel on 01/30/2007 05:50:04 PMRe: um.... incomplete?
It's there now - dgg.
 Add your comment!