日時フィールドの時刻を時刻フィールドに設定したい

ご教授ください!プログラミング初心者です。

ある月の時間帯別の呼数を集計をしようとして、日時フィールドでは時間帯ごとの集計ができないことがわかりました。

すでに数か月当該アプリを利用してもらっているため、フィールドの変更はできません。

日時フィールドから時刻を取り出して時刻フィールドに設定する方法を教えていただければ幸いです。どうかよろしくお願いします。

yuiさん、こんにちは。

すでにレコードがいくつか登録されているという状況ですね。

であれば、ファイル出力/ファイル入力を使って、以下の方法でデータを投入できると思います。

不安であれば、テスト用アプリを作って試してみてください。

  1. 既存レコードのデータをCSVで書き出し
  2. Excel等で、日時データの列から、時刻列を作成し、CSVファイル保存
    レコード番号、時刻 だけのCSVでいいと思います。
  3. 既存レコードを更新(レコード番号を更新キー)

Matshuda 様

早速のご回答、ありがとうございます。

既存レコードは数千件に上るので途方に暮れていました。ご教授のとおり、CSVの出力→編集(※時刻フィールド列の作成)→読み込みで対応いたします。

これから入力されるレコードなのですが、カスタマイズで日時のフィールドから時刻を取り出して、上記の※時刻フィールド列に入れたいのですが、方法を教えていただければ助かります。

yui さん

こんにちは!

日時フィールドの時刻だけを時刻フィールドに設定、という認識でよかったでしょうか。

 

既に時刻フィールドを配置済みであれば、以下のような処理で一括更新させるのはいかがでしょうか。

コチラを参考に、処理を記述してみました。

見苦しいコードになってるかもしれませんが、参考になれば嬉しいです。

 

※ moment.js を利用してます。

※ アプリのフィールドのフィールドコードはそれぞれ以下のようになってます。

     ・ 日時フィールド : re

     ・ 時刻フィールド : time

(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: {
time: {
value: moment(record.re.value).utc().format('HH:mm')
}
}
};
})).then(function(){
alert('更新しました。');
location.reload();
});
});
});
return event;
});
})();

 

yui さん

 

日時フィールドの changeイベントで時刻フィールドに値を設定する対応は

いかがでしょうか。以下のコードで実装できますよ!

参考になればうれしいです。

 

※ CSVファイルでデータを更新する場合もあるのかなと思い、

    一括更新の処理はそのままに、change の処理を追記したものになります。

(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: {
time: {
value: moment(record.re.value).utc().format('HH:mm')
}
}
};
})).then(function(){
alert('更新しました。');
location.reload();
});
});
});
return event;
});

kintone.events.on(['app.record.create.change.re', 'app.record.edit.change.re', 'app.record.index.edit.change.re'], function(event){

var record = event.record;
record.time.value = moment(record.re.value).utc().format('HH:mm');

return event;
});


})();

 

文系男

大変ご丁寧なご回答、本当にありがとうございました。

早速、先にいただきましたコードでトライしておりました。

結果、私の環境では添付のようなエラー?が表示されまして、原因の検討がつかず、途方にくれておりました。

大変恐縮ですが、原因を教えていただけないでしょうか?

 

yui さん

 

恐らく、moment.js が読み込まれていないのではないかな、と思われます!

以下の手順で、moment.js を読み込ませてみてどうか、お試しください。

 

  1. 日時フィールドテスト0820アプリの設定画面を開きます

2.「JavaScript/CSSでカスタマイズ」をクリックします

3.「URL指定で追加」をクリックし、以下の URL をコピーアンドペーストで貼り付け、入力欄右側の「保存」をクリックします

     ・ https://js.cybozu.com/momentjs/2.24.0/moment.min.js

     ・ https://js.cybozu.com/momentjs/2.24.0/moment-with-locales.min.js

     ※ 3 を繰り返して、上記 2つの URL それぞれを追加してください。

  1. 3 で追加した各URL の左側の「▲▼」のアイコンをドラッグアンドドロップで上側に持っていきます。

     ※ “日時の時刻を時刻フィールドにコピー.js” の上側に配置してください。

  1. 左上の「保存」をクリックします

  2. アプリを更新します

ちなみに、開発者ツールの「Source」タブだとエラーの詳細が確認できないので、

正常に動作していない場合は、「Console」タブを開いて、何かエラーが出ていないか、

確認の上、よくわからない場合は、その画像をこちらに添付していただけると助かります。

文系男さま

ご指摘どおり、moment.jsを追加して実行しましたところ、添付のような結果になりました。

-9時間って、日本時間とUTC?の時差ってらしいのですが、対処の仕方を教えていただけないでしょうか?

何から何までお手数かけて申し訳ありません。

yuiさん、こんにちは。

既存レコードのデータ移行を、ファイル操作で終わっていると仮定して、

今後追加・編集されるレコードについては、以下のようなカスタマイズを入れておけばいいと思います。

一括更新については、日常的に使うのであればJavaScriptカスタマイズを入れてもいいと思いますが、

最初に投入するだけであれば、カスタマイズは最小限にしておくことをおススメします。

 

サンプル:

※「日時」フィールドからデータをmoment.jsで取り出し、フォーマット変換(24時間表示のHH:mm)して時刻フィールドに更新

(function () {
"use strict";
kintone.events.on([
"app.record.create.show",
"app.record.create.change.日時",
"app.record.edit.change.日時"
], function (event) {
moment.locale('ja');
let record = event.record;
record['時刻']['value'] = moment(record['日時']['value']).format('HH:mm');
return event;
});
})();

yui さん

 

ごめんなさい。

私の環境で UTC になってたのでそのまま利用していました。

 

以下のコードに書き直してみて、いかがでしょうか。

 

(function() {
"use strict";
moment.locale('ja');

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: {
time: {
value: moment(record.re.value).format('HH:mm')
}
}
};
})).then(function(){
alert('更新しました。');
location.reload();
});
});
});
return event;
});

kintone.events.on(['app.record.create.change.re', 'app.record.edit.change.re', 'app.record.index.edit.change.re'], function(event){

var rec = event.record;
rec.time.value = moment(rec.re.value).format('HH:mm');

return event;
});


})();

 

文系男

一括更新できました!

うれしかったので結果を添付します

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

yui さん

 

良かったです!

お役に立てたようで、私も嬉しく存じます!^^

 

ちなみに、レコードの登録、編集、レコード一覧画面上でのインライン編集の際、

日時フィールドで時刻を設定した際、別の時刻フィールドの値も連動する動きについても、

問題なく動作しておりますでしょうか??

 

差支えなければ、そちらの動作も念のため、確認していただけると幸いです。

文系男 さま

登録、編集、一覧画面での編集、問題なく動作することを確認いたしました。

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

 

yui さん

 

問題なく動作したとのこと、承知しました!

良かったです!^^

Matshuda 様

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

一括更新の処理がないと、こんなにシンプルになるんですね。

日時データの操作の基本を教えていただき、助かります。

応用していろいろ使わせていただきます。

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