Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

リストの値を別のリストに追加する方法

ryo200
Tera Contributor

こんにちは

 

UIポリシーを使用し、

テーブル2のフォームでテーブル1を参照した際に

テーブル1のレコードに含まれるリストの値をテーブル2のリストにコピーしたいです。


テーブル2で指定したテーブル1のレコード名からQueryを行い、
テーブル1のリストの値をテーブル2のリストに追加したいと考えていますが、

以下のスクリプトが動作しません
解決策をできればスクリプトを添えて教えてください。

 

お願い致します。

 

構成とスクリプト

Tabale1
フィールド名:table1_list_name タイプ:string
フィールド名:table1_list タイプ:list 参照:sys_user

Table2

フィールド名:table1_list_name2 タイプ:string
フィールド名:table2_list タイプ:list 参照:sys_user

 

UIPoricy
条件
tabale1_list_name2 は空ではない

 

True
function onCondition() {
var userList = new GlideRecord('table1');
var user_array = [];
userList.addQuery('table1_list_name','=',current.table1_list_name2);
userList.query();
user_array.push(userList.table1_list.toSting());
current.table2list = user_array;
}

 

False
function onCondition() {
var user_array = [];
current.tabele2_list = user_array;
}

 

 

1 件の受理された解決策

Community Alums
適用対象外

@ryo200 様

こちらで同様の投稿をされているようですが、問題は解決されましたでしょうか?

https://www.servicenow.com/community/developer-forum/how-to-pass-a-list-value-to-another-list-in-ui-...

 

  • 上記URLに返信があるとおり、UI Policy などのクライアント側スクリプトで GlideRecord を呼び出すのは処理速度の観点でおすすめしません。GlideRecord の処理は Script Include に実装して、GlideAjax で呼び出すのが一般的です。
  • UI Policy で current オブジェクトは使用できません。代わりに g_form などでフォーム上の値を取得する必要があります。
  • List型のフィールドからは Array 型オブジェクトではなく、参照先レコードの sys_id をカンマ区切りにした文字列が返されます。

以上の点を踏まえて、Incident から Problem へ値をコピーするスクリプトの例を提示します。テーブル名やカラム名は適宜読み替えてください。


Script Include "UserListAJAX" を新規作成

  • Client callable : true(チェックを入れる)
  • Script : 

 

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

	copyUserList: function() {
		var table1_list_name2 = this.getParameter('sysparm_table1_list_name2');
		var table1_list = "";

		var table1 = 'incident';
		var userList = new GlideRecord(table1);
		userList.addQuery('u_table1_list_name', table1_list_name2);
		userList.query();
				
		if(userList.next()) {
			table1_list = userList.u_table1_list;
		}		
		return table1_list;
	},
	
    type: 'UserListAJAX'
});​

 

 

UI Policy "Copy User List" を新規作成

  • Table : Problem [problem]
  • Conditions : Table1 List Name2 | is not empty
  • Run scripts : true(チェックを入れる)
  • Execute if true :

 

function onCondition() {
	var ga = new GlideAjax('UserListAJAX');
	ga.addParam('sysparm_name','copyUserList');
	ga.addParam('sysparm_table1_list_name2', g_form.getValue('u_table1_list_name2'));
	ga.getXML(callback);

	// Script Include から受け取った値を処理するコールバック関数
	function callback(response) {
		var answer = response.responseXML.documentElement.getAttribute("answer");
        g_form.setValue("u_table2_list", answer);
	}
}​

 

 

  • Execute if false : 

 

function onCondition() {
	g_form.setValue("u_table2_list", "");
}​

 

 

ユースケースが不明なので一概には言えませんが、UI Policy と Script Include の2箇所を管理するのは煩雑になりそうなので、私なら Business Rule で(チケットを保存する直前に値をコピーする)実装を提案すると思います。

元の投稿で解決策を見る

2件の返信2

Community Alums
適用対象外

@ryo200 様

こちらで同様の投稿をされているようですが、問題は解決されましたでしょうか?

https://www.servicenow.com/community/developer-forum/how-to-pass-a-list-value-to-another-list-in-ui-...

 

  • 上記URLに返信があるとおり、UI Policy などのクライアント側スクリプトで GlideRecord を呼び出すのは処理速度の観点でおすすめしません。GlideRecord の処理は Script Include に実装して、GlideAjax で呼び出すのが一般的です。
  • UI Policy で current オブジェクトは使用できません。代わりに g_form などでフォーム上の値を取得する必要があります。
  • List型のフィールドからは Array 型オブジェクトではなく、参照先レコードの sys_id をカンマ区切りにした文字列が返されます。

以上の点を踏まえて、Incident から Problem へ値をコピーするスクリプトの例を提示します。テーブル名やカラム名は適宜読み替えてください。


Script Include "UserListAJAX" を新規作成

  • Client callable : true(チェックを入れる)
  • Script : 

 

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

	copyUserList: function() {
		var table1_list_name2 = this.getParameter('sysparm_table1_list_name2');
		var table1_list = "";

		var table1 = 'incident';
		var userList = new GlideRecord(table1);
		userList.addQuery('u_table1_list_name', table1_list_name2);
		userList.query();
				
		if(userList.next()) {
			table1_list = userList.u_table1_list;
		}		
		return table1_list;
	},
	
    type: 'UserListAJAX'
});​

 

 

UI Policy "Copy User List" を新規作成

  • Table : Problem [problem]
  • Conditions : Table1 List Name2 | is not empty
  • Run scripts : true(チェックを入れる)
  • Execute if true :

 

function onCondition() {
	var ga = new GlideAjax('UserListAJAX');
	ga.addParam('sysparm_name','copyUserList');
	ga.addParam('sysparm_table1_list_name2', g_form.getValue('u_table1_list_name2'));
	ga.getXML(callback);

	// Script Include から受け取った値を処理するコールバック関数
	function callback(response) {
		var answer = response.responseXML.documentElement.getAttribute("answer");
        g_form.setValue("u_table2_list", answer);
	}
}​

 

 

  • Execute if false : 

 

function onCondition() {
	g_form.setValue("u_table2_list", "");
}​

 

 

ユースケースが不明なので一概には言えませんが、UI Policy と Script Include の2箇所を管理するのは煩雑になりそうなので、私なら Business Rule で(チケットを保存する直前に値をコピーする)実装を提案すると思います。

@Community Alums 様

 

ご回答、有難う御座います。

当方、回避策として

1.Flow Designer

2.Client Script でのフィールドタイプ:参照と関連フィールドによる値のコピー の2つでの動作を確認出来ました。

 

ご回答頂いたのにも関わらず、ご活用出来ず、申し訳ございません。

1つの知見として蓄積させて頂きます。

 

この度は有難う御座いました。