一括登録(アプリ自身に)ボタンについて

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

一括で別のアプリに登録する

を応用したいですが、行き詰まっております。

項目を追加して、一年分のデータが登録したら、一覧画面でボタンをクリックし、同じアプリ内に来年度データの自動作成をしたいです。その際:

・年度=今の年度+1年 ;契約開始日:今の契約開始日+1年 ;残数⇒来年度の「前年残数」に反映される。

初心者のもので、どなたかコード作成の修正をご指導いただけますと幸いです。どうぞよろしくお願いいたします。

今作っているコード(コードを一つにまとめたいですが、できなくて、2個になっております・・・):

①契約終了日の自動計算

(function() {
"use strict";

kintone.events.on([
'app.record.create.show',
'app.record.edit.show',
'app.record.index.edit.show',
'app.record.detail.show',
'app.record.create.change.契約開始日',
'app.record.edit.change.契約開始日',
'app.record.create.change.契約期間',
'app.record.edit.change.契約期間'
], function(event) {
var record = event.record;
// フィールド制御
record['契約終了日']['disabled'] = true;

if(record['契約開始日'].value){
record['契約終了日'].value
= moment(record['契約開始日'].value)
.add(parseInt(record['契約期間'].value), 'year')
.subtract(1, 'day')
.format('YYYY-MM-DD');
}
// 契約年数が未定義になった時
if(!record['契約期間'].value){
record['契約終了日'].value = null;
}
return event;
});
})();

②一括登録ボタン

(function() {
‘use strict’;

kintone.events.on(‘app.record.index.show’, function(event) {
var records = event.records;
// ヘッダースペース要素の取得
var headerSpace = kintone.app.getHeaderMenuSpaceElement();
// ボタン要素の作成
var button = document.createElement(‘input’);
button.value = ‘一括登録’;
button.type = ‘button’;

// ボタンがクリックされた時の処理
var submit = function() {
// PUTするRecordsを用意する。
var put_records = [];
// レコード一覧のイベントで取得したレコードそれぞれに対して登録の処理を行う
records.forEach(function(data) {

var record = {

‘年度’: { ‘value’: parseInt(‘年度’, 10) - 1 },
‘残数’: { ‘value’:(typeof 残数 === “undefined”) ? 0 : parseInt(record[‘残数’].value) },
‘契約開始日’: { ‘value’:moment(‘契約開始日’).add(1, ‘year’).format(‘YYYY-MM-DD’)},
};
// レコードそれぞれに対して決定するフィールドを定義
record[‘顧客コード’] = data[‘顧客コード’];
record[‘契約NO’] = data[‘契約NO’];
record[‘支払方法’] = data[‘支払方法’];
record[‘商品’] = data[‘商品’];
record[‘数量’] = data[‘数量’];
record[‘単価’] = data[‘単価’];
record[‘年度’] = data[‘年度’];
record[‘前年残数’] = data[‘残数’];
//record[‘残数’] = data[‘残数’];
record[‘契約開始日’] = data[‘契約開始日’];
record[‘契約終了日’] = data[‘契約終了日’];

put_records.push(record);

});

var param = {
‘app’: 849,//このアプリ
‘records’: put_records
};

kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘POST’, param, function(resp) {
// success
alert(‘来年度へ登録成功しました。’);
console.log(resp);
}, function(error) {
// error
console.log(error);
});
};

// ボタンをヘッダースペースに追加
headerSpace.appendChild(button);
// ボタンのクリックイベントに処理を登録
button.onclick = submit;
});
})();

利絵 さん

> コードを一つにまとめたいですが、できなくて、2個になっております・・・

これについてですが、以下のように1つの js ファイルにイベントハンドラは2つ以上書くことができます。

(function() {
'use strict';

var event1 = [
'app.record.index.show',
'app.record.detail.show'
];
var event2 = [
'app.record.create.show',
'app.record.edit.show'
];

kintone.events.on(event1, function(event) {
});

kintone.events.on(event2, function(event) {
});

})();

 

肝心の処理についてですが、ぱっと見おかしそうな部分はなさそうです。
キチンとフィールドコードが設定できているか、など初歩的な部分を再確認してみて下さい。

