Attach csv to catalog item to populate a Multi Row Variable Set (MRVs)

Sam Ogden
Tera Guru

Hi All,

I was wondering if there is anyway to allow a user to upload a CSV to a catalog item that would populate a multi-row variable set on the same catalog item.

We have created a MRV on a Firewall rule change catalog item:

find_real_file.png

Use case:

Most of the time this is fine as the user will only need to add a handful of rows at a time.  However there are certain times where a new server would require many rows to be added.  Currently the team have some csv templates that they have with all the row information contained.  They have asked if in these instances they could attach the template which would be added to the MRV?

Is this possible?  Or any other suggestions for bulk upload to a MRV?

Any help is greatly appreciated

Thanks

Sam

1 ACCEPTED SOLUTION

Hey Sam,

Dam that was quick. Only one slight modification and that is to create an empty array within the while loop and also numerate the array

Changes Highlighted:

        var firewallArr = [];
        var i = 0; //Boolean to iterate

        var importRow = new GlideRecord('u_firewall_rule_upload');
        importRow.addQuery('sys_import_set', importSetRec.sys_id);
        importRow.query();

        while (importRow.next()) {
            var firewallObj = {}; //Moved obj to inside while loop so we have a new one each time.

            firewallObj.source_ip = importRow.getValue('u_source_ip');
            firewallObj.source_server_name = importRow.getValue('u_source_server_name');
            firewallObj.destination_ip = importRow.getValue('u_destination_ip');
            firewallObj.destination_server_name = importRow.getValue('u_destination_server_name');
            firewallObj.protocol = importRow.getValue('u_protocol');
            firewallObj.port = importRow.getValue('u_port');
            firewallObj.service = importRow.getValue('u_service');
            firewallArr[i] = firewallObj; //Set the object created to the array based on the value of i.

            i += 1; //increase value of i
        }

Full Code:

var MRVUtils = Class.create();
MRVUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    getCSVData: function() {
        gs.info('--> MRVUtils: Entered');
        var cartID = this.getParameter('sysparm_cart_id');
        gs.info('--> MRVUtils: cart ID - ' + cartID);
		var dataSource = this.createDataSource();

        var donorTable = 'sc_cart_item';
        var recipientTable = 'sys_data_source';
        var recipientID = dataSource.getUniqueValue();
        gs.info('--> MRVUtils: recipient ID - ' + recipientID);

        GlideSysAttachment.copy(donorTable, cartID, recipientTable, recipientID);

        var loader = new GlideImportSetLoader();
        var importSetRec = loader.getImportSetGr(dataSource);
        var ranload = loader.loadImportSetTable(importSetRec, dataSource);
        importSetRec.state = 'loaded';
        importSetRec.update();


        var firewallArr = [];
        var i = 0;

        var importRow = new GlideRecord('u_firewall_rule_upload');
        importRow.addQuery('sys_import_set', importSetRec.sys_id);
        importRow.query();

        while (importRow.next()) {
            var firewallObj = {};

            firewallObj.source_ip = importRow.getValue('u_source_ip');
            firewallObj.source_server_name = importRow.getValue('u_source_server_name');
            firewallObj.destination_ip = importRow.getValue('u_destination_ip');
            firewallObj.destination_server_name = importRow.getValue('u_destination_server_name');
            firewallObj.protocol = importRow.getValue('u_protocol');
            firewallObj.port = importRow.getValue('u_port');
            firewallObj.service = importRow.getValue('u_service');
            firewallArr[i] = firewallObj;

            i += 1;
        }

        var firewallJSONString = JSON.stringify(firewallArr);
        gs.info('--> MRVUtils: Result - ' + firewallJSONString);
        return firewallJSONString;

    },

    createDataSource: function() {
        var grDs = new GlideRecord('sys_data_source');
        grDs.name = 'Firewall Rule Change at: ' + new GlideDateTime();
        grDs.import_set_table_name = 'u_firewall_rule_upload';
        grDs.file_retrieval_method = 'Attachment';
        grDs.type = 'File';
        grDs.format = 'CSV';
        grDs.header_row = 1;
        grDs.sheet_number = 1;
        grDs.insert();
        gs.info('--> DataSource sysID is ' + grDs + ' and table val is ' + grDs.sys_class_name);
        return grDs;
    },



    type: 'MRVUtils'
});

 

find_real_file.png

View solution in original post

24 REPLIES 24

Ankur Bawiskar
Tera Patron
Tera Patron

Hi Sam,

below approach you can use

1) Let user attach the csv file in the required format

2) once the RITM is submitted populate the variable set with the json string by reading the content from csv file

Regards
Ankur

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

Hi Ankur,

 

I was able to achieve the above requirement but now i am stuck on the point where i am able to see the rows but they dont show any values(highly likely due to transform mapping)

I added first name to the field map with target field as "variable set" and it started showing that value.

But it is not letting me map multiple values to that field. Gives an error every time(attached screenshot for reference)

Wanted to know that how do i map multiple values using transform map to one variable_set.

Any suggestions would be really helpful.

find_real_file.png

find_real_file.png

Hi, I faced the same issue. Could you please explain how did you fix this?

Regards,

Guna Shalini

This got fixed.

But i can really use any suggestions or help around generating multiple RITMs via multirow variable set.

Are there any implementations done around this?

 

Thanks

Surabhi

rewanthrr
Tera Expert

Hi Sam,

This is a great thread. I have same requirement. Could you please share me the complete steps and code to achieve this functionality.

 

Thanks,

RRR