レコードの一括更新

こんにちは

今現在レコードの一括更新プログラムを作成しております。

レコードの中身はこういう値が入っています。

残・有給・copyの値は別のアプリからとっていまして、

UPDATEボタンを押すと残・有給・copyの値が残・有給の値にコピーされます。

 

こちらのレコードが約100件ほどありまして、一人一人UPDATEボタンを押すのが面倒なので一括更新プログラムを作りたいのですが、可能でしょうか?また可能ならばどのようにすればよろしいでしょうか?

ご教授よろしくお願いします。

番匠 祐樹様

お世話になっております。 cstapの江田です。

一覧画面に一括更新ボタンを設置する実装は如何でしょうか?

(function(){"use strict";vargetRecords=function(app,tmpRecords){varlimit=500;vartmpRecords=tmpRecords||[];returnkintone.api(kintone.api.url('/k/v1/records',true),'GET',{app:app,query:'limit '+limit+' offset '+tmpRecords.length}).then(function(response){tmpRecords=tmpRecords.concat(response.records);returnresponse.records.length===limit?getRecords(app,tmpRecords):tmpRecords;});}varputRecords=function(app,records){varlimit=100;returnPromise.all(records.reduce(function(recordsBlocks,record){if(recordsBlocks[recordsBlocks.length-1].length===limit){recordsBlocks.push([record]);}else{recordsBlocks[recordsBlocks.length-1].push(record);}returnrecordsBlocks;},[[]]).map(function(recordsBlock){returnkintone.api(kintone.api.url('/k/v1/records',true),'PUT',{app:app,records:recordsBlock});}));}kintone.events.on('app.record.index.show',function(event){if(document.getElementById('updateButton')!==null)return;varbutton=document.createElement('button');button.innerHTML='一括更新';button.id='updateButton';kintone.app.getHeaderMenuSpaceElement().appendChild(button);button.addEventListener('click',function(){getRecords(kintone.app.getId()).then(function(records){putRecords(kintone.app.getId(),records.map(function(record){return{id:record.レコード番号.value,record:{残・有給のフィールドコード:{value:record.残・有給・copyのフィールドコード.value}}};})).then(function(){alert('更新しました。');location.reload();});});});returnevent;});})();

※レコード数制限なしにしました。

江田さま

 

お世話になります。

ご返信ありがとうございました。

こちら側にて返信させていただきます。

 

上記の方法で「残・有給のフィールドコード」⇒「金額」へ変更し実行しました。

実行をすると「更新しました」と出ますが実際には計算されていないようです。

何か理解に間違いがありますでしょうか?

 

(function() {

“use strict”;

kintone.events.on(‘app.record.index.show’, function(event){

varbutton=document.createElement(‘button’);

button.innerHTML=‘一括更新’;

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

button.addEventListener(‘click’, function(){

kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, {

app:kintone.app.getId(),

query:‘limit 500’

}).then(function(response){

kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, {

app:kintone.app.getId(),

records:response.records.map(function(record){

return {

id:record.レコード番号.value,

record: {

金額: {

value:record.金額.value

}

}

};

})

}).then(function(){

alert(‘更新しました。’);

location.reload();

});

});

});

returnevent;

});

})();

青山昌司様

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

上述していただいたコードでは、金額の値を金額の値で上書きすることになるので、更新されません。
valueには関連レコードをもとに計算した値を指定してください。