問題なさそうな場合は以下の記事を参考にボタン押した際のデバッグをしてみてください。
デバッグの画面共有して頂ければもっと助言できるかと思います。

動かない?そんな時はデバッグをしてみよう!入門編
https://developer.cybozu.io/hc/ja/articles/207613916

HANSA 様

お世話になっております。ご指導いただき、誠にありがとうございます。

①コードを2つのままで、実行すると

ⅰ.「一括登録」で出来上がるレコードには「年度」が+1にならない。

ⅱ.「一括登録」で出来上がるレコードには「契約開始日」が+1にならない。

エラーは以下となっております。

ok をクリックすると

となっております。

②コードのまとめ方もご親切に教えていただき、ありがとうございます。今後まとめることができて、とても嬉しいです。

ただ、今回二つをまとめてみたら、以下のようにエラーになってしまっております・・

アプリを選択しただけとこの確認の画面が出てくる・・「OK」をクリックしたら以下のエラーとなります

 

全然知識ないので、コードは以下となっております。

(function() {
'use strict';

var event1 = [
// 'app.record.create.show',
//'app.record.edit.show',
'app.record.index.show'
];
var event2 = [
'app.record.create.show',
'app.record.edit.show',
'app.record.index.edit.show',
'app.record.detail.show',
'app.record.create.change.契約開始日',
'app.record.edit.change.契約開始日',
'app.record.create.change.契約期間',
'app.record.edit.change.契約期間'
];

kintone.events.on(event1, function(event) {

var records = event.records;
// ヘッダースペース要素の取得
var headerSpace = kintone.app.getHeaderMenuSpaceElement();
// ボタン要素の作成
var button = document.createElement('input');
button.value = '一括登録';
button.type = 'button';

// ボタンがクリックされた時の処理
var submit = function() {
// PUTするRecordsを用意する。
var put_records = [];
// レコード一覧のイベントで取得したレコードそれぞれに対して登録の処理を行う
records.forEach(function(data) {

var record = {
'年度': { 'value': parseInt('年度', 10) - 1 },
'残数': { 'value':(typeof 残数 === "undefined") ? 0 : parseInt(record['残数'].value) },
'契約開始日': { 'value':moment('契約開始日').add(1, 'year').format('YYYY-MM-DD')},
};
// レコードそれぞれに対して決定するフィールドを定義
record['顧客コード'] = data['顧客コード'];
record['契約NO'] = data['契約NO'];
record['支払方法'] = data['支払方法'];
record['商品'] = data['商品'];
record['数量'] = data['数量'];
record['単価'] = data['単価'];
record['年度'] = data['年度'];
record['前年残数'] = data['残数'];
record['契約開始日'] = data['契約開始日'];
record['契約終了日'] = data['契約終了日'];


put_records.push(record);

});

var param = {
'app': 849,//このアプリ
'records': put_records
};

kintone.api(kintone.api.url('/k/v1/records', true), 'POST', param, function(resp) {
// success
alert('来年度へ登録成功しました。');
console.log(resp);
}, function(error) {
// error
console.log(error);
});
};

// ボタンをヘッダースペースに追加
headerSpace.appendChild(button);
// ボタンのクリックイベントに処理を登録
button.onclick = submit;
});

});

kintone.events.on(event2, function(event) {

var record = event.record;
// フィールド制御
record['契約終了日']['disabled'] = true;

if(record['契約開始日'].value){
record['契約終了日'].value
= moment(record['契約開始日'].value)
.add(parseInt(record['契約期間'].value), 'year')
.subtract(1, 'day')
.format('YYYY-MM-DD');
}
// 契約年数が未定義になった時
if(!record['契約期間'].value){
record['契約終了日'].value = null;
}
return event;

})();

長々となってお忙しいところ大変申し訳ございません。お手すきなときに、ご指導いただければとても助かります。

どうぞよろしくお願い致します。

利絵 さん

初心者ということで知識がないことは仕方ないことかと思います。

スクショ添付ありがとうございます。
スクショ内に 利絵さんのドメイン名が出てしまっているので、削除していただいたほうが良いかもです。

①について

内容把握しました。

var record = {
'年度': { 'value': parseInt('年度', 10) - 1 },
'残数': { 'value':(typeof 残数 === "undefined") ? 0 : parseInt(record['残数'].value) },
'契約開始日': { 'value':moment('契約開始日').add(1, 'year').format('YYYY-MM-DD')},
};

