# 100件以上のレコードを取得しようとすると同じ100件のデータが重複して取得されてしまう

**URL:** <https://community.cybozu.dev/t/topic/9155>\
**Category:** kintone 開発相談\
**Created:** [2024 年 6 月 12 日午前 11:06 UTC](https://community.cybozu.dev/t/topic/9155 "2024-06-12T11:06:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yuchi208](https://avatars.discourse-cdn.com/v4/letter/y/6a8cbe/32.png) [@yuchi208](https://community.cybozu.dev/u/yuchi208)\
**Post date:** [2024 年 6 月 12 日午前 11:06 UTC](https://community.cybozu.dev/t/topic/9155/1 "2024-06-12T11:06:22Z")

</div>

ポータルにボタンを設置し、ボタン押下で取得したデータを指定アプリに反映させる処理を施したい過程で問題が起きました。  
（作成段階でありますので、別アプリへの反映処理などは未記載です。）

100件以上のデータを取得する場合、クエリにoffsetを持たせ、ループ処理をするとの記事を見かけチャレンジしてみたのですが、同じ100件のデータが重複して取得されてしまいました。

もちろん想定としては取得したデータ全てユニークである想定で作りたかったのですが、、、

offsetは間違いなく設定されていると思うのですが、、、どうにもこうにもいかず、、、

(() =\> {

‘use strict’;

// ポータル表示時のイベント  
kintone.events.on(‘portal.show’, () =\> {

```
// ポータルの上側の空白部分の要素を取得する
const el = kintone.portal.getContentSpaceElement();

// ボタン作成
const clockInButton = document.createElement('button');
clockInButton.textContent = '総合データ更新';
clockInButton.style.margin = '5px 0 0 16px';

// 押下時の処理
clockInButton.onclick = () => {
  dataUpdade();
};

//ポータルにボタンの設定
el.appendChild(clockInButton);

```

});

async function dataUpdade(){  
try{

```
  //アプリID
  const APP_ID_AAA = 6; //アプリ1
  const APP_ID_BBB = 10; //アプリ2
  const APP_ID_CCC = 12; //アプリ3
  const APP_ID_DDD = 13; //アプリ4
  const APP_ID_EEE = 14; //アプリ5
  const APP_ID_FFF = 15; //アプリ6
  
  //データ元：アプリ1のアプリID取得
  let appId = APP_ID_AAA;
  const query = 'アルファベット in ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")'; 
  
  let allRecords = [];
  let offset = 0;
  const limit = 100; // 1回のリクエストで取得するレコード数

  //取得フィールドの設定
  while (true) {
    const getParams = {
      app: appId,
      query: query,
      totalCount: true, // レコード数を取得するためのオプション
      offset: offset, // レコードのオフセット
      limit: limit, // 1回のリクエストで取得するレコード数
      orderBy: '日時 asc', // 日時の昇順で並び替える
    };
    
    //設定されたクエリでレコードを取得
    const res = await kintone.api(kintone.api.url('/k/v1/records'), 'GET', getParams);
    allRecords = allRecords.concat(res.records);

    // レコードの総数を取得
    const totalCount = res.totalCount;

    // 次のレコードを取得するためのオフセットを更新
    offset += limit;

    // 全てのレコードを取得したらループを終了
    if (allRecords.length >= totalCount) {
      break;
    }

  }

  // レスポンスから[アルファベット][月]ごとのレコード数を算出
  const monthlyCounts = {};
  allRecords.forEach(record => {

    const alphabet = record.アルファベット.value;
    const date = new Date(record.日時.value);
    const monthYear = `${date.getFullYear()}/${date.getMonth() + 1}`;

    if (!monthlyCounts[alphabet]) {
      monthlyCounts[alphabet] = {};
    }
    if (!monthlyCounts[alphabet][monthYear]) {
      monthlyCounts[alphabet][monthYear] = 0;
    }
    monthlyCounts[alphabet][monthYear]++;

  });

  // アルファベットごと、月ごとのレコード数をログに出力
  console.log('アルファベットごと月ごとのレコード数:', monthlyCounts);      
        
}catch(e){
  alert(e);
}

```

}  
})();

---

<div class="post-metadata">

**Author:** ![mura](https://sea1.discourse-cdn.com/flex015/user_avatar/community.cybozu.dev/mura/32/41_2.png) [@mura](https://community.cybozu.dev/u/mura)\
**Post date:** [2024 年 6 月 12 日午後 11:23 UTC](https://community.cybozu.dev/t/topic/9155/2 "2024-06-12T23:23:33Z")

</div>

> **[全レコードの取得方法](https://cybozu.dev/ja/kintone/tips/development/customize/development-know-how/retrieve-all-records-using-kintone-rest-api-client/#kintone-rest-api-client)**
>
> kintone-rest-api-clientを利用した、全レコードの取得方法を紹介します。

直接的な回答でなくて申し訳ありませんが、 kintone rest api clientをつかうとだいぶ楽に書けると思いますが、いかがでしょうか。

---

<div class="post-metadata">

**Author:** ![yuchi208](https://avatars.discourse-cdn.com/v4/letter/y/6a8cbe/32.png) [@yuchi208](https://community.cybozu.dev/u/yuchi208)\
**Post date:** [2024 年 6 月 14 日午前 12:05 UTC](https://community.cybozu.dev/t/topic/9155/3 "2024-06-14T00:05:25Z")

</div>

muraさん

ありがとうございます！  
私も最初そちらで試したのですが、kintone-rest-api-clientはアプリ内でしか使用できなく、ポータルでは使用不可とのことでした(\>\_\<)

---

<div class="post-metadata">

**Author:** ![aaa](https://sea1.discourse-cdn.com/flex015/user_avatar/community.cybozu.dev/aaa/32/277_2.png) [@aaa](https://community.cybozu.dev/u/aaa)\
**Post date:** [2024 年 6 月 14 日午前 2:53 UTC](https://community.cybozu.dev/t/topic/9155/4 "2024-06-14T02:53:19Z")

</div>

仮に現在のコードを改変して  
limitを500にしてみました。  
結果：1回につき100件しか取得できませんでした。

limitを50にしてみました。  
結果：1回につき100件しか取得できませんでした。

limitの情報は送ったつもりになっているが、反映されてません。  
limitを指定しないと100件がデフォルトで返却されるので動作しているように見える。  
同様にoffsetも送っているが反映されていないようです。  
同じ100件のデータが2回返ってきます。

以下の指定方法に誤りがあると思います。  
この指定方法がどこかに書いてあったのでしょうか？生成AI由来？

```javascript
    const getParams = {
      app: appId,
      query: query,
      totalCount: true, // レコード数を取得するためのオプション
      offset: offset, // レコードのオフセット
      limit: limit, // 1回のリクエストで取得するレコード数
      orderBy: '日時 asc', // 日時の昇順で並び替える
    };

```

複数のレコードを取得する - cybozu developer network

> **[複数のレコードを取得する](https://cybozu.dev/ja/kintone/docs/rest-api/records/get-records/#request)**
>
> クエリで条件を指定して、複数のレコードを取得します。

クエリの書き方 - cybozu developer network

> **[クエリの書き方](https://cybozu.dev/ja/kintone/docs/overview/query/)**
>
> レコードを絞り込むときのクエリの書き方を説明します。

[https://cybozu.dev/ja/id/b05ff19d869f1609a1326dc7/#option](https://cybozu.dev/ja/id/b05ff19d869f1609a1326dc7/#option)

を参考に queryの中にlimit/offset/order byなどを入れてください。

どこかのページを参考にしていた場合は、そのページも教えていただけるとありがたいです。

---

<div class="post-metadata">

**Author:** ![aaa](https://sea1.discourse-cdn.com/flex015/user_avatar/community.cybozu.dev/aaa/32/277_2.png) [@aaa](https://community.cybozu.dev/u/aaa)\
**Post date:** [2024 年 6 月 14 日午前 4:03 UTC](https://community.cybozu.dev/t/topic/9155/5 "2024-06-14T04:03:23Z")

</div>

質問者のコード貼り付けが失敗しています。  
途切れて見づらいので途切れないようにしてコードブロックを貼り付けておきます。

```javascript
(() => {

    'use strict';

    // ポータル表示時のイベント
    kintone.events.on('portal.show', () => {

        // ポータルの上側の空白部分の要素を取得する
        const el = kintone.portal.getContentSpaceElement();

        // ボタン作成
        const clockInButton = document.createElement('button');
        clockInButton.textContent = '総合データ更新';
        clockInButton.style.margin = '5px 0 0 16px';

        // 押下時の処理
        clockInButton.onclick = () => {
            dataUpdade();
        };

        //ポータルにボタンの設定
        el.appendChild(clockInButton);
    });

    async function dataUpdade() {
        try {

            //アプリID
            const APP_ID_AAA = 6; //アプリ1
            const APP_ID_BBB = 10; //アプリ2
            const APP_ID_CCC = 12; //アプリ3
            const APP_ID_DDD = 13; //アプリ4
            const APP_ID_EEE = 14; //アプリ5
            const APP_ID_FFF = 15; //アプリ6

            //データ元：アプリ1のアプリID取得
            let appId = APP_ID_AAA;
            const query = 'アルファベット in ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")';

            let allRecords = [];
            let offset = 0;
            const limit = 100; // 1回のリクエストで取得するレコード数

            //取得フィールドの設定
            while (true) {
                const getParams = {
                    app: appId,
                    query: query,
                    totalCount: true, // レコード数を取得するためのオプション
                    offset: offset, // レコードのオフセット
                    limit: limit, // 1回のリクエストで取得するレコード数
                    orderBy: '日時 asc', // 日時の昇順で並び替える
                };

                //設定されたクエリでレコードを取得
                const res = await kintone.api(kintone.api.url('/k/v1/records'), 'GET', getParams);
                allRecords = allRecords.concat(res.records);

                // レコードの総数を取得
                const totalCount = res.totalCount;

                // 次のレコードを取得するためのオフセットを更新
                offset += limit;

                // 全てのレコードを取得したらループを終了
                if (allRecords.length >= totalCount) {
                    break;
                }

            }

            // レスポンスから[アルファベット][月]ごとのレコード数を算出
            const monthlyCounts = {};
            allRecords.forEach(record => {

                const alphabet = record.アルファベット.value;
                const date = new Date(record.日時.value);
                const monthYear = `${date.getFullYear()}/${date.getMonth() + 1}`;

                if (!monthlyCounts[alphabet]) {
                    monthlyCounts[alphabet] = {};
                }
                if (!monthlyCounts[alphabet][monthYear]) {
                    monthlyCounts[alphabet][monthYear] = 0;
                }
                monthlyCounts[alphabet][monthYear]++;

            });

            // アルファベットごと、月ごとのレコード数をログに出力
            console.log('アルファベットごと月ごとのレコード数:', monthlyCounts);

        } catch (e) {
            alert(e);
        }
    }
})();

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex015/uploads/cybozu/original/1X/d5c841c3c5a6cb66eed514001c1b45147c9e1f4f.png) [@system](https://community.cybozu.dev/u/system)\
**Post date:** [2024 年 6 月 19 日午前 12:46 UTC](https://community.cybozu.dev/t/topic/9155/6 "2024-06-19T00:46:13Z")

</div>

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。
