Is there a way to detect which fields are being changed from a Business Rule?

Patrick Schult2
Giga Guru

The short story is - I have a need to know which fields are changing in the "current" object that's available in a Business Rule. I've seen a post on ServiceNowGuru about this but it involves J2JS, which isn't available in non-global application scopes.

If it helps, the use case is basically that there needs to be a separate change log of things that have happened to the record, and I don't want to hard code a list of fields to check for changes when this Business Rule runs.

1 ACCEPTED SOLUTION

Don't actually think you need to go get the fields, since they already is in the current/previous objects.



Something like this should work:



(function executeRule(current, previous /*null when async*/) {


  for (var x in current){


  if (current[x] != previous[x]) {


  gs.addInfoMessage ('Field ' + x + ' has changed!' );


  }


  }


})(current, previous);



//Göran


View solution in original post

8 REPLIES 8

Hi Göran,



Wonderful solution! Only two lines... I'm impressed!


I can't do Endorsements, but this one deserve it.


This is a great solution! I can loop through all these fields in current, check them for changes, and write them out to my log very easily. Thanks!


Yep, more elegant solution than mine...



"The best line of code is the one you don't have to code!"


Thanks Shiva - that works great. I was really hoping there was a package like GlideRecordUtil (but for scoped apps) that would just spit out which fields were changing.



In my case, I didn't want to watch for changes on all fields, but rather a specific, known set of fields. To accomplish this, I created a new Dictionary attribute (sys_schema_attribute) record that I then attached to my fields. In this way, I don't have to hard code the list of fields I care about, I can change them on the fly from the dictionary.



// There is a custom dictoinary attribute for noting which fields in this table should create log entries when changed. Query for fields with that attribute.


var fieldsToAudit = [];


var fieldsGR = new GlideRecord('sys_dictionary');


fieldsGR.addQuery('name', current.getTableName()).addCondition('attributes', 'CONTAINS', 'u_create_change_log');


fieldsGR.query();


while (fieldsGR.next()){


        fieldsToAudit.push(fieldsGR.getValue('element'));


}


gs.debug('Fields to audit: ' + fieldsToAudit.toString());



// For every field that has this attribute, check to see if it changed, and if it did, create a log record.


for (i =0; i < fieldsToAudit.length; i++){


        // Create records in the logging table.


        // In order to detect a change in a field, you need to use the GlideElement representation of the field, which we don't have. At this point, all we have is a string field name like "number" or           "use_detail".


        // Fortunately, GlideRecord has a getElement method that will provide you the right object for the specified field name.


        var currentField = current.getElement(fieldName);


        var previousField = previous.getElement(fieldName);


        if (currentField.changes()){


                  gs.debug(fieldName + ' was changed. ');


                            // Create a record in the logging table.


                  } else {


                          gs.debug(fieldName + ' was not changed.');


                  }


}