500件を超えるフィールドの取得・更新について

お世話になります。

ボタン押下で500件以上あると想定される対象レコードを抽出し、

処理を繰り返すことで、更新を行いたいと考えております。

 

下記の通り記述いたしましたが、"length"が未定義であるとエラーが返されてしまいます。

初心者な質問で大変申し訳ございませんが、どのlengthにあたるかを

ご教示いただけないでしょうか。コンソール画面では、エラーが出てこない状態です。

一つ一つconsole.log()にて確認してみると、おそらくですが最後の

return fetchAllRecords(0,putRecords);で引っかかっているのではと考えております。

初心者な質問で大変申し訳ございませんが、何卒よろしくお願い申し上げます。

 

(function() {
“use strict”;
// レコード一覧画面
kintone.events.on([‘app.record.index.show’], function (event) {

if (document.getElementById(‘my_index_button’) !== null) {
return;
}

var myIndexButton = document.createElement(‘button’);
myIndexButton.id = ‘my_index_button’;
myIndexButton.innerHTML = ‘ルックアップ一括更新’;

// ボタンクリック時の処理
myIndexButton.onclick = function() {

var putRecords = {
“app” : kintone.app.getId(),
“records” : []
};

//更新したいレコードを取得
var params = {
app: kintone.app.getId(),
filterCond: “ルックアップ_0 = ""”, //ここにクエリ
fields: [‘$id’, ‘文字列__1行__4’ , ‘文字列_複数行_’] //ここに取得したいフィールド
};

getRecords(params).then(function(resp) {
//console.log(resp);
let putRecords = [];

var resp_record = resp.records;
for (var i = 0; i < resp_record.length; i++ ) {
let tagId = resp_record[i][‘文字列_複数行_’].value.slice(-10).replace(/[^0-9]/g, ‘’);
let lookUpNum = resp_record[i][‘文字列__1行__4’].value;

//console.log(resp_record);

let putRecord = {
“id”: resp_record[i][‘$id’].value,
“record” : {}
};

if (tagId) {
putRecord.record[‘ルックアップ_0’] = {
‘value’: tagId
};
}
if (lookUpNum) {
putRecord.record[‘ルックアップ_2’] = {
‘value’: lookUpNum
};
}

putRecords.push(putRecord);
}

console.log(getRecords);

return fetchAllRecords(0,putRecords);

}).then(function(resp2) {

// 処理成功
alert(‘更新しましたリロードします’);
location.reload(); // 成功したら画面を更新

}).catch(function(error) {

// エラー表示をする
alert(‘Error Occurred’ + error.message);
return error;

});

 

}

kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);

return event;

});

/*
* @param {Object} params
* - app {String}: アプリID(省略時は表示中アプリ)
* - filterCond {String}: 絞り込み条件
* - sortConds {Array}: ソート条件の配列
* - fields {Array}: 取得対象フィールドの配列
* @return {Object} response
* - records {Array}: 取得レコードの配列
*/
var getRecords = function(_params) {
var MAX_READ_LIMIT = 500;

var params = _params || {};
var app = params.app || kintone.app.getId();
var filterCond = params.filterCond;
var sortConds = params.sortConds || [‘$id asc’];
var fields = params.fields;
var data = params.data;

if (!data) {
data = {
records: [],
lastRecordId: 0
};
}

var conditions = [];
var limit = MAX_READ_LIMIT;
if (filterCond) {
conditions.push(filterCond);
}

conditions.push('$id > ’ + data.lastRecordId);

var sortCondsAndLimit =
’ order by ’ + sortConds.join(', ‘) + ’ limit ’ + limit;
var query = conditions.join(’ and ') + sortCondsAndLimit;
var body = {
app: app,
query: query
};

if (fields && fields.length > 0) {
// $id で並び替えを行うため、取得フィールドに「$id」フィールドが含まれていなければ追加します
if (fields.indexOf(‘$id’) <= -1) {
fields.push(‘$id’)
}
body.fields = fields;
}

return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, body).then(function(resp) {
data.records = data.records.concat(resp.records);
if (resp.records.length === limit) {
// 取得レコードの件数が limit と同じ場合は、未取得のレコードが残っている場合があるので、getRecords を再帰呼び出して、残りのレコードを取得します
data.lastRecordId = resp.records[resp.records.length - 1].$id.value;
return getRecords({ app:app, filterCond:filterCond, sortConds: sortConds, fields:fields, data:data });
}
delete data.lastRecordId;
return data;
});
};

//100件以上の更新
function fetchAllRecords(offset, put_records){
//let putrecords = put_records;

//offsetは、取得したデータの先頭からいくつスキップするかを表す
offset = offset || 0;

//kintone.apiでレコード取得するためのパラメータ
var params = {
“app” : kintone.app.getId(),
“records” : []
};
var t=0

//100件ずつのパラメータを作る(パラメータが100件以上ある場合PUTリクエストが停止するまたは弾かれるため)
if (put_records.records.length - offset > 100) {
for (var s = offset; s < offset+100; s++) {
t++;
params[“records”][t-1] = put_records[“records”][s];

}
}else if (put_records.records.length - offset < 100) {
for (var s = offset; s < put_records.records.length; s++) {
t++;
params[“records”][t-1] = put_records[“records”][s];

}

}

return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, params).then(function(put_resp){

allRecords.concat(put_resp);

//取得したレコード数が上限に達していれば再帰呼び出し
if(put_resp.records.length === 100){
return fetchAllRecords(offset + put_resp.records.length, put_records);
}else{
return event;
}

});

}
})();

