Creating records from Multi Row Variable Set - ServiceNow Community
Mark Roethof
Tera Patron
Tera Patron

Hi there,

Ones in a while a Community thread passes by like how to create records out of the Multi-Row Variable Set rows entered? All kinds of solutions are mentioned, huge scripts, business rules applied, scripting in workflows, etcetera. So I thought let's see if we can come up with a lean, understandable and correct solution myself.

Case

For example, from a Record Producer with a Multi-Row Variable Set, one might want to create a record in a custom application, and child records are created based on the Multi-Row Variable Set rows entered. We could simulate this by using out-of-the-box Incident (for the Record Producer) and Incident Task (for the Multi-Row Variable Set).

Multi-Row Variable Set

If we would set up a basic Multi-Row Variable Set, with only a Short description field, after submitting the Record Producer the available Multi-Row Variable Set code would look like:

[ {
    "short_description" : "Test Row 1"
}, 
{
    "short_description" : "Test Row 2"
} ]

Knowing this, the available code is just plain JSON.

Record Producer Script

Within the Record Producer Script field, we could parse the JSON value retrieved. For this example, we named our Multi-Row Variable Set "Incident Task" [incident_task].

The number of rows within the Multi-Row Variable Set:

producer.incident_task.getRowCount()

Knowing this, we could use the getRowCount within a for loop.

Individual fields within the Multi-Row Variable Set could be accessed through:

producer.incident_task.getRow(0).short_description

Translating this all into one script, and creating new records (Incident Tasks) based on the Multi-Row Variable Set rows, we could use basic scripting like:

(function() {

	var rowsInt = producer.incident_task.getRowCount();

	for(var i = 0; i < rowsInt; i++) {
		var grIncident = new GlideRecord('incident_task');
		grIncident.initialize();
		grIncident.setValue('incident', current.getUniqueValue());
		grIncident.setValue('short_description', producer.incident_task.getRow(i).short_description);
		grIncident.insert();
	}

})();


Result

find_real_file.png

---

And that's it actually. Hope you like this. If any questions or remarks, let me know!

👍
If this post helped you in any way, I would appreciate it if you hit bookmark or mark it as helpful.

Interested in more articles, blogs, videos, and Share projects on Multi-Row Variable Set I published?
Multi-Row Variable Set


Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP

---

LinkedIn

Comments
Melissa Berry
Tera Guru

Could this be done using a Catalog item and creating multiple sctasks instead of Incident or a record producer?

Mark Roethof
Tera Patron
Tera Patron

Hi there,

Yes sure. This example uses the script field of the Record Producer. Though you could do the same within a Workflow and using a Run Script utility. Or doing so in a Flow.

Kind regards,
Mark
2020 ServiceNow Community MVP
2020 ServiceNow Developer MVP

---

LinkedIn
Community article list

Peter Xiang
Tera Expert

Hi,

I want to add or delete data to Multi Row Question Answers for a record, but I use row.addrow () and row.deleterow (), which are the related document links.https://docs.servicenow.com/bundle/paris-application-development/page/script/server-scripting/concept/c_ScriptableServiceCatalogVariables.html, do you know how to operate

Meeeshel
Tera Contributor

This is brilliant!! thank you!

 

If I wanted to add new tasks to an existing incident, rather than creating a new incident - how could i do that?

Thank you so much! 

Michelle

Jon M3
Tera Expert

How would you get the row count for a task?

Mark Roethof
Tera Patron
Tera Patron

Hi there,

Not sure what you mean here. Can you explain your question a bit more?

Kind regards,
Mark

Jon M3
Tera Expert

What would the code look like for a MultiRow SC Task?

Jon M3
Tera Expert

Here is what I got - but clearly I am missing something:

 

(function() {

var rowsInt = employee_badge.getRowCount();

for(var i = 0; i < rowsInt; i++) {
var grTask = new GlideRecord('sc_task');
grTask.initialize();
grTask.setValue('sc_req_item', current.getUniqueValue());
grTask.setValue('short_description', employee_badge.getRow(i).employee_name);
grTask.insert();
}

})();

Mark Roethof
Tera Patron
Tera Patron

What is:

employee_badge.getRowCount();

I think it already goes wrong here. Where are you trying to execute this? In a Workflow or Flow for example? Then you could try current.employee_badge.getRowCount(); (assuming employee_badge is the name of your MRVS)

Kind regards,
Mark

Jon M3
Tera Expert

employee badge is the name of the MRVS and this is being run in a script in the workflow.

Mark Roethof
Tera Patron
Tera Patron

Have you tried:
current.variables.employee_badge?

Kind regards,
Mark

Jon M3
Tera Expert

