お世話になります。
サブテーブルに新しいレコードを持たせる作業を全レコードに対して一括で行いたいのですが、良い方法はありますでしょうか。
レコードを追加させる際に初期値として別フォームの値を持たせたいです。
具体的には年に1回マスタを更新したいのですが、年度ごとにサブテーブルで持っているため、手動で追加するのが手間です。
下記のようにjsで追加しようとしたのですが、テーブル自体が行追加ではなく、リメイク動作をしてしまいます(元あったデータが削除されて新たに作り直される)
(function() {
"use strict";
kintone.events.on("app.record.index.show", function(event) {
if (document.getElementById('my_4_button') !== null) {
return;
}
var myIndexButton = document.createElement('button');
myIndexButton.id = 'my_4_button';
myIndexButton.innerHTML = 'table';
//ボタンクリック後の処理
myIndexButton.onclick = function() {
var appId = kintone.app.getId();
var param = {
app: appId,
query: '',
fields: ['$id', '有給用', '有給年度'],
totalCount: true,
isGuest: false
};
kintoneUtility.rest.getAllRecordsByQuery(param).then(function(resp) {
/////////空更新オブジェクトの生成
var param = {
"app": appId,
"records": [],
isGuest: false
};
//レコード更新
resp.records.forEach(function(record) {
var newRow1 = {};
newRow1 = {
value: {
'有給年度': { value: 2022 },
}
}
param.records.push({
"id": record.$id.value,
"record": {
'有給用': {
value: [
newRow1
]
}
}
});
});
kintoneUtility.rest.putAllRecords(param).then(function(resp) {
//success
console.log(resp);
}, function(error) {
//error
console.log(param);
console.log(error);
});
});
}
kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);
return event;
});
})();
テーブルのデータを作り直さずに更新する方法をお答えします。
サブレコード行の値を更新する時は、行ごとに付与されているIDを使用します。
下図のサブテーブルの場合、
データ構造は以下のようになっています。
レコード作成前 (kintone の仕様として必ず1行存在する)
[
{
"id": null,
"value": {
"有給年度": {
"type": "NUMBER"
}
}
}
]
レコード作成後
[
{
"id": "34077",
"value": {
"有給年度": {
"type": "NUMBER",
"value": "2022"
}
}
}
]
このような構造のため、ADMさんのコードはIDを指定していないことから、データを破棄して新たな行を作成するという挙動になっています。
既存の行を更新する場合は、下記のようにIDを指定すれば解決します。
newRow1 = {
id: targetRowId, // 更新対象の行のIDを設定する
value: {
'有給年度': { value: 2022 },
}
}
また、サブテーブルに行を追加する場合は、既存の行を含める必要があります。
param.records.push({
"id": record.$id.value,
"record": {
'有給用': {
value: [
{ id: firstRowId }, // 値に変更がなければ、IDのみを指定すればOK
newRow1
]
}
}
});
以上になります。
川村様
ご教示いただきありがとうございます。
頂いた内容を反映させてみました。
既存のテーブル2行が1行となり全て空白、その下に今回の追加分が挿入されていました。想定では既存のレコード2行は残ったまま今回の追加分が挿入されて3行になる想定でした。
何か指定を間違えていますでしょうか
(function() {
"use strict";
kintone.events.on("app.record.index.show", function(event) {
if (document.getElementById('my_4_button') !== null) {
return;
}
var myIndexButton = document.createElement('button');
myIndexButton.id = 'my_4_button';
myIndexButton.innerHTML = '年次処理';
//ボタンクリック後の処理
myIndexButton.onclick = function() {
var appId = kintone.app.getId();
var param = {
app: appId,
query: '',
fields: ['$id', '有給用', '有給年度','前残'],
totalCount: true,
isGuest: false
};
kintoneUtility.rest.getAllRecordsByQuery(param).then(function(resp) {
/////////空更新オブジェクトの生成
var param = {
"app": appId,
"records": [],
isGuest: false
};
//レコード更新
resp.records.forEach(function(record) {
var newRow1 = {};
var targetRowId = {};
var firstRowId = {};
newRow1 = {
$id: targetRowId, // 更新対象の行のIDを設定する
value: {
'有給年度': { value: 2022 },
}
}
param.records.push({
"id": record.$id.value,
"record": {
'有給用': {
value: [
{ $id: firstRowId }, // 値に変更がなければ、IDのみを指定すればOK
newRow1
]
}
}
});
});
kintoneUtility.rest.putAllRecords(param).then(function(resp) {
//success
console.log(resp);
}, function(error) {
//error
console.log(param);
console.log(error);
});
});
}
kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);
return event;
});
})();
ADMさん
私が書いたコード内の変数(targetRowId, firstRowId)は一例ですので、ADMさんのコードの場合は、下記のようにIDを指定すれば再作成にはならず、デフォルトの行(1行目)を更新できます。
var newRow1 = {
id: record.有給用.value[0].id,
value: {
'有給年度': { value: 2022 },
}
}
param.records.push({
"id": record.$id.value,
"record": {
'有給用': {
value: [
newRow1
]
}
}
});
2行以上ある場合はこの記述だとサブテーブルの値を上書きしてしまうので、更新するデータ(param.records)に既存の行を含めてみてください。
実装上で不明な点がありましたら、お気軽にご質問ください。
川村様
度々ありがとうございます。
更新の必要がなく、追加のみが前提だとすると記述は変わってきますでしょうか。
最低1行は既に入っており、最終行に1行を追加する想定です。
最初にお伝えすればよかったですが、前後して申し訳ございません。
1つ問題なのは、テーブル内の行数はレコードによってバラバラで1行のときもあれば5行の時もあったりします。
そのため2行目に追加するのか、6行目に追加するのかが固定できません。
ADMさん
それでは質問内容を下記と理解した上で、コードの一例で回答します。
-
デフォルトの1行(値は未設定)が存在する場合は、その行に値を設定する
-
値が設定されている行が存在する場合は、新たに行を追加する
resp.records.forEach(function (record) {
var oldRows = record.有給用.value;
var newRow = { value: { 有給年度: { value: '2022' } } };
var newRows = [];
if (oldRows.length === 1 && !oldRows[0].value.有給年度.value) {
// デフォルトの行が未入力の場合、値を設定して更新(行内の他のフィールドも判定が必要な場合は条件に追加)
newRow.id = oldRows[0].id;
} else {
// 既存の行は更新しないためIDのみ取り出す、通信量・パフォーマンスを気にしなければ newRows = oldRows でも可
newRows = oldRows.map(function (row) {
return { id: row.id };
});
}
newRows.push(newRow);
param.records.push({
id: record.$id.value,
record: {
有給用: {
value: newRows,
},
},
});
});
以上になります。既に設定したい値が存在する場合の処理は考慮していませんが、参考になれば幸いです。
>>川村様
ありがとうございます。
想定通りの動きになりました。今回の件、とても勉強になりました。感謝いたします。
今後のために知りたいのですが、今回は有給年度を「2022」固定としましたが、別フィールドから持ってくる場合は、
varnewRow = { value: { 有給年度: { value:'2022'} } };
この部分のvalue:以降をレコードフィールド指定で問題ありませんでしょうか。
今後は年度の他にも前年度残数等を持ってきたいと考えています。
system
(system)
クローズされました:
9
このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。