Working with Field Values Using a Parameterized Name
When writing reusable code, if your object function needs to perform the same operations on different fields, you can parameterize the field name.
Start by defining a function parameter of type String
whose value at runtime
will be the name of a field in the current object. Then, when your code needs to access the
value of the parameterized field, just call
getAttribute(fieldNameParam)
. To assign a new value to that field,
call setAttribute(fieldNameParam,newValue)
. In either case, if
the value of the field name parameter passed in does not match the name of some field in the
current object, a NoDefException
will be thrown to signal an error.
Consider the following example of an object function named
conditionalIncrement()
that increments the value of the number field whose
name is passed in only if the field’s value is less than a maximum value also passed in:
// Object function: void conditionalIncrement(fieldName String, maxValue Long)
// ---------------
def fieldValue = getAttribute(fieldName)
if (fieldValue < maxValue) {
setAttribute(fieldName, fieldValue + 1)
}
The first line defines a fieldValue
variable to store the value of the field
whose name is passed in. If its value is less than maxValue
, then line three
assigns the field a new value that is one greater than its current value. Once you define an
object function like conditionalIncrement()
, then any Groovy scripts on the
same object can invoke it, passing in appropriate argument values. For example, in one script
suppose you need to increment the value of a field named UsageCount
if its
value is less than 500:
// Increment the usage count if it is less than 500
conditionalIncrement('UsageCount', 500)
In another script, imagine you need to increment the value of a
DocumentVersionNumber
field if its value is less than 1000. You can use the
same object function: just pass in different values for the field name and maximum value
parameters:
// Increment the document version number if it is less than 1000
conditionalIncrement('DocumentVersionNumber', 1000)
Of course the getAttribute()
and setAttribute()
functions
can also accept a literal String
value as their first argument, so you could
theoretically write conditional logic like:
// Ensure document is not locked before updating request-for-approval date
// NOTE: more verbose get/setAttribute() approach
if (getAttribute('DocumentStatus') != 'LOCKED') {
setAttribute('RequestForApprovalDate', today())
}
However, in the example above, when the name of the field being evaluated and assigned is not coming from a parameter or local variable, then it is simpler and more readable to write this equivalent code instead:
// Ensure document is not locked before updating request-for-approval date
// NOTE: More terse, elegant direct field name access
if (DocumentStatus != 'LOCKED') {
RequestForApprovalDate = today()
}
When invoked on their own, the getAttribute()
and
setAttribute()
functions operate on the current object. However, anywhere
in your script code where you are working with a business object Row
, you can
also call these functions on that particular row as shown in the following example of an
object function. Notice that it also parameterizes the name of the object passed to the
newView()
function:
// Object function: String getRowDescription(objectName String, displayFieldName String, id Long)
// ---------------
// Create a new view object to work with the business object whose name is
// passed in the objectName parameter
def view = newView(objectName)
// Find the row in that view whose key is given by the value of the id parameter
def rows = view.findByKey(key(id),1)
// If we found exactly one row, return the value of the display field name on
// that row, whose field name is given by the value in the displayFieldName parameter
return rows.size() == 1 ? return rows[0].getAttribute(displayFieldName) : null
With such a function defined, we can invoke it from any script in the object to access the display field value of different objects we might need to work with:
// Get RecordName of the Task object with key 123456
def taskName = getRowDescription('Task','RecordName',123456)
// Get the Name of the Territory object with key 987654
def optyName = getRowDescription('Territory','Name',987654)
If you use the getAttribute()
or setAttribute()
to access
field values on a related object, remember that the first argument must represent the name of
a single field on the object on which you invoke it. For example, the following is not
a correct way to use the setAttribute()
function to set the
Status
field of the parent TroubleTicket
object for an
activity because TroubleTicket?.Status
is not the name of a single field on
the current Activity
object:
// Assume script runs in context of an Activity object (child of TroubleTicket)
// INCORRECT way to set a parent field's value using setAttribute()
setAttribute('TroubleTicket?.Status', 'Open')
Instead, first access the related object and store it in a local variable. Then you can assign a field on the related object as follows:
// Assume script runs in context of an Activity object (child object TroubleTicket)
// First access the parent object
def parentTicket = TroubleTicket
// Then call the setAttribute on that parent object
parentTicket?.setAttribute('Status', 'Open')