Multi row variable set not displaying properly in Approval Mail Notification

bhupendra paree
Tera Contributor

Hello Folks, 

 

I created a Custom Mail Script for Multi Row Variable Set (MRVS) for approval mail notification and called that mail script just below OOB req-item-variables mail script(See Below)

bhupendraparee_1-1736533669013.png

Doing this , i wanted MRVS data to populate in two different tables on mail. Its showing two tables but with other parameters coming inbetween them (Kindly refer below screenshot)

 

bhupendraparee_0-1736533625322.png

Here table: 2 should come right after table 1 , Why its coming not together am not sure , even though both tables are configured with no Gap in the one script only.

Kindly suggest if you can help on it.

 

3 ACCEPTED SOLUTIONS

Hello Can you Try the below Script 

the issue you're facing, where the two tables are getting separated by other parameters (such as comment and approval activity sections), is likely due to how the content is being printed within your script and how ServiceNow handles the rendering of email templates

 

(function runMailScript(current, template, email, email_action, event) {
var arr2 = arr3 = arr4 = arr1 = arr5 = [];
var gr = new GlideRecord("sc_req_item");
gr.addQuery("cat_item",'57e4a7254rtg9ad08d7bcda036e45a19');
gr.addQuery("sys_id", current.document_id);
gr.query();
if (gr.next()) {
arr2 = gr.variables.destination_machines.destination_machine;
arr3 = gr.variables.destination_machines.computer_name;
arr1 = gr.variables.people_requiring_access.person_requiring_access;
arr4 = gr.variables.people_requiring_access.email_address;
for (var i = 0; i < arr1.length; ++i) {
var gr2 = new GlideRecord("sys_user");
gr2.addQuery('sys_id', (arr1[i]));
gr2.query();
while (gr2.next()) {
var name = gr2.name;
arr5.push(name);
}
}
}

// Print the first table for destination machine data
if (arr2.length > 0) {
template.print("<table border='1'>");
template.print("<tr><th>Destination Machine</th><th>Computer Name</th></tr>");
for (var i = 0; i < arr2.length; ++i) {
template.print("<tr><td>" + arr2[i] + "</td><td>" + arr3[i] + "</td></tr>");
}
template.print("</table>");
}

// Add a line break to prevent the tables from merging visually
template.print("<br>");

// Print the second table for people requiring access data
if (arr1.length > 0) {
template.print("<table border='1'>");
template.print("<tr><th>Person Requiring Access</th><th>Email ID</th></tr>");
for (var i = 0; i < arr1.length; ++i) {
template.print("<tr><td>" + arr5[i] + "</td><td>" + arr4[i] + "</td></tr>");
}
template.print("</table>");
}
})(current, template, email, email_action, event);

--------------------------------------------------------------------------------------------------------------------------


If you found my response helpful, I would greatly appreciate it if you could mark it as "Accepted Solution" and "Helpful."
Your support not only benefits the community but also encourages me to continue assisting. Thank you so much!

Thanks and Regards
Ravi Gaurav | ServiceNow MVP 2025,2024 | ServiceNow Practice Lead | Solution Architect
CGI
M.Tech in Data Science & AI

 YouTube: https://www.youtube.com/@learnservicenowwithravi
 LinkedIn: https://www.linkedin.com/in/ravi-gaurav-a67542aa/

View solution in original post

Hello @bhupendra paree 

Please try this optimized script. 

(function runMailScript(current, template, email, email_action, event) {
    // Arrays to store MRVS data
    var destinationMachines = [];
    var computerNames = [];
    var personSysIds = [];
    var emailAddresses = [];
    var personNames = [];

    // Fetch the record
    var gr = new GlideRecord("sc_req_item");
    gr.addQuery("cat_item", "57e4a7254rtg9ad08d7bcda036e45a19"); // Catalog item sys_id
    gr.addQuery("sys_id", current.document_id);
    gr.query();

    if (gr.next()) {
        // Extract MRVS data
        destinationMachines = gr.variables.destination_machines.destination_machine;
        computerNames = gr.variables.destination_machines.computer_name;
        personSysIds = gr.variables.people_requiring_access.person_requiring_access;
        emailAddresses = gr.variables.people_requiring_access.email_address;

        // Fetch names for person_sys_ids
        if (personSysIds && personSysIds.length > 0) {
            var userGr = new GlideRecord("sys_user");
            userGr.addQuery("sys_id", "IN", personSysIds.join(","));
            userGr.query();
            while (userGr.next()) {
                personNames.push(userGr.name.toString());
            }
        }
    }

    // Generate tables for Destination Machines
    if (destinationMachines && destinationMachines.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr><th>Destination Machine</th><th>Computer Name</th></tr>");
        for (var i = 0; i < destinationMachines.length; i++) {
            template.print("<tr>");
            template.print("<td>" + destinationMachines[i] + "</td>");
            template.print("<td>" + computerNames[i] + "</td>");
            template.print("</tr>");
        }
        template.print("</table>");
    }

    // Generate tables for People Requiring Access
    if (personSysIds && personSysIds.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr><th>Person Requiring Access</th><th>Email Address</th></tr>");
        for (var j = 0; j < personSysIds.length; j++) {
            template.print("<tr>");
            template.print("<td>" + (personNames[j] || "Unknown") + "</td>");
            template.print("<td>" + emailAddresses[j] + "</td>");
            template.print("</tr>");
        }
        template.print("</table>");
    }
})(current, template, email, email_action, event);