(function(){"use strict";vargetRecords=function(app,tmpRecords){varlimit=500;vartmpRecords=tmpRecords||[];returnkintone.api(kintone.api.url('/k/v1/records',true),'GET',{app:app,query:'limit '+limit+' offset '+tmpRecords.length}).then(function(response){tmpRecords=tmpRecords.concat(response.records);returnresponse.records.length===limit?getRecords(app,tmpRecords):tmpRecords;});}varputRecords=function(app,records){varlimit=100;returnPromise.all(records.reduce(function(recordsBlocks,record){if(recordsBlocks[recordsBlocks.length-1].length===limit){recordsBlocks.push([record]);}else{recordsBlocks[recordsBlocks.length-1].push(record);}returnrecordsBlocks;},[[]]).map(function(recordsBlock){returnkintone.api(kintone.api.url('/k/v1/records',true),'PUT',{app:app,records:recordsBlock});}));}kintone.events.on('app.record.index.show',function(event){if(document.getElementById('updateButton')!==null)return;varbutton=document.createElement('button');button.innerHTML='一括更新';button.id='updateButton';kintone.app.getHeaderMenuSpaceElement().appendChild(button);button.addEventListener('click',function(){Promise.all([getRecords(kintone.app.getId()),RelatedRecordsFieldManager.prototype.getFieldProperties()]).then(function(responses){returnPromise.all(responses[0].map(function(selfRecord){return(newRelatedRecordsFieldManager('案件一覧')).getRecords(selfRecord).then(function(relatedRecords){return{id:selfRecord.レコード番号.value,record:{金額:{value:relatedRecords.reduce(function(sum,relatedRecord){returnsum+Number(relatedRecord.合計費用.value);},0)}}};});}));}).then(function(records){putRecords(kintone.app.getId(),records).then(function(){alert('更新しました。');location.reload();});});});returnevent;});})();

江田さま

 

お世話になります。

上記の方法で値の更新ができました。

ありがとうございます。

更新確認できました。

違いを確認し学習したいと思います。

重ね重ねありがとうございました。

今後ともよろしくお願いいたします。

江田さま

 

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

下記の内容で更新ボタンを作成しましたが、更新ボタンを押すとエラーになってしまいます。

レコードは10,000件ほどあるのですが、原因がわかりますでしょうか?

ご教授いただければ幸いです。

 

 

関連レコード名:関連レコード

関連レコード内の集計したいフィールド:フラグ

数値フィールド:数値

 

 

(function() {

“use strict”;

vargetRecords=function(app, tmpRecords){

varlimit=500;

vartmpRecords=tmpRecords|| [];

returnkintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, {

app:app,

query:'limit ‘+limit+’ offset '+tmpRecords.length

}).then(function(response){

tmpRecords=tmpRecords.concat(response.records);

returnresponse.records.length===limit?getRecords(app, tmpRecords) :tmpRecords;

});

}

varputRecords=function(app, records){

varlimit=100;

returnPromise.all(

records.reduce(function(recordsBlocks, record){

if(recordsBlocks[recordsBlocks.length-1].length===limit){

recordsBlocks.push([record]);

}else{

recordsBlocks[recordsBlocks.length-1].push(record);

}

returnrecordsBlocks;

}, [[]]).map(function(recordsBlock){

returnkintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, {

app:app,

records:recordsBlock

});

})

);

}

kintone.events.on(‘app.record.index.show’, function(event){

if(document.getElementById(‘updateButton’) !==null) return;

varbutton=document.createElement(‘button’);

button.innerHTML=‘一括更新’;

button.id=‘updateButton’;

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

button.addEventListener(‘click’, function(){

Promise.all([

getRecords(kintone.app.getId()),

RelatedRecordsFieldManager.prototype.getFieldProperties()

]).then(function(responses){

returnPromise.all(responses[0].map(function(selfRecord){

return (newRelatedRecordsFieldManager(‘関連レコード’)).getRecords(selfRecord).then(function(relatedRecords){

return {

id:selfRecord.レコード番号.value,

record: {

フラグ: {

value:relatedRecords.reduce(function(sum, relatedRecord){

returnsum+Number(relatedRecord.数値.value);

}, 0)

}

}

};

});

}));

}).then(function(records){

putRecords(kintone.app.getId(), records).then(function(){

alert(‘更新しました。’);

location.reload();

});

});

});

returnevent;

});

})();

青山昌司様

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

https://qiita.com/t_konparu/items/01c9a6d9bfee119f578d

こちらの記事が参考になるかと思います。
「net::ERR_INSUFFICIENT_RESOURCES」は、ブラウザのメモリ上限を超えた場合に出るエラーのようです。
Firefoxなど、別のブラウザで試してみてはいかがでしょうか?

江田様

 

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

一覧画面にボタンを追加して更新を行っていますが、

件数が増えてくると時間がかかるようになってしまします。

表示している一覧のみ更新をするなんてことは可能でしょうか?

なにとぞご教示いただけますと幸いです。

 

よろしくお願いいたします。

青山昌司様

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

レコードをREST APIで取得せずに、eventオブジェクトのrecordsプロパティから取得すれば可能です。
https://developer.cybozu.io/hc/ja/articles/201941964#step1

