【解決】アプリ間でのレコードを比較し差分を調べたい

平素お世話になっております。

前に進めなくなってしまいましたので、ご教示願います。

表題にもあります通り、同じデータ項目群を扱っているアプリ同士でデータの差分を比較・調べるためのアプリを作製しています。

アプリAに存在するデータが、アプリB内のデータと重複していないかを調べ、重複があったらアラートを出すという仕組みが目標です。コードはアプリA内に書いています。

現在以下リンクの記事を参考にコードを書いております。

https://developer.cybozu.io/hc/ja/articles/203702800-%E5%85%A8%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%8F%96%E5%BE%97%E6%96%B9%E6%B3%95  

まず以下のようにクラスを作成しておき、(何故かインデントを維持したまま貼り付けられずすみません)

/**
* kintoneと通信を行うクラス recordManagerFunc.js
*/
var KintoneRecordManager = (function () { //prototypeでメソッドを作っている
KintoneRecordManager.prototype.records = []; // 取得したレコード
KintoneRecordManager.prototype.appId = null; // アプリID
KintoneRecordManager.prototype.query = ""; // 検索クエリ
KintoneRecordManager.prototype.limit = 100; // 一回あたりの最大取得件数
KintoneRecordManager.prototype.offset = 0; // オフセット

function KintoneRecordManager() {
this.appId = kintone.app.getId();
this.records = [];
}

KintoneRecordManager.prototype.getRecords = function (callback) { // すべてのレコード取得するメソッド
kintone.api(
kintone.api.url("/k/v1/records", true), //第一引数
"GET", //第二引数
{ //第三引数(対象となるアプリとクエリを指定する)
app: this.appId,
query:
this.query +
(" limit " + this.limit + " offset " + this.offset),
},
(function (_this) { //第四引数(関数)
return function (res) {
var len;
Array.prototype.push.apply(_this.records, res.records);
len = res.records.length;
_this.offset += len;
if (len < _this.limit) { // まだレコードがあるか?
_this.ready = true;
if (callback !== null) {
callback(_this.records); // レコード取得後のcallback
}
} else {
_this.getRecords(callback); // 自分自身をコール
}
};
})(this)
);
};
return KintoneRecordManager;
})();

次に以下のコードで、アプリAとアプリBのデータを行列で取り出し、比較をしたいのですがここで止まってしまっています。

/*
**compare.js
*/
(function () {
"use strict";
kintone.events.on("app.record.index.show", function (event) {
//アプリA読み取り - レコード一覧画面;
var manager1 = new KintoneRecordManager();
manager1.appId = 1; // アプリAのID
//検索条件を指定
manager1.query = '項目1 in ("①")'; // ドロップダウンのクエリ記法 //関数を変数(値)として活用する
const value = function (record) {
console.log(record);
return;
};
manager1.getRecords(value);

//アプリB読み取り
var manager2 = new KintoneRecordManager();
manager2.appId = 2; // アプリBのID
//検索条件を指定
manager2.query = '項目1 in ("①")'; // アプリAと同じ条件で検索
manager2.getRecords(value);
return event;
});
})();

console.log(record)を記載し、レコードの中身が配列で取れてくるのは確認できるのですが、

コールバック関数(関数を変数として扱う)を使用していることもあり、配列比較にまで持ち込むことが出来ません。スコープ・クロージャ・コールバック関数あたりの基本知識を確認しつつトライしていますが、苦戦しております。

ちなみに、以下のコードをベースにして比較・差分を求めていくつもりです。

const array1 = [1, 2, 3, 4, 5, 6];
const array2 = [1, 2, 3, 4];
array3 = array1.filter(i => array2.indexOf(i) == -1)
console.log(array3); // [5, 6]

以上、よろしくお願いいたします。

私もJavaScriptは初心者で、動作を試してないのですが。

getRecordsメソッドで取得したレコードにアクセスできないということで良いですか?

下記のようにクラスのインスタンスプロパティでアクセスできないでしょうか?

manager1.getRecords(value);
console.log(manager1.records);

Kazuhiro Yoshida

ありがとうございます。

私が提示したコード内にも既にそれは書かれておりまして、

console.log(manager1.records);

の部分は検証ツールですとundefinedと出てしまいます。

const valueで、コンソール出力するようコードを書いていますので、配列の中身は検証ツールで見れますが、

そもそも引数recordは

manager1.getRecords() のコールバック関数で使われる引数なので、

どうやって配列として取り出して、配列比較で扱うことができるのかがわからなくなっています。

書き方がわかりにくくてすみません。

 

kintone REST API Clientを使ってみるとかんたんに書けると思いますがいかがでしょうか?

目指せ!JavaScriptカスタマイズ中級者(4) 〜kintone REST API Client編〜

getAllRecordsというメソッドで全件取ってこれます。
2つのアプリのレコードを比較したいということでしたら、async/awaitで非同期処理するといいと思います。

 

julidon様

お世話になっております。

有益な回答ありがとうございます。

上記の記事、並びに非同期処理を用いてチャレンジしてみようと思います。

何かありましたらまたコメントいたします。

juridon様

お世話になっております。webpack, kintone REST API Clientの導入を行ったあとで、

以下、簡易的ではありますがこのようにして双方のレコードを全取得できました。

一旦こちらはクローズにいたします。ありがとうございました。

import { KintoneRestAPIClient } from "@kintone/rest-api-client";

const appID = 1; //レコードを取りたい他のアプリ(アプリ1とする)

const thisAppID = 2; //このアプリ(アプリ2とする)

const events = ["app.record.detail.show"]; //レコード一覧画面において、表示させるとする

kintone.events.on(events, async (event) => {

const client=new KintoneRestAPIClient(); // kintoneへ接続するためのインスタンスを作成

const res=await client.record.getAllRecords({ app:appID }); //アプリ1の配列を全取得

console.log(res);

const res2=await client.record.getAllRecords({ app:thisAppID }); //このアプリの配列を全取得

console.log(res2);

return event;

});

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。