Hope this helps!

 

"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"

 

Thank You
Juhi Poddar

View solution in original post

Ankur Bawiskar
Tera Patron
Tera Patron

@bhupendra paree 

try this

(function runMailScript(current, template, email, email_action, event) {
    var arr2 = arr3 = arr4 = arr1 = arr5 = [];
    var gr = new GlideRecord("sc_req_item");
    gr.addQuery("cat_item", '57e4a7254rtg9ad08d7bcda036e45a19');
    gr.addQuery("sys_id", current.document_id);
    gr.query();
    if (gr.next()) {
        arr2 = gr.variables.destination_machines.destination_machine;
        arr3 = gr.variables.destination_machines.computer_name;
        arr1 = gr.variables.people_requiring_access.person_requiring_access;
        arr4 = gr.variables.people_requiring_access.email_address;
        for (var i = 0; i < arr1.length; ++i) {
            var gr2 = new GlideRecord("sys_user");
            gr2.addQuery('sys_id', (arr1[i]));
            gr2.query();
            while (gr2.next()) {
                var name = gr2.name;
                arr5.push(name);
            }
        }
    }

    var table1 = "";
    if (arr2.length > 0) {
        table1 += "<table border='1'>";
        table1 += "<tr>";
        table1 += "<th> Destination Machine </th>";
        table1 += "<th> Computer Name </th>";
        table1 += "</tr>";
        for (i = 0; i < arr2.length; ++i) {
            table1 += "<tr>";
            table1 += "<td>" + arr2[i] + "</td>";
            table1 += "<td>" + arr3[i] + "</td>";
            table1 += "</tr>";
        }
        table1 += "</table>";
    }

    var table2 = "";
    if (arr1.length > 0) {
        table2 += "<table border='1'>";
        table2 += "<tr>";
        table2 += "<th> Person Requiring Access </th>";
        table2 += "<th> Email ID </th>";
        table2 += "</tr>";
        for (i = 0; i < arr1.length; ++i) {
            table2 += "<tr>";
            table2 += "<td>" + arr5[i] + "</td>";
            table2 += "<td>" + arr4[i] + "</td>";
            table2 += "</tr>";
        }
        table2 += "</table>";
    }

    // Print both tables consecutively
    template.print(table1 + table2);
})(current, template, email, email_action, event);

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

View solution in original post

5 REPLIES 5

Juhi Poddar
Kilo Patron

Hello @bhupendra paree 

You need to verify the mail script.

If possible please share the script.

 

"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"

 

Thank You
Juhi Poddar

Below is the script i created.
============

(function runMailScript(current, template, email, email_action, event) {
    // var mrvs = current.variables.destination_machines; // MRVS Internal name
    var arr2 = arr3 = arr4 = arr1 = arr5 = [];
    var gr = new GlideRecord("sc_req_item");
    gr.addQuery("cat_item",'57e4a7254rtg9ad08d7bcda036e45a19');
    gr.addQuery("sys_id", current.document_id);
    gr.query();
    if (gr.next()) {
        arr2 = gr.variables.destination_machines.destination_machine;
        arr3 = gr.variables.destination_machines.computer_name;
        arr1 = gr.variables.people_requiring_access.person_requiring_access;
        arr4 = gr.variables.people_requiring_access.email_address;
        for (var i = 0; i < arr1.length; ++i) {
            var gr2 = new GlideRecord("sys_user");
            gr2.addQuery('sys_id', (arr1[i]));
            gr2.query();
            while (gr2.next()) {
                var name = gr2.name;
                arr5.push(name);
            }
        }
    }
    if (arr2.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr>");
        template.print("<th> Destination Machine </th>");
        template.print("<th> Computer Name </th>");
        template.print("</tr>");
        for (i = 0; i < arr2.length; ++i) {
            template.print("<tr>");
            template.print("<td>" + arr2[i] + "</td>");
            template.print("<td>" + arr3[i] + "</td>");
            template.print("</tr>");
        }
        template.print("</table>");
    }
    if (arr1.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr>");
        template.print("<th> Person Requiring Access </th>");
        template.print("<th> Email ID </th>");
        template.print("</tr>");
        for (i = 0; i < arr1.length; ++i) {
            template.print("<tr>");
            template.print("<td>" + arr5[i] + "</td>");
            template.print("<td>" + arr4[i] + "</td>");
            template.print("</tr>");
        }
    }
})(current, template, email, email_action, event);

