新規投稿
フォローする

ボタンクリックで2000件のデータを登録しようとすると、毎回登録数が異なってしまう

いつも大変お世話になっております。
今回、スケジュール管理を行いたく、各曜日の予定を1か月分自動登録するアプリを作成したのですが、データがきちんと登録されません。

データ数は全体で2000件ほどだと思うのですが、毎回登録されるデータ数が違います。

例)

・個人カード番号 1番 月曜日 10:00~ 火曜日 10:00~ 水曜日 13:00~ 

・個人カード番号 2番 月曜日 9:00~ 水曜日 12:00~ 金曜日 11:00~

・・・etc

個人カード側から曜日と時間を取得し、
カレンダーアプリ側に1か月分を登録しています。

取得はできているのですが、登録がところどころ落ちてしまったり、2000件あるにもかかわらず、100件程度しか登録できない時もあります。

また、2000件登録できる時もあります…。

 

見よう見まねでコードを書いているので、おかしな箇所が多々あるかと思うのですが、このような動きをするのは、PUTの部分に何か問題があるのか、それともそもそもこのような大量のデータを一括で登録しない方が良いのか、判断できずにおります。

Kintoneマスターの皆様、何卒ご教授よろしくお願い致します。

 

moment.locale("ja");

//個人カード
var personal_app = 111;
var schedule_app = 112;

var m = moment();
var year = m.year();
var month = m.month();

(function() {
  "use strict";


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

      //増殖バグ防止
    if (document.getElementById('my_put_button') !== null) {
    return;
    }

    var myIndexButton = document.createElement('button');
    myIndexButton.id = 'my_put_button';
    myIndexButton.innerText = '予定の一括登録';
    
    
    kintone.app.getHeaderMenuSpaceElement().appendChild(myIndexButton);
    

//カレンダーだけにボタン設置    
//    if(event.viewName !== 'カレンダー') return;
    

    myIndexButton.onclick = function () {
          
          if(window.confirm("データを登録します")) {
            
              //個人カードからデータ取得
              var manager = new KintoneRecordManager;
            manager.appId = personal_app; // 個人カードアプリID
              manager.getRecords(function(records) {
                // レコード取得後の処理
                console.log(records);
                //予定登録
                new_data(records);
              });


           } else { 
               return false;
           }
          
          
          
         //   window.alert('予定一括登録しました。');
    };


    var KintoneRecordManager = (function() {
        KintoneRecordManager.prototype.records = [];    // 取得したレコード
        KintoneRecordManager.prototype.appId = null;    // アプリID
        KintoneRecordManager.prototype.query = '';      // 検索クエリ
        KintoneRecordManager.prototype.limit = 500;   // 一回あたりの最大取得件数
        KintoneRecordManager.prototype.offset = 0;      // オフセット

        function KintoneRecordManager() {
            this.appId = kintone.app.getId();
            this.records = [];
        }

        // すべてのレコード取得する
        KintoneRecordManager.prototype.getRecords = function(callback) {
            kintone.api(
                kintone.api.url('/k/v1/records', true),
                'GET',
                {
                    app: this.appId,
                  query: this.query + (' limit ' + this.limit + ' offset ' + this.offset),
                },
                (function(_this) {
                    return function(res) {
                        var len;
                        Array.prototype.push.apply(_this.records, res.records);
                        len = res.records.length;
                        _this.offset += len;
                        if (len < _this.limit) { // まだレコードがあるか?
                            _this.ready = true;
                            if (callback !== null) {
                                callback(_this.records); // レコード取得後のcallback
                            }
                        } else {
                            _this.getRecords(callback); // 自分自身をコール
                        }
                    };
                })(this)
            );
        };
        return KintoneRecordManager;
    })();

    /*全データ登録*/
    function new_data(records) {
         records.forEach(function(data) {

            //今月の予定を一括入力
            var last_day = moment().endOf('month').format("DD")

            var i = 0;

            while(i < last_day) {
              i++;
              
              //曜日を取得
              moment.updateLocale('ja', {weekdaysShort: ["日曜","月曜","火曜","水曜","木曜","金曜","土曜"]});


              var hiduke = moment().set({'year': year, 'month': month, 'date': i}).format("YYYY-MM-DD");
              var yobi = moment(new Date(hiduke)).format('ddd');
            //データをセット

              var yotei_yobi = yobi + "予定";
              var yotei_status = yobi + "ステータス";
              //0327
              var user_no = data.レコード番号.value;
              var name = data.facility_name.value;
              var yobitime = data[yotei_yobi].value;
              var status = data[yotei_status].value;


            
              if (yobitime.length === 0) {
                        //  window.alert(hiduke + yobi + name + "空");
              } else {
    
                        // window.alert(hiduke + yobi + name + "空じゃない");
                          
              for (var y = 0; y < yobitime.length; y++) {                         
                          var work_time = yobitime[y];
                          var work_time2;
                          
                          if(work_time == "9:00~") {
                              work_time = "09:00:00+09:00";
                              work_time2 = "11:00:00+09:00";
                          } else if(work_time == "11:10~") {
                              work_time = "11:00:00+09:00";
                              work_time2 = "12:00:00+09:00";                          
                          } else if(work_time == "13:10~") {
                              work_time = "13:10:00+09:00";
                              work_time2 = "14:00:00+09:00";                                                    
                          } else {
                              work_time = "00:00:00+09:00";
                              work_time2 = "00:00:00+09:00";                                                    
                          }

                          var start_time = hiduke + 'T' + work_time;
                          var end_time = hiduke + 'T' + work_time2;              

                          //window.alert(start_time + "ユーザーNO."+user_no+"名前"+name+"予定"+yobitime+"ステータス"+status);
                     
                          var postbody = {
                            'app': schedule_app,
                            'record': {
                             'user_no': {
                                'value': user_no
                              },
                              'start': {
                                'value' : start_time
                              },
                              'end': {
                                'value': end_time
                              },
                              'status': {
                                'value': status
                              }
                            }
                          }
                            // postbody end
                          
                            kintone.api(kintone.api.url('/k/v1/record.json', true), 'POST', postbody).then((resp) => {
                              // success
                              window.alert(user_no + 'レコード登録完了');
                            
                            }, (error) => {


  // error:エラーの場合はメッセージを表示する
  let errmsg = 'レコード登録時にエラーが発生しました。';
  // レスポンスにエラーメッセージが含まれる場合はメッセージを表示する
  if (error.message !== undefined) {
    errmsg += '\n' + error.message;
  }
  window.alert(user_no + errmsg);
  
  
                              console.log(error);
                              
                            });  // kintone.api end

  
  
                } //for end
                
              }// if end
              
              
            } //while end


        });
                
                window.alert('レコードを登録しました');                

                location.reload();

    }

});


})();
0

2件のコメント

Avatar
TO

Mayuko Yamamoto様

              //個人カードからデータ取得
              var manager = new KintoneRecordManager;
            manager.appId = personal_app; // 個人カードアプリID
              manager.getRecords(function(records) {
                // レコード取得後の処理
                console.log(records);
                //予定登録
                new_data(records);
              });

上記のmanager.getRecordsのレコード取得とnew_dataが非同期に流れているように思います.
(getRecordsでレコードを取得しきる前にnew_dataが実行されているという意味)
manager.getRecordsをpromise処理してレコードをちゃんと取得してからnew_dataに流れるようにすると良いかと思います.
ちなみにconsole.logでの取得確認は構文ミスなどの"実行(是非)確認"には使えますが,非同期処理における"工程確認"にはあまり役立ちません.

promise処理についてはdeveloper network内にもテキストがあるので,参考になるかと思います.
(ググってもたくさんでてきます)
kintoneにおけるPromiseの書き方の基本
目指せ!JavaScriptカスタマイズ中級者(2) 〜Promiseのかわりにasync/await編〜

なお,全体的に少し古い手法?のようにも見えました.
ライブラリとしてmoment.jsを利用しているようですが,現在Cybozu CDNではmoment.jsから別のライブラリに替えるよう案内されています.
Cybozu CDN
代替ライブラリとしてはLuxonが紹介されています.
Luxon を使って kintone の日付や日時フィールドのフォーマットをカスタマイズする

KintoneRecordManagerについては利用経験がないのですが,今はkintone/rest-api-clientというものもあって,比較的簡単な記載で再帰処理(Manager内で行われている同じAPIを繰り返して実行する仕組み)をしてくれます.
kintone JavaScript Client (@kintone/rest-api-client)

以上,参考になれば幸いです.

0
Avatar
Mayuko Yamamoto

TO 様

ご返信いただきありがとうございます!
まだ試していないのですが、先にお礼をお伝えさせていただきたいと思いました。

>上記のmanager.getRecordsのレコード取得とnew_dataが非同期に流れているように思います.
(getRecordsでレコードを取得しきる前にnew_dataが実行されているという意味)
manager.getRecordsをpromise処理してレコードをちゃんと取得してからnew_dataに流れるようにすると良いかと思います.
ちなみにconsole.logでの取得確認は構文ミスなどの"実行(是非)確認"には使えますが,非同期処理における"工程確認"にはあまり役立ちません.

この部分、全くもっておっしゃるとおりで、console.logには何も表示されていないため、「ミスはない?」と思ってしまって途方にくれていた次第です。

早速修正して、試して見たいと思います!

また、ライブラリの件もありがとうございます。
最初は kintone JavaScript Client (@kintone/rest-api-client)

こちらを利用してみようと思ったのですが、なかなか利用している方の参考コードがみつからず、
割と急ぎだったため、過去に動作していたものに頼ってしまいました。。。

大元の部分が直ったら、改めて新しいライブラリを使用してみたいと思います。

この度はありがとうございます。
早速試して見たいと思います。

0
サインインしてコメントを残してください。