江田篤史様

いつもお世話になっております。

ご返信ありがとうございます。可能との事で希望が見えました。

下記の箇所の変更が必要になるという理解であっておりますでしょうか?(太字の部分)

その場合、どのように変更してよいのか教えていただけますでしょうか。

甘えてばかりで大変恐縮ですがどうぞよろしくお願いいたします。

 

(function() {
"use strict";
var getRecords = function(app, tmpRecords){
var limit = 500;
var tmpRecords = tmpRecords || [];
 **return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {**
app: app,
query: 'limit ' + limit +' offset ' + tmpRecords.length
}).then(function(response){
tmpRecords = tmpRecords.concat(response.records);
return response.records.length === limit ? getRecords(app, tmpRecords) : tmpRecords;
});
}
var putRecords = function(app, records){
var limit = 100;
return Promise.all(
records.reduce(function(recordsBlocks, record){
if(recordsBlocks[recordsBlocks.length - 1].length === limit){
recordsBlocks.push([record]);
}else{
recordsBlocks[recordsBlocks.length - 1].push(record);
}
return recordsBlocks;
}, [[]]).map(function(recordsBlock){
**return kintone.api(kintone.api.url('/k/v1/records', true), 'PUT', {**
app: app,
records: recordsBlock
});
})
);
}

 

 

青山昌司様

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

動作確認はしておりませんが、下記のようになるかと思います。

(function() {
  "use strict";
  kintone.events.on('app.record.index.show', function(event){
    var oldButton = document.getElementById('updateButton');
    if(oldButton !== null){
      oldButton.parentNode.removeChild(oldButton);
    }
    var button = document.createElement('button');
    button.innerHTML = '一括更新';
    button.id = 'updateButton';
    kintone.app.getHeaderMenuSpaceElement().appendChild(button);
    button.addEventListener('click', function(){
      RelatedRecordsFieldManager.prototype.getFieldProperties().then(function(){
        return Promise.all(event.records.map(function(selfRecord){
          return (new RelatedRecordsFieldManager('案件一覧')).getRecords(selfRecord).then(function(relatedRecords){
            return {
              id: selfRecord.レコード番号.value,
              record: {
                金額: {
                  value: relatedRecords.reduce(function(sum, relatedRecord){
                    return sum + Number(relatedRecord.合計費用.value);
                  }, 0)
                }
              }
            };
          });
        }));
      }).then(function(records){
        kintone.api(kintone.api.url('/k/v1/records', true), 'PUT', {
          app: kintone.app.getId(),
          records: records
        }).then(function(){
          alert('更新しました。');
          location.reload();
        });
      });
    });
  });
})();

江田篤史様

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

ご教授いただきました方法で更新ができました。

取り急ぎデモ環境で更新ができていることを確認しました。

毎月中頃に一括更新するシーンがありますのでとても楽しみです。

ありがとうございました。

今後ともよろしくお願いいたします。

江田篤史様、

すみません。

全くの初心者です。

上記スレッド見て見様見真似でjavascriptを組んだのですがいまいち理解していなく、助けてほしいです。

やりたい事は一括ボタンを一覧で作成し、一括ボタンを押した際、(レコードコード:kaikake)および(レコードコード:urikake)を更新した後、(レコードコード:計算)を更新したいと考えております。

且つ、一覧で検索した(絞った)案件のみの更新を行いたいと思っております。

ご教示いただけると幸いです。

 

(function() {
“use strict”;
var getRecords = function(app, tmpRecords){
var limit = 500;
var tmpRecords = tmpRecords || [];
return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, {
app: app,
query: ‘limit ’ + limit +’ offset ’ + tmpRecords.length
}).then(function(response){
tmpRecords = tmpRecords.concat(response.records);
return response.records.length === limit ? getRecords(app, tmpRecords) : tmpRecords;
});
}
var putRecords = function(app, records){
var limit = 100;
return Promise.all(
records.reduce(function(recordsBlocks, record){
if(recordsBlocks[recordsBlocks.length - 1].length === limit){
recordsBlocks.push([record]);
}else{
recordsBlocks[recordsBlocks.length - 1].push(record);
}
return recordsBlocks;
}, [[]]).map(function(recordsBlock){
return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, {
app: app,
records: recordsBlock
});
})
);
}
kintone.events.on(‘app.record.index.show’, function(event){
if(document.getElementById(‘updateButton’) !== null) return;
var button = document.createElement(‘button’);
button.innerHTML = ‘売一括更新’;
button.id = ‘updateButton’;
kintone.app.getHeaderMenuSpaceElement().appendChild(button);
button.addEventListener(‘click’, function(){
getRecords(kintone.app.getId()).then(function(records){
putRecords(kintone.app.getId(), records.map(function(record){
return {
id: record.レコード番号.value,
record: {
urikake: {
kaikake: {
value: record.計算.value
}
}
}};
})).then(function(){
alert(‘更新しました。’);
location.reload();
});
});
});
return event;
});
})();