湊 知央さん

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

「"length"が未定義である」というエラーはどこに出ますか?
「コンソール画面では、エラーが出てこない状態です。」ということなので、アラートなどでしょうか?

可能であれば、スクリーンショットなどを見せて頂きたいです。

江田篤史様

お世話になります。

スクリーンショットはこちらとなります。

アラート画面のところにエラーが返されているといった状態です。

まずは、コンソール画面に表示される状態にできればと考えております。

湊 知央さん

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

スクリーンショットありがとうございます。

}).catch(function (error) {
// エラー表示をする
alert('Error Occurred' + error.message);
return error;
});

でエラーハンドリングしているようですね。

そのcatchのコールバック関数内に、console.log(error)を記述すれば、どこのエラーかわかるかと思います。

江田篤史様

お世話になります。

早速試してみますと、下記のエラーが返されておりました。(黄色で色を付けた部分となります。)

Recordsの定義がおかしいのでしょうか。

湊 知央さん

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

はい、fetchAllRecords()の第2引数に指定しているputRecordsの構造が正しくないのかと思います。

putRecordsが普通の配列となってしまっていますが、fetchAllRecords()内での用法を見ると、recordsプロパティを持つ連想配列である必要があるかと思います。

江田篤史様

何でも聞いてしまい申し訳ありません。

putRecordsの連想配列なので、下記の部分を修正ということでよろしいでしょうか。

let putRecords = [];

var resp_record = resp.records;
for (var i = 0; i < resp_record.length; i++ ) {
let tagId = resp_record[i][‘文字列_複数行_’].value.slice(-10).replace(/[^0-9]/g, ‘’);
let lookUpNum = resp_record[i][‘文字列__1行__4’].value;

//console.log(resp_record);

let putRecord = {
“id”: resp_record[i][‘$id’].value,
“record” : {}
};

if (tagId) {
putRecord.record[‘ルックアップ_0’] = {
‘value’: tagId
};
}
if (lookUpNum) {
putRecord.record[‘ルックアップ_2’] = {
‘value’: lookUpNum
};
}

putRecords.push(putRecord);
}

湊 知央さん

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

はい、仰る通りです。

現状ですと、putRecordsを普通として作成して、putRecordをそのままpushしているかと思います。

putRecordsをrecordsプロパティを持つ連想配列として作成し、recordsにputRecordをpushすれば良いかと思います。

江田篤史様

お世話になります。

ご返信有難うございます。ご指摘いただきました通り連想配列とすることで動きました。

誠に有難うございます!下記に最終的なコードを記載いたします。

