[DB]在庫管理バーコード Stock4

Database

どうも。つじけ(tsujikenzo)です。このシリーズでは「在庫管理バーコード」についてお届けしています。まだ全然終わらなくて4記事目になってしまいました💦

前回のおさらい

前回は、突合する為のデータはあらかじめ結合したら効率がいいということに気付き、その準備とミニマムデータでテストをしていました。

[DB]在庫管理バーコード Stock3
どうも。つじけ(tsujikenzo)です。このシリーズでは「在庫管理バーコード」についてお届けしています。社内マニュアル的な要素が強いですが、皆さんのお勤め先でも使えるアイディアになれば幸いです。前回のおさらい前回は「現場棚卸とデ...

今日はその続きです。

突合データの準備

間が開いてしまって忘れた人もいると思うので、今回はこのような2つのテーブル(右と左)を一致してるか問題です。

データの準備は3行で十分です。

const objArray = SpreadsheetDataConverterToObject.getElementsArray('Sheet ID','シート1');
const leftValues = objArray.map(element => [element['商品ID'] + element['納品書番号']]);
const rightValues = objArray.map(element => [element['商品ID2'] + element['納品書番号2']]);

無事に結合した状態で配列が取れてるようです。

後で作業がしやすいように.flat()メソッドで1次元化したVerにしましょう。

const objArray = SpreadsheetDataConverterToObject.getElementsArray('Sheet ID','シート1');
const leftValues = objArray.map(element => [element['商品ID'] + element['納品書番号']]).flat();
const rightValues = objArray.map(element => [element['商品ID2'] + element['納品書番号2']])..flat();

2つの配列の差分を抽出

2つの配列の差分を抽出する為には.filter()メソッドで一発です。ログまで出力してみましょう。

const diffs = leftValues.filter(element => rightValues.indexOf(element) === -1);
console.log(diffs);

いい感じですね👏

今は差分の結果を左テーブルのみ出力していますが、できれば右テーブルで発生している差分も確認しておきたいです。必要なコードはこうです。

const rightDiffs = rightValues.filter(element => leftValues.indexOf(element) === -1);
console.log(rightDiffs);

パーツ化する

完成したコードはこちらです。

function myFunction() {
const objArray =
SpreadsheetDataConverterToObject.getElementsArray('Sheet ID','シート1');
const leftValues = objArray.map(element => [element['商品ID'] + element['納品書番号']]).flat();
const rightValues = objArray.map(element => [element['商品ID2'] + element['納品書番号2']]).flat();
const leftDiffs = leftValues.filter(element => rightValues.indexOf(element) === -1);
const rightDiffs = rightValues.filter(element => leftValues.indexOf(element) === -1);
}

このコードに汎用性を持たせるとするならどうしたらいいでしょうか。要件定義の話になってきますね💦(苦手です)

Valuesの取得

今回は3つのテーブルの重複判定というのは想定しません。比較する2つでいいでしょう。構造化データのテーブルを準備してもらうのは当然なので、SpreadsheetDataConverterToObject.getElementsArray()メソッドに必要な[Sheet ID][シート名]があれば良さそうです。名称を「オリジナルSheet ID」「オリジナルシート名」と名付けるのはいかかでしょう。同様に列挙しますと、

第1引数・・・オリジナルSheet ID
第2引数・・・オリジナルシート名
第3引数・・・比較Sheet ID
第4引数・・・比較シート名
という感じでしょうか。

比較するColumnの選択

結合したいColumnは2つだけでしょうか?もしかしたら3つ、4つのセルを結合して比較したいかもです。

element['商品ID'] + element['納品書番号']

かと言って無限にセルがあることもないと思いますので、今回は最大5つのセルを結合する場合を想定するということでいかかでしょうか。(ここ要件定義が難しいところですね💦)

念の為、.filter()メソッドに空文字が渡されても動くことを確認しておきます。

const leftValues = objArray.map(element => [element['商品ID'] + element['’]]).flat();
const rightValues = objArray.map(element => [element['商品ID2'] + element['']]).flat();

ちょっと野暮ったいかもしれませんが、ベタ書きしてみます。

const param1 = '商品ID';
const param2 = '納品書番号';
const param3 = '';
const param4 = '';
const param5 = '';

const param6 = '商品ID2';
const param7 = '納品書番号2';
const param8 = '';
const param9 = '';
const param10 = '';

const leftValues = objArray.map(element => [element[param1] +
element[param2] + element[param3] + element[param4] +
element[param5]]).flat();
const rightValues = objArray.map(element => [element[param6] +
element[param7] + element[param8] + element[param9] +
element[param10]).flat();

いやー、やっぱ野暮ったいな。動くんですけどカッコ悪いなぁ。。。💦

解決しました。join()メソッドでやっつけます。分割代入にもします。

const [param1,param2,param3,param4,param5] = ['商品ID','納品書番号','','',''];
const [param6,param7,param8,param9,param10] = ['商品ID2','納品書番号2','','',''];

const leftValues = objArray.map(element => [[element[param1],element[param2],element[param3],element[param4],element[param5]].join(``)]).flat();
const rightValues = objArray.map(element => [[element[param6],element[param7],element[param8],element[param9],element[param10]].join(``)]).flat();
const diffs = leftValues.filter(element => rightValues.indexOf(element) === -1);

console.log(diffs);

無事に突合できているようです。

比較するColumnsは最大10個の引数を用意すれば良さそうです。

戻り値は何か

大事なことを忘れていました。今は重複しないレコードをconsole.log()で出力したままですが、実際の現場ではどのような戻り値を返すと便利でしょうか。

今回は2つの配列を出力していますので、2次元配列にしてしまえばスプレッドシートに張り付けなど汎用性が高そうです。

return [rightDiffs, leftDiffs];

パーツ化する

このようなパーツ化が正しいのか、経験がないのでこれから学んでいきたいことですが、下記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次元配列
*
*/

function  symDiffChecker(orgSsId,orgSheetName,cmpSsId,cmpSheetName,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10) {

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];
}

まとめ

さて、コードが完成したので、汎用性を持たせる為にマジックナンバー(ベタ書き)になってしまっていた値を引数にして関数化してみました。このように引数が多い場合は配列で受けるような気もしますが、今回はベタ打ちで書いてみました💦(お恥ずかしいです)。まぁこの辺は経験が全くないのでこれから知識を増やしていこうと思います。

次回は最終回としてライブラリとして公開して公式マニュアルとしたいと思います。

このシリーズの目次

  1. [DB]在庫管理バーコード Stock1
  2. [DB]在庫管理バーコード Stock2
  3. [DB]在庫管理バーコード Stock3
  4. [DB]在庫管理バーコード Stock4

Comments

Copied title and URL