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
Dirtyflag 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)