[ServiceNow]Multi-row Variable Set(複数行変数セット)へのsetValueについて

## Multi-row Variable Set(複数行変数セット)とは
Servicenowのサービスカタログにスプレッドシート形式で複数の値を設定することができるカタログアイテムになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/5a42595a-e684-5c6a-f0d9-2bb2c11defe3.png)

複数行変数セットの作成方法はメニューのService Catalog＞Catalog Variables＞Variable Setsを押下し、
表示されるVariable Setsの一覧からNewを押下することで作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/312cd526-bea3-2cd8-5d32-75543e6e0cc3.png)

### setValue方法
g_formのsetValue(String fieldName, String value)メソッドで
fieldNameに複数行変数セットの内部名、valueにJSONを文字列化したデータを指定することで値を設定できる。

#### Catalog Client Script
```javascript:sample
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    var sampleJson = [{
        one: '1',
        two: '2',
        user: 'c2826bf03710200044e0bfc8bcbe5d7c' //Reference項目の場合sys_idを指定
    }, {
        one: 'hoge',
        two: 'hogehoge',
        user: 'c2826bf03710200044e0bfc8bcbe5d8e' //Reference項目の場合sys_idを指定
    }, {
        one: 'ほげ',
        two: 'ほげほげ'
    }, {
        two: 'oneが空',
        user: 'c2826bf03710200044e0bfc8bcbe5d97' //Reference項目の場合sys_idを指定
    }];
		
	g_form.setValue('sample_multi_row',JSON.stringify(sampleJson));

}
```
### スクリプト実行結果
値を設定していなかったところは空欄になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/1f1f1a53-2c1a-ff0c-d5ef-87a4b96e8070.png)


## (応用編)過去に申請した内容をコピーする
よくありそうなやつ
#### Script Include
```javascript:sample Script Include
var sampleCatalogUtils = Class.create();
sampleCatalogUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    getMultiRowData: function() {
        var result;
        var requestId = this.getParameter('sysparm_request_id');
        var gr = new GlideRecord('sc_req_item');
        if (gr.get(requestId)) {
            result = gr.variables['sample_multi_row']; //変数セットの内部名を指定
        }

        return result.toString(); //変数セットの配列を文字列化する。JSON.stringify()は動かない
    },
    type: 'sampleCatalogUtils'
});
```
#### Catalog Client Script
```javascript:sample Client Script
function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
    var ga = new GlideAjax('global.sampleCatalogUtils'); // Script IncludeのAPI名を指定
    ga.addParam('sysparm_name', 'getMultiRowData'); // 呼び出す関数名を指定
    ga.addParam('sysparm_request_id', newValue); // RequstItemのsys_id
    ga.getXML(callback); // 非同期呼び出し

    // Script Include側で処理が終わった際に呼ばれるコールバック関数
    function callback(response) { 
    var answer = response.responseXML.documentElement.getAttribute("answer");
		g_form.setValue('sample_multi_row',answer);
    }
}
```
### スクリプト実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/946893/23f84b41-3476-d933-38ea-769ec3d2ee6d.png)
### 考慮が必要なこと
申請時に値を設定していなかったところはnullが入ってしまう。
値を一部設定している状態でスクリプトが動作すると値が上書きされるため、
追記したい場合はsetValue()を行う前にgetVlaue()で複数行変数セットの配列情報を取得し、
Script Includeで取得した情報を配列にpush()する必要がある。

## 最後に
いかがでしたでしょうか。
一部考慮が必要なことがあるためこちらのコードを参考にする際はご注意ください。

変数セットの配列を文字列化する際にJSON.stringify()が利用できず、toString()を使用しています。
使えない理由をご存知の方いましたらご教示いただけますと幸いです。
{じゃなくて[始まりだからくらいしかわからない・・・

変数セット取得スクリプト
```javascript:scripts-background
        var result;
        var requestId = '【sc_req_itemのsys_id】';
        var gr = new GlideRecord('sc_req_item');
        if (gr.get(requestId)) {
            result = gr.variables['sample_multi_row'];
        }
        gs.info(result);
```
実行結果
```
*** Script: [ {
  "one" : "1",
  "two" : "2",
  "user" : "c2826bf03710200044e0bfc8bcbe5d7c"
}, {
  "one" : "hoge",
  "two" : "hogehoge",
  "user" : "c2826bf03710200044e0bfc8bcbe5d8e"
}, {
  "one" : "ほげ",
  "two" : "ほげほげ",
  "user" : "null"
}, {
  "one" : "null",
  "two" : "oneが空",
  "user" : "c2826bf03710200044e0bfc8bcbe5d97"
} ]
```