どうも。つじけ(tsujikenzo)です。このシリーズでは「棚卸データの突合」についてお届けしています。全3~4回の今日は4回目です。 延長戦で第5回まで行く気がしています💦
前回のおさらい
さて、前回は「テーブルを連想配列で取得する」についてお届けしました。連想配列で取得したデータがあまりに操作性が長けたので、ついでに突合作業も終わってしまいましたね。
今回はこのコードをパーツ化(ライブラリ化)したいと思います。
Valuesの取得
要件定義になっていきますが(苦手です💦)今回は「3つのテーブルの重複判定」というのは想定しません。比較するのは2つのテーブルでいいでしょう。構造化データのテーブルを準備してもらうのは当然です。
SpreadsheetDataConverterToObject.getElementsArray()メソッドに必要な[Sheet ID]と[シート名]があれば良さそうです。名称を「オリジナルSheet ID」と「オリジナルシート名」と名付けるのはいかかでしょう。同様に列挙しますと、
第1引数・・・オリジナルSheet ID
第2引数・・・オリジナルシート名
第3引数・・・比較Sheet ID
第4引数・・・比較シート名
という4つの引数があれば良さそうです。
比較するColumnの選択
結合したいColumnは3つだけでしょうか?もしかしたら4つ、5つのセルを結合して比較したいかもです。かと言って無限にセルがあることもないと思いますので、今回は最大5つのセルを結合する場合を想定するということでいかかでしょうか。(ここ要件定義が難しいところですね💦)
念の為、.map()メソッドに空文字が渡されても動くことを確認しておきます。
const joinedCmpValues = comparedValues.map(element => [[element['商品ID'], element['’]].join(``)]).flat();
const joinedOrgValues = originalValues.map(element => [[element['商品ID2'], element['']].join(``)]).flat();
.join()メソッドでやっつけます。分割代入にもします。
const [param1,param2,param3,param4,param5] = ['商品ID','納品書番号','','',''];
const [param6,param7,param8,param9,param10] = ['商品ID2','納品書番号2','','',''];
const joinedCmpValues = comparedValues.map(element => [[element[param1],element[param2],element[param3],element[param4],element[param5]].join(``)]).flat();
const joinedOrgValues = originalValues.map(element => [[element[param6],element[param7],element[param8],element[param9],element[param10]].join(``)]).flat();
比較するColumnsは最大10個の引数を用意すれば良さそうです。が流石に引数10個は多すぎます💦コンテンツアシストに引数が出なくなってしまいますが、コードがスッキリするので、スプレッド構文で仮引数を受けてコードの中で引数に分割代入したいと思います。
function symDiffChecker(...arr) {
let [orgSsId,orgSheetName,cmpSsId,cmpSheetName,param1,param2,param3,param4,
param5,param6,param7,param8,param9,param10] = arr;
}
戻り値は何か
大事なことを忘れていました。今は重複しないレコードをconsole.log()で出力したままですが、実際の現場ではどのような戻り値を返すと便利でしょうか。
今回は2つの配列を出力していますので、2次元配列にしてしまえばスプレッドシートに張り付けなど汎用性が高そうです。
return [cmpDiffs, orgDiffs];
パーツ化する
このようなパーツ化が正しいのか、経験がないのでこれから学んでいきたいことですが、下記14個の引数を渡してあげると、その差分(対象差)を2次元配列として返します。
第1引数・・・オリジナルSheet ID
第2引数・・・オリジナルシート名
第3引数・・・比較Sheet ID
第4引数・・・比較シート名
第5引数・・・オリジナルシート列名1
第6引数・・・オリジナルシート列名2
第7引数・・・オリジナルシート列名3
第8引数・・・オリジナルシート列名4
第9引数・・・オリジナルシート列名5
第10引数・・・比較シート列名1
第11引数・・・比較シート列名2
第12引数・・・比較シート列名3
第13引数・・・比較シート列名4
第14引数・・・比較シート列名5
戻り値・・・・それぞれの差分を配列の要素としてもつ2次元配列
完成したコードはこちらです。関数名を名付けて、ドキュメンテーションコメントも付けました。
/**
* 2つのテーブルの差分を返す
*
* @param {string} オリジナルSheet ID
* @param {string} オリジナルシート名
* @param {string} 比較Sheet ID
* @param {string} 比較シート名
* @param {string} オリジナルシート列名1
* @param {string} オリジナルシート列名2
* @param {string} オリジナルシート列名3
* @param {string} オリジナルシート列名4
* @param {string} オリジナルシート列名5
* @param {string} 比較シート列名1
* @param {string} 比較シート列名2
* @param {string} 比較シート列名3
* @param {string} 比較シート列名4
* @param {string} 比較シート列名5
* @return {array} 両テーブルの差分の2次元配列
* @Library SpreadsheetDataConverterToObject(Script ID: 1s4kGJwF2eG-WGmeqgLWeqQtIBRAXUZbbh3fQ3f7QHvNywubO99nduFIY)
*/
function symDiffChecker(...arr) {
let [orgSsId,orgSheetName,cmpSsId,cmpSheetName,param1,param2,param3,param4,
param5,param6,param7,param8,param9,param10] = arr;
const orgArray = SpreadsheetDataConverterToObject.getElementsArray(orgSsId,orgSheetName);
const cmpArray = SpreadsheetDataConverterToObject.getElementsArray(cmpSsId,cmpSheetName);
const orgValues = orgArray.map(element => [[element[param1],element[param2],element[param3],element[param4],element[param5]].join(``)]).flat();
const cmpValues = cmpArray.map(element => [[element[param6],element[param7],element[param8],element[param9],element[param10]].join(``)]).flat();
const orgDiffs = orgValues.filter(element => cmpValues.indexOf(element) === -1);
const cmpDiffs = cmpValues.filter(element => orgValues.indexOf(element) === -1);
return [rightDiffs, leftDiffs];
}
ライブラリとして公開する
ライブラリとして公開する方法はこちらの記事を参考にしてください(新IDE対応)。
プロジェクトファイルの名前は「SymDiffChecker」としました。
まとめ
さて、パーツ化の要件定義と、ライブラリとして公開が完了しました。次回は最終回としてライブラリのマニュアルを公開したいと思います。間違っていることも沢山あると思いますので、ツッコミ大歓迎です!よろしくお願いいたします。