↑の部分がちゃんとできていないですね。
parseInt() と momen() の使い方をよく勉強したほうが良いです。
parseInt() は 文字列を数値に変換してくれる関数です。

例えば↓ように使います。

var str = '10';
console.log(parseInt(str, 10)) // -> 10(数値型)

本来は「レコードの年度フィールドの値」を使用したいのだと思います。
ただ、 ‘年度’ はただの文字列 「年度」です。
レコードの年度フィールドの値を記載してください。

moment() についてもほぼ同様の考えです。

var datetime = '2019-06-01';
moment(datetime);

「レコードの契約開始日フィールドの値」を使用したいが、ただの ’契約開始日’ という文字列を使用してしまっています。

 

②について

1つにする方法を提示しましたが、無理にまとめる必要はないと思います。

エラー内容をよく読んでください。

今回は「{}」や「()」の位置がおかしいようです。

HANSA 様

お世話になっております。ご指導いただき、誠にありがとうございます。

(スクショ内に ドメイン名が出てしまっているとうっかりしてました・・削除しました。(汗))

その他もやっぱりちゃんと理解してない部分が多くて、お忙しいところお時間取らせてしまって申し訳ございませんでした。

色々と教えていただき本当にありがとうございます。粘って進めてみます。また行き詰まったら、どうかよろしくお願い致します。

利絵 さん

forEach 文内の data という変数に何が入っているのか確認すると良いと思います。

records.forEach(function(data) {
  console.log(data);
});

頑張ってください!

HANSA

お世話になっております。いつもご丁寧に教えていただき、本当にありがとうございます。

年度は数値型で、‘年度’: {‘value’: Number(record[‘年度’].value) + 1}, として実行したら、やっぱりタイプエラーというメッセージで動かなく・・・

(前にもこんなエラーがあって、それでrecord[‘年度’].value⇒’年度’のみにして、HANSAさんのご指摘通り、文字列になってしまったです。)

records.forEach(function(data) {
var nendu = Number(record[‘年度’].value);
var record = {
‘年度’: {‘value’: nendu + 1},

としてみてもvar nendu = Number(record[‘年度’].value);のところも同じエラーで、全然進まなくて・・

厚かましいとは存じますが、どうかアドバイスいただくことは可能でしょうか?

利絵 さん

画像の行数ベースで解説します。

まず、5行目に着目しましょう。

var records = event.records;

event オブジェクトにある、records プロパティの値を records という変数に格納しています。
event オブジェクトの中身は、 ‘app.record.index.show’ のイベントなので、以下の通りです。
https://developer.cybozu.io/hc/ja/articles/201941964#step1

次に18行目から始まる forEach 文についてです。
まずは以下の通り、console.log() で変数 data に何が入っているか確認してみてください。 

records.forEach(function(data) {
console.log(data)
})

forEach() は配列に対して使えるメソッドです。
配列1つ1つにアクセスしたいときに使えるものとなっています。
https://www.sejuku.net/blog/20257

例えば、以下のようなプログラムだと、forEach 文は配列の長さ分ループするので、
console は2回実行され、1回目は array[0]、2回目は array[1] が出力されます。

var array = [
{
prop1: 'value1',
prop2: 'value2'
},
{
prop1: 'value3',
prop2: 'value4'
}
]
array.forEach(function(data){
console.log(data)
});

ここまで理解頂いたところで、やりたいことを再確認します。
「レコードの年度フィールドの値」を使いたい。ので、どこにその値が保存されているのかはすぐにお分かりいただけるかと思います。

HANSA

お世話になっております。お返事ありがとうございます。いつもご丁寧に教えていただき、誠にありがとうございます。アドバイスを元に試してみたところ、無事期待通りの動作をしました。非常に助かりました。本当にありがとうございました。

 

 

利絵 さん

私のつたない説明で解決できたとのことで良かったです。
オブジェクト、配列の扱いは kintone カスタマイズ(JS)の学習において1つの壁なので、
是非これからも勉強してみて下さい!

HANSA 様

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

お陰様で「一括登録」の動きやオブジェクト、配列の勉強もできて、とても感謝しております。

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