江田様

お世話になります。

以前ご対応いただきました下記の件でご質問がございます。

https://developer.cybozu.io/hc/ja/community/posts/360017977863/comments/360004431671

下記のようなエラーが出ることがしばしばあります。(出ないときもある。)

 

現在のコードは下記のとおりです。

お手すきな時にご確認いただければ幸いです。

よろしくお願いいたします。

 

(function() {
"use strict";
var getRecords = function(app, tmpRecords){
var limit = 500;
var tmpRecords = tmpRecords || [];
return kintone.api(kintone.api.url('/k/v1/records', true), 'GET', {
app: app,
query: 'limit ' + limit +' offset ' + tmpRecords.length
}).then(function(response){
tmpRecords = tmpRecords.concat(response.records);
return response.records.length === limit ? getRecords(app, tmpRecords) : tmpRecords;
});
}
var putRecords = function(app, records){
var limit = 100;
return Promise.all(
records.reduce(function(recordsBlocks, record){
if(recordsBlocks[recordsBlocks.length - 1].length === limit){
recordsBlocks.push([record]);
}else{
recordsBlocks[recordsBlocks.length - 1].push(record);
}
return recordsBlocks;
}, [[]]).map(function(recordsBlock){
return kintone.api(kintone.api.url('/k/v1/records', true), 'PUT', {
app: app,
records: recordsBlock
});
})
);
}
kintone.events.on('app.record.index.show', function(event){
if(document.getElementById('updateButton') !== null) return;
var button = document.createElement('button');
button.innerHTML = '一括更新';
button.id = 'updateButton';
kintone.app.getHeaderMenuSpaceElement().appendChild(button);
button.addEventListener('click', function(){
Promise.all([
getRecords(kintone.app.getId()),
RelatedRecordsFieldManager.prototype.getFieldProperties()
]).then(function(responses){
return Promise.all(responses[0].map(function(selfRecord){
return (new RelatedRecordsFieldManager('明細')).getRecords(selfRecord).then(function(relatedRecords){
return {
id: selfRecord.レコード番号.value,
record: {
粗利: {
value: relatedRecords.reduce(function(sum, relatedRecord){
return sum + Number(relatedRecord.金額.value);
}, 0)
}
}
};
});
}));
}).then(function(records){
putRecords(kintone.app.getId(), records).then(function(){
alert('更新しました。');
location.reload();
});
});
});
return event;
});
})();

青山昌司様

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

レコードの更新処理を同時に複数行っているため,エラーになるのかもしれません.
putRecords()を@kintone/rest-api-clientupdateAllRecords()に置き換えて試していただけますか?

上のコメントのJSコードより先に@kintone/rest-api-clientを読み込んでください.
https://js.cybozu.com/kintone-rest-api-client/1.4.0/KintoneRestAPIClient.min.js

また,上のコメントのJSコードを一部書き換えてください.

...
        putRecords(kintone.app.getId(), records).then(function(){
          alert('更新しました。');
          location.reload();
        });
...

...
        (new KintoneRestAPIClient()).record.updateAllRecords({
          app: kintone.app.getId(),
          records: records
        }).then(function(){
          alert('更新しました。');
          location.reload();
        });
...

江田篤史さま

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

ご返信ありがとうございます。

ご指摘の箇所の変更でエラーがなくなった?気がします。

今のところエラーは発生してません。

件数がそれなりにある更新なので大変助かっています。

記入サンプルも大変助かりました。

本当にありがとうございます。

今後ともよろしくお願いいたします。