レコード詳細画面・一覧表示画面でのフィールド値変更が定着しない

お世話になります。初めて投稿させていただきます。

現在、kintoneのカスタマイズを進めている最中ですが,タイトルのことで困っております。

顧客の基本情報を管理するアプリで、レコード詳細画面もしくは一覧表示した際に生年月日フィールドより年齢を自動算出するプログラムを作成しています(Webに公開されているプログラムを利用させていただいております)。

参照サイト:http://www.messiahworks.com/archives/4554

自動計算自体には成功しておりますが,レコード編集画面を開くと値は消えてしまいます。また,他のアプリからルックアップで年齢を呼び出そうとしても表示されません。

目標は,自動算出された年齢をフィールドに定着させることです。

皆様のご助言のほどどうぞよろしくお願いいたします。

 

// 20140813 kintone用javascript作成
// 生年月日(日付フィールド)から、年齢を計算する
// 以下のサンプルコードだと、うるう年を考えていないので自作した
// https://cybozudev.zendesk.com/hc/ja/articles/202640900-%E7%B5%8C%E9%81%8E%E5%B9%B4%E6%95%B0%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B

(function() {

    // 生年月日が入っているフィールドコード名
    const AGE = ‘agec’;
  const BIRTHYEAR = ‘year’;
    const BIRTHMONTH = ‘month’;
    const BIRTHDAY = ‘day’;

    “use strict”;

    // 現在の年齢計算する関数
    function getYearMonth(year, month, day) {

        //本日の日付を取得
        var today=new Date();

        // 肝心の年齢計算について
        // 年月日の日は、そのまま引き算。
        // 年月日の月は、2ケタ左シフトして(100倍にする。1月は0なので+100からスタート)から、引き算。
        // 年月日の年は、4ケタ左シフトして(1万倍にする)から、引き算。
        // この計算方法の優れた所は、年・月・日を単独で計算して、足らなかったら上位からマイナスするという点!
        // 単純ながら、確実な年齢計算が出来る優れたアルゴリズムです!
        // ちなみに日数計算はできません。あくまで年数計算のみ
        // 参照URL:http://d.hatena.ne.jp/toku-hiro/20070824
        today=today.getFullYear()*10000+today.getMonth()*100+100+today.getDate();

        // 生年月日一列に
        var birthday=parseInt(year + month + day);

        // 単純に引き算して、下4ケタを切り捨てて、年部分だけを返す
        return(Math.floor((today-birthday)/10000));

    }

    // レコード詳細表示
    kintone.events.on([‘app.record.detail.show’], function (event) {

        var record = event.record; // 保存前の画面上のレコード
    //関数で計算
        var valBirthday = getYearMonth(record[BIRTHYEAR][‘value’], record[BIRTHMONTH][‘value’], record[BIRTHDAY][‘value’]);
        // 年齢
      var emBirthDay = kintone.app.record.getFieldElement(AGE);
        emBirthDay.innerHTML = valBirthday;

        return event;
    });

    // レコード一覧表示
    kintone.events.on([‘app.record.index.show’], function (event) {

        // レコード配列をローカル変数に格納
        var records = event.records;

        var emBirthDay = kintone.app.getFieldElements(AGE);

        // レコード数の分だけループ
        for (var i = 0; i < records.length; i++) {
            var record = records[i];

            // 生年・生月・生日値の取得
            var record_data_1 = record[BIRTHYEAR][‘value’];
            var record_data_2 = record[BIRTHMONTH][‘value’];
            var record_data_3 = record[BIRTHDAY][‘value’];

            // DOM要素の取得し、年齢を追加
            var part = emBirthDay[i];
            part.innerHTML = getYearMonth(record_data_1,record_data_2,record_data_3);

        }
        return event;
    });

})();

Hiroさん

 

こんにちは。コードを見てみると、innerTextで追加されていますね。

innerTextだと、HTMLの表示だけ変えるので実際のレコードのデータは変わりません。

すべての画面で表示したいということでしたら、以下4つのイベントでinnerTextする必要があります。

  1. レコード表示イベント
  2. レコード編集イベント
  3. レコード一覧画面の表示後イベント
  4. レコード一覧画面のインライン編集開始時イベント

 

それ以外の方法としては、レコード作成時に年齢フィールドに自動で年齢を設定する方法もあります。

欠点として、レコード保存時の年齢が保存されてしまうため、1年以上更新をしないと年齢が合わなくなってきます。

 

レコード作成時に年齢フィールドに自動で年齢を設定 するコードのサンプルを貼っておきますのでご確認ください。

(function() {

  "use strict";

  // 生年月日が入っているフィールドコード名
  var AGE = 'agec';
  var BIRTHYEAR = 'year';
  var BIRTHMONTH = 'month';
  var BIRTHDAY = 'day';

  // 現在の年齢計算する関数
  function getYearMonth(year, month, day) {

    //本日の日付を取得
    var today = new Date();

    // 肝心の年齢計算について
    // 年月日の日は、そのまま引き算。
    // 年月日の月は、2ケタ左シフトして(100倍にする。1月は0なので+100からスタート)から、引き算。
    // 年月日の年は、4ケタ左シフトして(1万倍にする)から、引き算。
    // この計算方法の優れた所は、年・月・日を単独で計算して、足らなかったら上位からマイナスするという点!
    // 単純ながら、確実な年齢計算が出来る優れたアルゴリズムです!
    // ちなみに日数計算はできません。あくまで年数計算のみ
    // 参照URL:http://d.hatena.ne.jp/toku-hiro/20070824
    today = today.getFullYear() * 10000 + today.getMonth() * 100 + 100 + today.getDate();

    // 生年月日一列に
    var birthday = parseInt(year + month + day);

    // 単純に引き算して、下4ケタを切り捨てて、年部分だけを返す
    return (Math.floor((today - birthday) / 10000));
  }

  // レコード保存前イベント
  kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {

    // 保存前の画面上のレコード
    var record = event.record;
    // 関数で計算
    var valBirthday = getYearMonth(record[BIRTHYEAR]['value'], record[BIRTHMONTH]['value'], record[BIRTHDAY]['value']);
    // 年齢フィールドに値をセット
    record[AGE].value = valBirthday;

    return event;
  });

}());

 

カキ氷様

コメントありがとうございます!

やはりinnerHTMLがいけなかったのですね…。

そこではないかと考え,試行錯誤しておりましたが,ご教授いただいた,

record[AGE].value = valBirthday; の書き方で問題が解決しました。

自分で調べてみて

record[AGE][value] = valBirthday; という方法でやってみたのですが,

表示されず困っておりました。

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

申し訳ありません。

やはり表示できておりませんでした…。

目標は”レコード値の更新”です。

現在色々調べておりますが,皆様のお知恵をお借りできれば幸いです。

Hiroさん

 

上記のコードではレコード保存(新規追加、編集)時のイベントで処理を行っています。 開発中のコードで他のイベントが設定されてないか確認いただけるでしょうか。

 

↓この部分です

  // レコード保存前イベント
  kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {

 

カキ氷様

 

たびたびお教えいただきありがとうございます。

下記URLのものも参照しましたが,レコードの詳細表示や一覧表示ではレコードの更新はできないのですね…。

https://cybozudev.zendesk.com/hc/ja/community/posts/202311534-%E8%A9%B3%E7%B4%B0%E7%94%BB%E9%9D%A2%E8%A1%A8%E7%A4%BA%E6%99%82%E3%81%AE%E9%A0%85%E7%9B%AE%E6%9B%B4%E6%96%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

カキ氷様がおっしゃるようにレコード保存時のイベントで記入すると,できました。

ありがとうございます。

素人考えでkintoneを開くと年齢が自動更新されるといいな…なんて考えております。

現在は下記のページを参考に何らかのアクション(ボタンなど)をすると一斉更新ががかるカスタマイズをしたいと考えております。

https://kintoneapp.com/blog/lookup_improvement/

Hiroさん

 

ひとまず保存時のほうが成功したようでよかったです。

一覧画面や詳細画面でやる場合、はRestAPIを使うことになります。①レコードを取得をして②年齢計算を行い③レコードを更新する流れです。

いきなり一覧画面は難しいと思うので、まずは詳細画面上で、1レコードのみを対象としてレコード取得と更新を試してみることをおすすめします。

カキ氷様

ありがとうございます。

挑戦してみます。

また、進捗報告させていただければと思います。

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

その後の進捗報告です。

下記コードにて,一覧画面で”年齢一括更新”というボタンを押した際に年齢を計算し,更新することができました。

ただ,一覧に表示されている20レコードくらいしか更新できていないので,全レコード一括更新をできる処理を目指したいと思います。

 

(function() {

“use strict”;
kintone.events.on(‘app.record.index.show’, function(event) {

//eventオブジェクトのプロパティでレコードID、レコード情報取得
  var records = event.records;
  var appId = kintone.app.getId();

// メニュ右側の空白部分にボタンを設置
var MenuButton = document.createElement(‘button’);
//ボタンのID指定
MenuButton.id = ‘Menu_Button’;
//ボタン名表示
MenuButton.innerHTML = ‘年齢一括更新’;
//ボタンサイズ
MenuButton.style.width = ‘200px’;
//左側のスペース
MenuButton.style.marginLeft = ‘250px’;
//ボタンをクリックしたら
MenuButton.onclick = function () {

//レコードの数取得
var resplen = event.records.length;

//書き換え用
var params = {
  “app” : appId,
  “records” : []
};
// レコード番号を繰り返しアラート表示
for (var i=0; i < resplen ; i+=1){

//レコード番号を取得
var recno = event.records[i].レコード番号.value;
//フィールドから生年を取得
var nen = event.records[i].year.value;
//フィールドから生月を取得
var tuki = event.records[i].month.value;
//フィールドから生日を取得
var nichi = event.records[i].day.value;

//関数で計算
var valBirthday = getYearMonth(nen,tuki,nichi);

//アラートで表示
//window.alert(valBirthday);

params[“records”][i] = {
  “id” : recno,
  “record” : {
    “agec” : {
      “value” : valBirthday
    }
  }
};

} //for終了

//////////////////////////////////////////////////////////////////////////////

kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘PUT’, params).then(function(resp) {
// 成功時
alert(“更新成功”);
location.reload(); // 成功したら画面を更新
}, function(resp) {
// 失敗時
alert(“更新失敗”);
});

}; //onclickイベント終了

 //showイベント終了

//////////////////////////////////////////////////////////////////////////////
// 現在の年齢計算する関数
function getYearMonth(year, month, day) {

  //本日の日付を取得
  var today=new Date();

  // 肝心の年齢計算について
  // 年月日の日は、そのまま引き算。
  // 年月日の月は、2ケタ左シフトして(100倍にする。1月は0なので+100からスタート)から、引き算。
  // 年月日の年は、4ケタ左シフトして(1万倍にする)から、引き算。
  // この計算方法の優れた所は、年・月・日を単独で計算して、足らなかったら上位からマイナスするという点!
  // 単純ながら、確実な年齢計算が出来る優れたアルゴリズムです!
  // ちなみに日数計算はできません。あくまで年数計算のみ
  // 参照URL:http://d.hatena.ne.jp/toku-hiro/20070824
  today=today.getFullYear()*10000+today.getMonth()*100+100+today.getDate();

  // 生年月日一列に
  var birthday=parseInt(year + month + day);

  // 単純に引き算して、下4ケタを切り捨てて、年部分だけを返す
  return(Math.floor((today-birthday)/10000));

}

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

})

})();

4100件のレコードを作り、       
Hiroさんの「その後の進捗報告です。」以下にある、jsコードを試してみました。       
       
//レコードの数取得       
var resplen = event.records.length;       
       
この「resplen」の値は「100」でした。       
※これは、アプリ1画面に表示されているレコード数です。       
       
当方のアプリのヘッダー部分のレコード件数表示エリアには、次のように表示されています。       
       
 1 - 100 (4100件中)(件数を表示)      

その後、ボタンをクリックして、レコードの更新処理を行い、"更新成功"となりました。      
      
更新後のレコードの一覧表示は次のようになり、Hiroさんのご報告通り、      
「20レコードくらいしか更新できていない」ことが確認できました。      
※ちょうど21件目のレコードから、「年齢を計算」の数値が正しくなくなりました。

それで、その理由を調べたところ、      
当方のこの例では、ちょうど21件目のレコードから、生年月日が、      
10月から9月になり、      
  var birthday=parseInt(nen + tuki + nichi);       
parseIntした値が「1880910」となっていました。      
※10月までは「18801010」など、8桁の整数でした。      
      
今日の日付は、下記のソースコードにより、「20170214」と8桁の整数となっています。      
  today=today.getFullYear()*10000+today.getMonth()*100+100+today.getDate();   
      
そこで、この点を修正し、9月の生年月日でも、「18800910」などと、8桁の整数に      
なるように補正したところ、100件のレコードがすべて、正しく、更新されました。

[結論] 当方のアプリ実施結果が、Hiroさんのアプリと同じかどうか分かりませんが、   
 一桁の数字の「月」の問題がなければ、   
 Hiroさんのご提示いただいた、jsソースコードで、20件程度に限らず、   
 全件(この場合1画面分)のレコードの「年齢フィールド(agec)」の更新は   
 問題なくでききるのではないかと思いました。   
   
    
以上、ご参考までに、コメントアップします。    
よろしくお願い致します。

 

kazuo urata様

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

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

ご丁寧にレコードまで作成していただき,なおかつお試しいただきありがとうございました。

記載してなかったのですが,私の方では月フィールドを必ず2桁で入力してもらうようにしております(2桁でなかったらエラーが出ます)。

ですが,ユーザビリティを考えた時,urata様のように自動で2桁にするほうが良いかもしれないと思いました。ありがとうございます。

そして実は問題はこの後で,レコード一覧に表示されるものだけではなく,4000件全てのレコードを取得して,計算し,更新するプログラムを作成中です。

REST APIコミュニティの方に転記させていただきましたが,うまく動かずハマってしまっている状態です。

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

※念のためそちらの投稿のURLも貼らせていただきます。

https://cybozudev.zendesk.com/hc/ja/community/posts/115000327006-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E4%B8%80%E8%A6%A7%E7%94%BB%E9%9D%A2%E3%81%A7%E3%81%AE%E5%B9%B4%E9%BD%A2%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E4%B8%80%E6%8B%AC%E6%9B%B4%E6%96%B0 

Hiroさん、お疲れ様です。

REST APIコミュニティの方を最初に見ました。それで、経緯を確認しようと思い、

こちらの方から入りました。

興味がありますので、REST APIコミュニティの方も考えてみたいと思います。

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