- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-21-2021 05:34 PM
以下のQiitaのサイトを参考にServiceNowテーブルに添付されたファイルを読み取り、テーブルへ反映する処理を実装しようとしています。
https://qiita.com/htshozawa/items/c3c12fe06e99831e3012
Qiitaの内容と今回やろうとしていることの違いは以下の通りですが、スクリプトの変更点についてご教授いただけないでしょうか。
①添付ファイル形式
Qiita:Excel
今回:CSV
②ファイルが添付されるレコード数
Qiita:1レコードに添付
今回:複数レコードに添付 ※全レコードの内、添付ファイルが存在するレコードのみインポート対象とする
③定期的にスクリプトを実行
Qiita:要件はなし
今回:システム定義>ジョブスケジュール
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-22-2021 05:46 PM
ご丁寧に懸念点とソースコードをご連携いただいありがとうございます。
今回、ImportSetテーブルへCSVファイルを添付 ⇒ 反映したいテーブル(今回ですとIncident)へCSVファイルの内容をインポートすることを想定しています。
念のための確認になってしまうのですが、こちらのスクリプトを1日に一回など、定期的に実行する場合は
「システム定義>ジョブスケジュール」を使用するで合っていますでしょうか?
また、以下処理の内容について、質問させてください。
grInc.comments.setJournalEntry('CSV Data ' + JSON.stringify(csvList, null, 2));
⇒CSVファイルの内容をJSON形式に変換しておりますが、理由についてご教示いただけますでしょうか?
if (grInc.update()) {
⇒こちらの処理でインシデントテーブルをCSVファイルの内容で一括更新している認識で合っていますでしょうか?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-22-2021 01:12 AM
処理を考えてみたのですが、多くの懸念点があります。
懸念点
- Excel を処理しているGlideExcelParserとCSV処理は異なる個所が多いので参考にならない。
- 参考にしているQiitaの記事は少々信頼性がありません。気になる点がいくかあります。これはどこの記事も当てはまりますし私のScriptもバグがあるかもしれませんが、動きもしないScriptや、やめておいた方が良い処理を掲載している場合も見かけます。
- 多数の変換処理が必要なCSVならServiceNowのImportSetを使ったImportをお勧めします。
- 添付ファイルを取り込むとして、対象のレコードに複数添付されていたらどうするか。
- 前回取り込んだ添付ファイルと、今回取り込むべき添付ファイルはどう見分けるか。その対策のため、取り込み済みの添付ファイルを削除してしまうと原本が失われて確認や編集ができなくなってしまうのは良いか。
- 添付ファイルが全く別のファイルであったり、表記に誤りがあってエラーがあったらどうするか。
- 新規作成レコードを対象に取り込むとしたら、修正して再取り込みは出来なくても良いか。
などなど要件が詰め切れていないです。
それらは後で考えるとして、参考Scriptを作成してみました。
処理内容は、今日(0時以降)作成したIncidentを対象にCSVファイルUTF8を取り込んでデータを処理できるようにした後Commentに出力します。
参考資料:CSVParser | ServiceNow Developers
// 添付ファイルTableからCSVデータを抽出する
function getCsv(grAtt) {
var gsAttachment = new GlideSysAttachment();
var byteData = gsAttachment.getBytes(grAtt);
var csvStr;
var parser = new sn_impex.CSVParser();
var headers;
var csvObj;
var csvList = [];
var delimiter = ',';
var quoteCharacter = '"';
if (!byteData) return null;
csvStr = '' + Packages.java.lang.String(byteData, 'UTF-8');// 'UTF-8' or 'MS932' (JavaのSJIS)
if (!csvStr) return null;
csvLine = csvStr.match(/[^\r\n]+/g);
if (!csvLine) return null;
headers = parser.parseLineToArray(csvLine[0], delimiter, quoteCharacter); //
if (!headers) return null;
for (var i = 1; i < csvLine.length; i++) {
csvObj = parser.parseLineToObject(csvLine[i], headers, delimiter, quoteCharacter);
csvList.push(csvObj);
}
return csvList;
}
var grAtt;
var csvList;
// インシデントTableから今日一日に作成されたインシデントを検索して添付ファイルがあるなら情報を取得する
var grInc = new GlideRecord('incident');
grInc.addEncodedQuery('sys_created_on>javascript:gs.endOfYesterday()');
gs.info('gs.endOfYesterday()=' + gs.endOfYesterday());
grInc.query();
while (grInc.next()) {
grAtt = new GlideRecord('sys_attachment');
grAtt.addQuery('table_name', 'incident');
grAtt.addQuery('table_sys_id', grInc.sys_id);
grAtt.query();
//ひとつの添付ファイルのみ処理します。複数処理する場合はwhileに変更
if (grAtt.next()) {
csvList = getCsv(grAtt);
if (csvList) {
grInc.comments.setJournalEntry('CSV Data ' + JSON.stringify(csvList, null, 2));
if (grInc.update()) {
gs.info(grInc.number + ' update');
}
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-22-2021 05:46 PM
ご丁寧に懸念点とソースコードをご連携いただいありがとうございます。
今回、ImportSetテーブルへCSVファイルを添付 ⇒ 反映したいテーブル(今回ですとIncident)へCSVファイルの内容をインポートすることを想定しています。
念のための確認になってしまうのですが、こちらのスクリプトを1日に一回など、定期的に実行する場合は
「システム定義>ジョブスケジュール」を使用するで合っていますでしょうか?
また、以下処理の内容について、質問させてください。
grInc.comments.setJournalEntry('CSV Data ' + JSON.stringify(csvList, null, 2));
⇒CSVファイルの内容をJSON形式に変換しておりますが、理由についてご教示いただけますでしょうか?
if (grInc.update()) {
⇒こちらの処理でインシデントテーブルをCSVファイルの内容で一括更新している認識で合っていますでしょうか?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-22-2021 07:28 PM
- 質問:「システム定義>ジョブスケジュール」を使用するで合っていますでしょうか?
- 回答:合っています。もしくは、Flowでも定期実行できます。
- 質問:CSVファイルの内容をJSON形式に変換しておりますが、理由についてご教示いただけますでしょうか?
- 回答:CSVファイルを正しく取り込めたか目で見て確認するためにJSON形式に変換してIncidentのCommentsに記載しました。
- 質問:こちらの処理でインシデントテーブルをCSVファイルの内容で一括更新している認識で合っていますでしょうか?
- 回答:インシデントにCSVの値を格納はしていますが、CSVの各カラムごとに、インシデントの特定の項目値を入れるようには作っていません。そこは要件に合わせて変換処理を作成してください。例を下記に記載します。
前回の参考例のScriptを実行した時のデータを使って変換処理を説明します。
添付したCSVの内容
"Item01","Item02","Item03"
"test7590","2021/02/25 09:29","クローズ"
"test7590","2021/02/25 09:29","クローズ"
"test7590","2021/02/25 09:29","クローズ"
Incident Commentの内容
CSV Data[{
"Item01": "test7590",
"Item02": "2021/02/25 09:29",
"Item03": "クローズ"
}, {
"Item01": "test7590",
"Item02": "2021/02/25 09:29",
"Item03": "クローズ"
}, {
"Item01": "test7590",
"Item02": "2021/02/25 09:29",
"Item03": "クローズ"
}]
参照するには、
csvList[0]['Item01'] これで1行目の Item01 カラムのデータを参照できます。
csvList[2]['Item03'] この場合は3行目の Item03 カラムのデータを参照できます。
この結果からIncidentの各項目に格納する処理
参考例
var gdt;
while (grInc.next()) {
grAtt = new GlideRecord('sys_attachment');
grAtt.addQuery('table_name', 'incident');
grAtt.addQuery('table_sys_id', grInc.sys_id);
grAtt.query();
//ひとつの添付ファイルのみ処理します。複数処理する場合はwhileに変更
if (grAtt.next()) {
csvList = getCsv(grAtt);
if (csvList) {
grInc.comments.setJournalEntry('CSV Data ' + JSON.stringify(csvList, null, 2));
grInc.setValue('short_description',csvList[0]['Item01']);
gdt = new GlideDateTime();
gdt.setDisplayValue(csvList[0]['Item02'],'yyyy/MM/dd HH:mm');
grInc.setValue('opened_at',gdt);
if(csvList[0]['Item03'] == 'クローズ'){
grInc.setValue('state','7');
}
if (grInc.update()) {
gs.info(grInc.number + ' update');
}
}
}
}
変換方法はCSVカラムに格納されている値の形式と、格納先のインシデントの形式に合わせて、様々な変換が必要になります。