Welcome to Forums Sign in | Join | Help | Forums
in Search


Data Object Macro

Last post 12-13-2006 5:00 AM by David Zeidman. 7 replies.
Page 1 of 1 (8 items)
Sort Posts: Previous Next
  • 05-27-2005 12:29 PM

    • Mitchell Gibbs
    • Top 50 Contributor
    • User Since: 2000
    • Posts 127
    • Organization: Advocate Charitable Foundation
    • Products:  The Raiser's Edge, Sphere

    Data Object Macro

    I feel like I need training wheels for RE... I've got the beginnings of a grasp on opening a record and creating a record, but I'm having a devil of a time with using data from the currently opened record. Would it be possible from someone to offer a very brief procedure to help me through the concept of Data Object Macros? I'm thinking of something that, if run from the pulldown macro menu on a constituent record, will popup a message box with the first name of the constituent. If I had that, I just know I could build an empire from that foundation =P Thanks! Mitch Gibbs Director, IS Advocate Charitable Foundation
  • 06-01-2005 8:52 AM In reply to

    • Jeff Montgomery
    • Top 500 Contributor
    • Posts 22
    • Organization: O-matic Software, LLC
    • Products:  Accounting for Nonprofits

    Data Object Macro

    How 'bout this... [trying a new code format here, let's see what happens]. [blue] Public Sub TestMacro(oData As IBBDataObject) [tab] [tab]If UCase$(oData.OBJECTNAME) <> "CRECORD" Then [tab][tab]MsgBox "This macro can only be invoked from a constituent." [tab][tab]Exit Sub [tab]End If [tab] [tab]Dim oConstit As CRecord [tab]Set oConstit = oData [tab]MsgBox "Name = " & oConstit.Fields(RECORDS_fld_FULL_NAME) [tab]Set oConstit = Nothing [tab] End Sub [/blue]
  • 06-01-2005 3:31 PM In reply to

    Data Object Macro

    Jeff Montgomery's example pretty much says it all, but this explanatory text might be useful too. In RE, the "System_Macros" module of the VBA System project contains all the macro procedures that will be displayed on the pulldown menu. Any procedure defined as a Public Sub with a single argument of type IBBDataObject) will be displayed on the pulldown menu. For example: Public Sub ShowFirstName(obj as IBBDataObject) Other procedures, both Sub and Function types, can be defined within the System_Macros module, but will not be shown on RE's pulldown menu. Most RE data objects, CRecord, CGift, CConstitAddress, CFund, CCampaign, etc., implement IBBDataObject. (IBBDataObject is kind of a superset.) When an RE form displays one of these objects, RE does the equivalent of scanning System_Macros for appropriately defined Subs and displays them on the macro list pulldown. I doubt that's really what RE does, but it's what I use for a mental map of the process. When displaying that list of macros, RE does not discern which macros are written for one type of object and which of macros are written for another type of object. So it's necessary to add appropriate code to each macro to validate the kind of object being passed. Nasty looking macro errors are otherwise displayed to the user. Jeff's example shows one way of doing this. Two other code snippets that do the same thing are: if Not (TypeOf obj is CRecord) then MsgBox "Not on constituent, etc." exit sub endif and if TypeName(obj) <> "CRecord" then Msgbox "Not on constituent, etc." exit sub endif After doing the above checks, the IBBDataObject needs to be 'cast' as the appropriate RE Object type. From Jeff's example: Dim oConstit As CRecord Set oConstit = oData MsgBox "Name = " & oConstit.Fields(RECORDS_fld_FULL_NAME) Set oConstit = Nothing If you are familiar with C, oConstit in the above example functions very much like a pointer. (Technically, it's called a reference to an object.) Instead of merely using the assignment operator like regular VBA variables, the Set operator is used. When finished using the new reference, it's good practice to do the 'Set oConstit = Nothing' step. RE technical literature says this has to be done, but VBA should automatically do it when oConstit goes out of scope. For the more advanced student, below is a more complicated example. To give a simple demonstration of the possibilities, this example works from both the Constituent form _and_ from the Gift form. Public Sub demo(obj As IBBDataObject) Dim oConstit As CRecord If TypeOf obj Is CRecord Then Set oConstit = obj ElseIf TypeOf obj Is CGift Then Dim oGift As CGift Set oGift = obj Set oConstit = oGift.Constituent Else MsgBox "This macro can only be invoked from constituent or gift forms." Exit Sub End If MsgBox "Name = " & oConstit.Fields(RECORDS_fld_FULL_NAME) Set oConstit = Nothing End Sub Tom Luongo [Email Removed] 617-852-7350
  • 06-01-2005 3:34 PM In reply to

    Data Object Macro

    That looks awfully ugly. Let's try it one more time! Jeff Montgomery's example pretty much says it all, but this explanatory text might be useful too. In RE, the "System_Macros" module of the VBA System project contains all the macro procedures that will be displayed on the pulldown menu. Any procedure defined as a Public Sub with a single argument of type IBBDataObject) will be displayed on the pulldown menu. For example: Public Sub ShowFirstName(obj as IBBDataObject) Other procedures, both Sub and Function types, can be defined within the System_Macros module, but will not be shown on RE's pulldown menu. Most RE data objects, CRecord, CGift, CConstitAddress, CFund, CCampaign, etc., implement IBBDataObject. (IBBDataObject is kind of a superset.) When an RE form displays one of these objects, RE does the equivalent of scanning System_Macros for appropriately defined Subs and displays them on the macro list pulldown. I doubt that's really what RE does, but it's what I use for a mental map of the process. When displaying that list of macros, RE does not discern which macros are written for one type of object and which of macros are written for another type of object. So it's necessary to add appropriate code to each macro to validate the kind of object being passed. Nasty looking macro errors are otherwise displayed to the user. Jeff's example shows one way of doing this. Two other code snippets that do the same thing are: if Not (TypeOf obj is CRecord) then MsgBox "Not on constituent, etc." exit sub endif and if TypeName(obj) <> "CRecord" then Msgbox "Not on constituent, etc." exit sub endif After doing the above checks, the IBBDataObject needs to be 'cast' as the appropriate RE Object type. From Jeff's example: Dim oConstit As CRecord Set oConstit = oData MsgBox "Name = " & oConstit.Fields(RECORDS_fld_FULL_NAME) Set oConstit = Nothing If you are familiar with C, oConstit in the above example functions very much like a pointer. (Technically, it's called a reference to an object.) Instead of merely using the assignment operator like regular VBA variables, the Set operator is used. When finished using the new reference, it's good practice to do the 'Set oConstit = Nothing' step. RE technical literature says this has to be done, but VBA should automatically do it when oConstit goes out of scope. For the more advanced student, below is a more complicated example. To give a simple demonstration of the possibilities, this example works from both the Constituent form _and_ from the Gift form. Public Sub demo(obj As IBBDataObject) Dim oConstit As CRecord If TypeOf obj Is CRecord Then Set oConstit = obj ElseIf TypeOf obj Is CGift Then Dim oGift As CGift Set oGift = obj Set oConstit = oGift.Constituent Else MsgBox "This macro can only be invoked from constituent or gift forms." Exit Sub End If MsgBox "Name = " & oConstit.Fields(RECORDS_fld_FULL_NAME) Set oConstit = Nothing End Sub Tom Luongo [Email Removed] 617-852-7350
  • 12-12-2006 9:05 PM In reply to

    Data Object Macro

    We're struggling with the same initial question - how can we determine the ID of the currently open constituent? Where is Jeff Montgomery's code example as referred to in this post? Most importantly, Tom wrote: > Any procedure defined as a Public Sub with a single > argument of type IBBDataObject) will be displayed > on the pulldown menu. This doesn't seem to work for us. The only public subs which show up on the Tools -> Run Macro pulldown menu are those with no parameters (which of course then don't have the IBBDataObject to tell us which is the current constituent). What are we doing wrong? David Wanless [Email Removed] and Gary Hay [Email Removed]
  • 12-12-2006 11:12 PM In reply to

    • Peter Falconer
    • Top 500 Contributor
    • Posts 36
    • Organization: Oxfam Australia
    • Products:  The Raiser's Edge

    Data Object Macro

    Hi guys, You're looking at the wrong pulldown menu. Open a constituent record and click the icon second from the right end. This shows a dropdown of all object macros. Because it doesn't differentiate between object types the first thing you have to do id determine what kind of object is being passed to you and cast the obj to the right object type so you can get to all its fields and methods. The sample code below may be of some use Public Sub InvalidCreditCard(oRec As IBBDataObject) On Error GoTo eh If TypeOf oRec Is CRecord Then Dim oConstit As CRecord Set oConstit = oRec frmInvalidCCFollowup.gstrConId = oConstit.Fields(RECORDS_fld_CONSTITUENT_ID) frmInvalidCCFollowup.Show Set oConstit = Nothing Else 'future enhancement - pop the constit search form and allow the user to find a constit MsgBox "I'm sorry. You can't manage an invalid credit card from here." & vbCrLf _ & "Select the macro from the constituent record" End If ex: On Error GoTo 0 Exit Sub eh: MsgBox "Error '" & Err.Description & "' in procedure InvalidCreditCard of Module System_Macros" Resume ex End Sub
  • 12-12-2006 11:26 PM In reply to

    Data Object Macro

    Brilliant. Thanks Peter. That solved the problem. I'm going to suggest to BB that they put a KB article up on this question as it took us a lot of searching to find this out! Thanks, David.
  • 12-13-2006 5:00 AM In reply to

    • David Zeidman
    • Top 25 Contributor
    • User Since: 2002
    • Posts 326
    • Organization: Zeidman Development
    • Products:  Blackbaud Direct Marketing, Blackbaud Enterprise CRM, The Information Edge, The Raiser's Edge

    Data Object Macro

    Just to add some more information to this. In the forthcoming release of 7.81 it will be possible to customize the drop down that shows the macros. You will be able to change the name of the macro so that it doesn't show "System_Macros.mymacro" but says simply "My Macro", so that you can change the icon from the standard one to somethign of your own choosing, and perhaps most importantly, so that you can restrict which objects the macro appears on, i.e. only constituent, gifts, events, or a combination of these, etc. If you need any more information then please do not hesistate to contact me. David Zeidman Development http://www.zeidman.info
    David Zeidman
    Zeidman Development
    http://www.zeidman.info

    Check out my RE API blog
    http://www.re-decoded.com
Page 1 of 1 (8 items)