(function() {
“use strict”;
// レコード一覧画面
kintone.events.on([‘app.record.index.show’], function (event) {

if (document.getElementById(‘my_index_button’) !== null) {
return;
}

var myIndexButton = document.createElement(‘button’);
myIndexButton.id = ‘my_index_button’;
myIndexButton.innerHTML = ‘ルックアップ一括更新’;

// ボタンクリック時の処理
myIndexButton.onclick = function() {

var putRecords = {
“app” : kintone.app.getId(),
“records” : []
};

//更新したいレコードを取得
var params = {
app: kintone.app.getId(),
filterCond: “ルックアップ_0 = ""”, //ここにクエリ
fields: [‘$id’, ‘文字列__1行__4’ , ‘文字列_複数行_’] //ここに取得したいフィールド
};

getRecords(params).then(function(resp) {
console.log(resp);

var resp_record = resp.records;
for (var i = 0; i < resp_record.length; i++ ) {
let tagId = resp_record[i][‘文字列_複数行_’].value.slice(-10).replace(/[^0-9]/g, ‘’);
let lookUpNum = resp_record[i][‘文字列__1行__4’].value;

//console.log(resp_record);

putRecords[“records”][i] = {
“id”: resp_record[i][‘$id’].value,
“record” : {
‘ルックアップ_0’: {‘value’: tagId},
‘ルックアップ_2’: {‘value’: lookUpNum}
}

};

console.log(putRecords);

}

return fetchAllRecords(0,putRecords);

}).then(function(resp2) {

// 処理成功
alert(‘更新しましたリロードします’);
location.reload(); // 成功したら画面を更新

}).catch(function(error) {

// エラー表示をする
alert(‘Error Occurred’ + error.message);
return error;

});
}

kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);

return event;

});

/*
* @param {Object} params
* - app {String}: アプリID(省略時は表示中アプリ)
* - filterCond {String}: 絞り込み条件
* - sortConds {Array}: ソート条件の配列
* - fields {Array}: 取得対象フィールドの配列
* @return {Object} response
* - records {Array}: 取得レコードの配列
*/
var getRecords = function(_params) {
var MAX_READ_LIMIT = 500;

var params = _params || {};
var app = params.app || kintone.app.getId();
var filterCond = params.filterCond;
var sortConds = params.sortConds || [‘$id asc’];
var fields = params.fields;
var data = params.data;

if (!data) {
data = {
records: [],
lastRecordId: 0
};
}

var conditions = [];
var limit = MAX_READ_LIMIT;
if (filterCond) {
conditions.push(filterCond);
}

conditions.push('$id > ’ + data.lastRecordId);

var sortCondsAndLimit =
’ order by ’ + sortConds.join(', ‘) + ’ limit ’ + limit;
var query = conditions.join(’ and ') + sortCondsAndLimit;
var body = {
app: app,
query: query
};

if (fields && fields.length > 0) {
// $id で並び替えを行うため、取得フィールドに「$id」フィールドが含まれていなければ追加します
if (fields.indexOf(‘$id’) <= -1) {
fields.push(‘$id’)
}
body.fields = fields;
}

return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, body).then(function(r) {
data.records = data.records.concat(r.records);
if (r.records.length === limit) {
// 取得レコードの件数が limit と同じ場合は、未取得のレコードが残っている場合があるので、getRecords を再帰呼び出して、残りのレコードを取得します
data.lastRecordId = r.records[r.records.length - 1].$id.value;
return getRecords({ app:app, filterCond:filterCond, sortConds: sortConds, fields:fields, data:data });
}
delete data.lastRecordId;
return data;
});
};

//100件以上の更新
function fetchAllRecords(offset, put_records){

//offsetは、取得したデータの先頭からいくつスキップするかを表す
offset = offset || 0;

//kintone.apiでレコード取得するためのパラメータ
var params = {
“app” : kintone.app.getId(),
“records” : []
};
var t=0

//100件ずつのパラメータを作る(パラメータが100件以上ある場合PUTリクエストが停止するまたは弾かれるため)
if (put_records.records.length - offset > 100) {
for (var s = offset; s < offset+100; s++) {
t++;
params[“records”][t-1] = put_records[“records”][s];

}
}else if (put_records.records.length - offset < 100) {
for (var s = offset; s < put_records.records.length; s++) {
t++;
params[“records”][t-1] = put_records[“records”][s];

}

}

return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, params).then(function(put_resp){

//allRecords.concat(put_resp);

//取得したレコード数が上限に達していれば再帰呼び出し
if(put_resp.records.length === 100){
return fetchAllRecords(offset + put_resp.records.length, put_records);
}else{
return event;
}

});

}
})();

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