Custom user defined business rules

The idea of creating user defined business rules has been discussed in various threads at Blackbus and on the Blackbaud Raiser’s Edge forums (see User Defined Business Rules for example). The whole functionality  is really useful but there are clearly limitations.

One really good use of VBA is to perform this very task. For those not familiar with the build in version it allows you to select a query (constituent, gift or action) and for a all or a limited number of security groups it allows you to display a message on opening the record. This same functionality can be repeated using VBA. Of course you are able to query on a lot more, or perform more than simply display a message.

The example below works on all constituent that have given a gift over a certain amount. So far this can easily be done with the built in functionality so let’s spice it up a bit. We should also provide the largest gift they have given in the message and what is more we should do this when they try to save the gift after making a change to it (not when it is being opened) prompting whether they really want to make the change.

Public Sub Constituent_BeforeSave(oRecord As Object, bCancel As Boolean)    
    'oRecord              : record object being saved    
    'bCancel              : set to true to cancel the save operation    

    Dim oConstit As CRecord
    Dim oDataObj As IBBDataObject   
    Dim curAmount As Currency
    Dim oGift As CGift

    On Error GoTo ErrHandler

    Set oConstit = oRecord
    Set oDataObj = oRecord

    If Not oConstit Is Nothing Then

        'Firstly we check to see if the constituent has been changed
        If oDataObj.Dirty Then

            curAmount = 0
    
            'Now we want to search their gifts for large gifts
            For Each oGift In oConstit.Gifts
              
                If oGift.Fields(GIFT_fld_Amount) > curAmount Then
                    curAmount = oGift.Fields(GIFT_fld_Amount)
                End If
       
                oGift.CloseDown
            Next oGift              

            'Now we determine whether to warn the user that this constituent is important
            If curAmount > 1000 Then
                If MsgBox(oConstit.Fields(RECORDS_fld_FULL_NAME) & " is a major donor as they have given " & curAmount & ". Do you really want update the record?", vbYesNo) = vbNo Then

                    bCancel = True
                End If
            End If
        End If
    End If

    Set oConstit = Nothing

    On Error GoTo 0
    Exit Sub

ErrHandler:

    Dim sErr As String
    sErr = Err.Description

    On Error GoTo 0

    '< place your custom error handling code here >

    MsgBox "Error processing Constituent_BeforeSave : " & sErr

    Set oConstit = Nothing
    bCancel = False
    Exit Sub
End Sub

This is quite a trivial example and you would probably want to be a bit more specific than if any change has been made to the constituent. However it does show a few points.

  • We use the Dirty flag to determine whether a record has been changed or not.
  • We have to close down each gift as we go around the loop. (see Close down or crash)
  • We could have take a collection of gifts and a filter object. We would filter on the constituent id and the amount being greater than 1000. This would have avoided looping through all gifts on a record that could slow the process down. (See Filtering on Gifts)