I did but still no tasks were created.

Mark Roethof
Tera Patron
Tera Patron

So if you debug current.variables.employee_badge, what does this provide you?

Kind regards,
Mark

Mark Roethof
Tera Patron
Tera Patron

Just tested, works fine when using current.variables.etc.. Task is also created. Issue though... You are using field sc_req_item on sc_task. This field does not exist, so you've created a task which is floating around now, it has no parent record. Just use field request_item instead.

Kind regards,
Mark

Ina
Giga Guru

Not sure of your use case, and if you still need the record producer. But you would need to change this line. Variable two should be the sys_id of your incident. 

grIncident.setValue('incident', current.getUniqueValue());
Ishwar Lad
Tera Contributor

Exactly was looking for this, thank you.

Inactive_User40
Kilo Contributor

Hi @Mark Roethof,

 

I am trying to achieve same thing, as you mentioned above but not able to create a record. Below is my record producer script, please let me know if I am missing something.

 

createTBD(); // function called
current.state = 1;
current.contact_type='web';
//if current.account != login user company, then case is created for partner
//set partner contact and partner account
var accountId = gs.getUser().getCompanyID();
if (current.account != accountId) {
var account = new GlideRecord("customer_account");
if(account.get(accountId) && account.partner){
current.partner_contact = gs.getUserID();
current.partner = gs.getUser().getCompanyID();
}
}
//clear hidden field value used for record produce display only
producer.HiddenField = "";

if(producer.html_description && producer.html_description != '')
current.comments = '[code]' + producer.html_description + '[/code]';


function createTBD(){ // creating records through MRVS
gs.debug("Inside function");

var rowsInt = producer.tbd_ci_creation.getRowCount();

for(var i = 0; i < rowsInt; i++) {
var gr = new GlideRecord('sn_customerservice_u_cmdb_ci_tbd');
gr.initialize();
gr.setValue('serial_number', producer.gr.getRow(i).serial_number);
gr.insert();
}

}

 

Thanks in advance!

 

Regards,

Sushama C

 

Mark Roethof
Tera Patron
Tera Patron

Can you share the debugging steps you already took? Up to which point your script is working? From which point it's not working anymore? Etc..

If my answer helped you in any way, please then mark it as helpful.

Kind regards,
Mark
2020, 2021 ServiceNow Community MVP
2020, 2021 ServiceNow Developer MVP

---

LinkedIn
Community article, blog, video list

Inactive_User40
Kilo Contributor

Hi Mark,

 

It's not entering in function only giving below error : 

The undefined value has no properties.
Caused by error in sys_ws_operation.4b9f0a8967101200d22b794717415a30.operation_script at line 1

 

Thanks,

Sushama

Mark Roethof
Tera Patron
Tera Patron

My suspicion is, it's this line:

gr.setValue('serial_number', producer.gr.getRow(i).serial_number);

What is producer.gr? Is gr the name of your MRVS? Could be, though not lickely.

Kind regards,
Mark

Inactive_User40
Kilo Contributor

Hi Mark,

 

Thanks for your immediate help 🙂

It was with MRVS name only, I corrected and got solved.

 

Your article really helped me and got to learn new thing 🙂

 

Just small query : can we populate this created record on form under section or copy to List type field.

Thank you very much

RiteshSwarnakar
Giga Guru

In "What it will contain" section of Record Producer:

 

Script:

var count = producer.variable_set_name.getRowCount();
var gr = new GlideRecord('custom_table');

for(var i = 0; i < count; i++) {
gr.initialize();
gr.setValue('table_field1', producer.variable_set_name.getRow(i).variable1);
gr.setValue('table_field2', producer.variable_set_name.getRow(i).variable2);
gr.insert();
}
current.setAbortAction(true);           // to prevent a empty record creation

michaelslabodni
ServiceNow Employee
ServiceNow Employee

The easiest way I've found to do it is through Flow Designer using the Get Catalog Variables action. https://docs.servicenow.com/bundle/rome-servicenow-platform/page/administer/flow-designer/reference/... . 

 

That action allows variable sets to be selected and outputs the data into an array that then allows a repetitive loop to create the records. No scripting is required.

 

The two things to keep in mind are:

 

1) The Flow will be run after the parent record gets created. So keep in mind if you have any logic that depends on the relationships.

2) I've found that the action only works on tables extended from the task table. If you create a new table from scratch you can still get data from multi-row variables, but you'll need to script it.

Rajini2
Kilo Sage

This helped us a lot. Thank you!

JonathanR149250
Tera Contributor

Can this be applied to create ritms?

Version history
Last update:
‎05-31-2020 03:02 AM
Updated by: