sabell2012
Mega Sage
Mega Sage

NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.

 

DIFFICULTY LEVEL: INTERMEDIATE
Assumes good knowledge and/or familiarity of Orchestration, Workflows, and Scripting in ServiceNow. Assumes having taken the class SSNF and has good intermediate level of knowledge and/or familiarity with Scripting in ServiceNow. 


I was exploring ways to do looping, and wanted a method similar to a "for" loop in JavaScript. There was simply nothing out-of-the-box in the way of activities that gave me what I wanted, and that would give me the control I was looking for. The Turnstile Activity, while useful, did not allow for a variable to be plugged in for the value, and was in essence hard-coded.  

 

Thinking it through I was able to come up with a relatively straightforward solution. I am providing this lab as an example.

 

So what we will be creating will be something like the following only implemented with Workflow Activities:

 

for (var counter = 0; counter < incidentList.length; counter++) {
    //… do some work
}

 

Warning: You should probably play with this in your personal instance until you get proficient with the concept. Just saying.

 

NOTE: We are going to create all of our activities first and wire them all together as the last step prior to testing.

 

 

Lab 1.1: Implementing a Loop in a Workflow

1. Navigate to Workflow > Workflow Editor. This will open the workflow editor

2. In the Workflow Navigation column click on the "+" symbol to create a new workflow

a. Name: Loop Example

b. Table: Global

c. Description: Method for implementing a For/Next loop with Workflow Activities

d. Take all other defaults

e. Click the Submit button to create the workflow

3. Navigate to Core > Utilities

4. Drag out a Run Script Activity on to the desktop.

 

NOTE: Here we will be initializing our loop. We will load a specified number of records from the Incident table. Store these into a scratchpad variable. The number of times to loop will be the number of records. We will start with 0 as the first number.

 

a. Name: Initialize

b. Script:

 

var identifier = context.name + '.' + activity.name; // introducing just a bit more sophistication!

var incidentRecords = new GlideRecord('incident');
incidentRecords.addQuery('state', '!=', 7); // state of closed
incidentRecords.setLimit(workflow.inputs.u_numberofrecords); // note that this comes from your inputs
incidentRecords.orderByDesc('number');
incidentRecords.query();

var incident = {};
var incidentList = []; // this will be an array of objects
while (incidentRecords.next()) {
    incident = {};
    incident.sys_id = incidentRecords.sys_id + '';
    incident.number = incidentRecords.number + '';
    incident.assigned_to = incidentRecords.assigned_to.getDisplayValue() + '';
    incident.short_description = incidentRecords.short_description + '';
    incident.state = incidentRecords.state.getDisplayValue() + ''; // notice that we get the label
    incidentList.push(incident);
}

workflow.scratchpad.count = incidentList.length; // the overall count available
workflow.scratchpad.incidentList = incidentList; // the list of incident objects
workflow.scratchpad.counter = 0; // our counter
workflow.scratchpad.message = ''; // the cumulative message

gs.info('---> [WF:{1}] Total number of records to loop: {0}', [workflow.scratchpad.count, identifier]);

 

  c. Click the Submit button to create the Activity

 

5. Drag out another Run Script Activity on to the desktop.

 

NOTE: Here we will save up a cumulative message which we will print out each time to the System Log (in the Do Work Script Activity). Note that we are reference the "current" incident record using our object array, and our counter. This is part of the magic!

 

a. Name: Compile Message

b. Script:

 

var incident = workflow.scratchpad.incidentList[workflow.scratchpad.counter];

workflow.scratchpad.message += 
	gs.getMessage('[{0}] Number: {1} - {2} - {3} - {4}\n',
		[workflow.scratchpad.counter,
		incident.number,
		incident.short_description,
		incident.assigned_to,
		incident.state
		]
	);

 

c. Click the Submit button to create the Activity

 

6. Navigate to Core > Timers

7. Drag out a Timer Activity.

 

NOTE: Here we will wait one second so that the logs are written down in order. Otherwise there is no need for this activity.

 

a. Name: Wait a Sec

b. Timer Based On: A user specified duration

c. Duration: 1 seconds

d. Click on the Submit button to create the Activity

 

8. Copy the Wait a Sec Activity (we will need two for our workflow). Rename it to Wait a Sec Too.

9. Navigate to Core > Utilities

10. Drag out another Script Activity on to the desktop.

a. Name: Do Work

b. Script:

 

var identifier = context.name + '.' + activity.name;

gs.info('---> [WF:{2}]\nLoop Count: {0} - Message so far:\n{1}', 
	[workflow.scratchpad.counter, 
	workflow.scratchpad.message, 
	identifier]
);

 

11. Navigate to Core > Conditions

12. Drag out an If Activity on to the desktop.

 

NOTE: Here is where we do the check! The other part of the magic. This is the condition and increment portions of the "for".

 

a. Name: Check Counter

b. Advanced: Checked

c. Script (replace the template comments):

 

answer = ifScript();

function ifScript() {
    var check = 'no';
    workflow.scratchpad.counter++; // increment the counter

    // check the counter and see if we need to go again or stop
    if (workflow.scratchpad.counter < workflow.scratchpad.count) {
        check = 'yes';
    }

    return check;
}

 

 d. Click the Submit button to create the Activity

 

13. Navigate to Core > Utilities

14. Drag out another Run Script Activity on to the desktop.

 

NOTE: Here we will log down the final Message to the System Logs. You could probably put together a scratchpad variable in the previous step and use a Log Message Activity to print it off, but I like this method a bit better. It's just me.

 

a. Name: Log Message

b. Script:

 

var identifier = context.name + '.' + activity.name;
gs.info('---> [WF:{1}]\nFINAL Message:\n{0}', [workflow.scratchpad.message, identifier]);

 

c. Click the Submit button to create the Activity

 

15. Wire everything up to look like the following:

 

sabell2012_0-1703262192763.png

 

16. Click on the triple bar (a.k.a hamburger/tri-lipse) in the upper left of the Desktop, then click on Edit Inputs. We will define a single test input variable for our workflow.

17. Click on the New button to add a new input variable:

a. Type: Integer
b. Label: Number of Records

c. Column Name: u_numberofrecords
d. Default Value: 5

e. Click the Submit button to create the new variable.

18. Close the Workflow Inputs form.

 

So what do we have so far? Everything we need to test the "For" loop concept. So, now let's test!

 

 

Lab 1.2: Testing

1. Now click the Run Workflow button on the top right. The Start Workflow form will appear.

 

19.sub-workflow_run workflow.JPG

 

2. Click the Start button to run the workflow.

3. Accept the default of five loops.

4. The workflow will loop through five times and then exit.

 

sabell2012_1-1703262413016.png

 

5. From your ServiceNow browser tab Navigate to System Logs > All. This will open the System Logs list view.

6. Filter for all messages starting with --->

7. Order by date Created descending. You should see something like the following. There should be five entries showing the counting up from zero to four, then a "FINAL" message should be printed out with all of the entries.

 

sabell2012_2-1703264039052.png

 

Pretty neat, actually, how it works!

 

Enjoy!

Steven Bell.

 

If you find this article helps you, don't forget to log in and mark it as "Helpful"!

 

sabell2012_0-1703110999495.png


Originally published on: 09-27-2015 03:30 PM

I updated the code, fixed broken links, and brought the article into alignment with my new formatting standard.

2 Comments