============

 

Please look and provide some output why Comment and Approval activity section is coming inbetween two tables.

Hello Can you Try the below Script 

the issue you're facing, where the two tables are getting separated by other parameters (such as comment and approval activity sections), is likely due to how the content is being printed within your script and how ServiceNow handles the rendering of email templates

 

(function runMailScript(current, template, email, email_action, event) {
var arr2 = arr3 = arr4 = arr1 = arr5 = [];
var gr = new GlideRecord("sc_req_item");
gr.addQuery("cat_item",'57e4a7254rtg9ad08d7bcda036e45a19');
gr.addQuery("sys_id", current.document_id);
gr.query();
if (gr.next()) {
arr2 = gr.variables.destination_machines.destination_machine;
arr3 = gr.variables.destination_machines.computer_name;
arr1 = gr.variables.people_requiring_access.person_requiring_access;
arr4 = gr.variables.people_requiring_access.email_address;
for (var i = 0; i < arr1.length; ++i) {
var gr2 = new GlideRecord("sys_user");
gr2.addQuery('sys_id', (arr1[i]));
gr2.query();
while (gr2.next()) {
var name = gr2.name;
arr5.push(name);
}
}
}

// Print the first table for destination machine data
if (arr2.length > 0) {
template.print("<table border='1'>");
template.print("<tr><th>Destination Machine</th><th>Computer Name</th></tr>");
for (var i = 0; i < arr2.length; ++i) {
template.print("<tr><td>" + arr2[i] + "</td><td>" + arr3[i] + "</td></tr>");
}
template.print("</table>");
}

// Add a line break to prevent the tables from merging visually
template.print("<br>");

// Print the second table for people requiring access data
if (arr1.length > 0) {
template.print("<table border='1'>");
template.print("<tr><th>Person Requiring Access</th><th>Email ID</th></tr>");
for (var i = 0; i < arr1.length; ++i) {
template.print("<tr><td>" + arr5[i] + "</td><td>" + arr4[i] + "</td></tr>");
}
template.print("</table>");
}
})(current, template, email, email_action, event);

--------------------------------------------------------------------------------------------------------------------------


If you found my response helpful, I would greatly appreciate it if you could mark it as "Accepted Solution" and "Helpful."
Your support not only benefits the community but also encourages me to continue assisting. Thank you so much!

Thanks and Regards
Ravi Gaurav | ServiceNow MVP 2025,2024 | ServiceNow Practice Lead | Solution Architect
CGI
M.Tech in Data Science & AI

 YouTube: https://www.youtube.com/@learnservicenowwithravi
 LinkedIn: https://www.linkedin.com/in/ravi-gaurav-a67542aa/

Hello @bhupendra paree 

Please try this optimized script. 

(function runMailScript(current, template, email, email_action, event) {
    // Arrays to store MRVS data
    var destinationMachines = [];
    var computerNames = [];
    var personSysIds = [];
    var emailAddresses = [];
    var personNames = [];

    // Fetch the record
    var gr = new GlideRecord("sc_req_item");
    gr.addQuery("cat_item", "57e4a7254rtg9ad08d7bcda036e45a19"); // Catalog item sys_id
    gr.addQuery("sys_id", current.document_id);
    gr.query();

    if (gr.next()) {
        // Extract MRVS data
        destinationMachines = gr.variables.destination_machines.destination_machine;
        computerNames = gr.variables.destination_machines.computer_name;
        personSysIds = gr.variables.people_requiring_access.person_requiring_access;
        emailAddresses = gr.variables.people_requiring_access.email_address;

        // Fetch names for person_sys_ids
        if (personSysIds && personSysIds.length > 0) {
            var userGr = new GlideRecord("sys_user");
            userGr.addQuery("sys_id", "IN", personSysIds.join(","));
            userGr.query();
            while (userGr.next()) {
                personNames.push(userGr.name.toString());
            }
        }
    }

    // Generate tables for Destination Machines
    if (destinationMachines && destinationMachines.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr><th>Destination Machine</th><th>Computer Name</th></tr>");
        for (var i = 0; i < destinationMachines.length; i++) {
            template.print("<tr>");
            template.print("<td>" + destinationMachines[i] + "</td>");
            template.print("<td>" + computerNames[i] + "</td>");
            template.print("</tr>");
        }
        template.print("</table>");
    }

    // Generate tables for People Requiring Access
    if (personSysIds && personSysIds.length > 0) {
        template.print("<table border='1'>");
        template.print("<tr><th>Person Requiring Access</th><th>Email Address</th></tr>");
        for (var j = 0; j < personSysIds.length; j++) {
            template.print("<tr>");
            template.print("<td>" + (personNames[j] || "Unknown") + "</td>");
            template.print("<td>" + emailAddresses[j] + "</td>");
            template.print("</tr>");
        }
        template.print("</table>");
    }
})(current, template, email, email_action, event);

Hope this helps!

 

"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"

 

Thank You
Juhi Poddar