cybozu developer network

カテゴリー内の他の記事

第6回 テーブルの値を利用する(条件付きでデータを集計)

はじめて kintone をカスタマイズする人が kintone API の基礎知識を学べるよう、チュートリアルの内容を充実させてリニューアルしました。
   リニューアル後のチュートリアルは次のページを参照してください。
   はじめよう kintone API

(著者:落合 雄一

はじめに

今回は、kintoneのJavaScript APIでのデータ取得の中で質問が多いテーブルを使って、カテゴリ別のデータを集計してみようと思います(^^)

~~~~~~~~~~~~~~

とある森の隅で小さなパン屋を経営しているJおじさんの焼くパンは、愛と勇気がたくさん詰まっていると子供たちから大評判です。しかしJおじさんは、街の平和を守る必要もあり、売上の管理までなかなか手が回りません。そこで困ったJおじさんは、心強いビジネスパートナーでもある友人のkintoneマンに相談して、kintoneのテーブルとJavaScript APIを使って日別売上集計を行うことに決めました!

(この物語はフィクションであり、実在の人物・団体・事件などとは一切関係ありません。)

~~~~~~~~~~~~~~

それでは、皆さんもkintoneマンと一緒にJおじさんを助けましょう!O( ・`ω´・)乂(・∀・` )O

アプリの準備

Jおじさんが作ったアプリの設定を見てみましょう。テーブルの作り方は、フォームに表(テーブル)を追加する を参考にしてください。

各フィールドとフィールドコードは以下のようになっています。毎度のことですが、フィールドコードはあとで使いますのでφ( ̄ー ̄ )メモメモ

フィールド名

フィールドタイプ

フィールドコード

日付

日付

日付

-

テーブル

order_items

-

スペース

sub_total_area

作成日時

作成日時

作成日時

更新日時

更新日時

更新日時

また、テーブル(order_items)フィールドの中はこのような感じです。

フィールド名

フィールドタイプ

フィールドコード

カテゴリ

ラジオボタン

カテゴリ

商品名

文字列(1行)

商品名

単価(円)

数値

単価

個数

数値

個数

レコードの取得

以下は、6月23日のパン屋さんの売上データです。このデータを利用してみる事にしましょう(^^♪

テーブルのレコードオブジェクトを取得する、といっても特に難しい事はありません。他のフィールドタイプと同じように、eventオブジェクトのrecord要素にテーブルに設定したフィールドコードを指定してください。つまり、以下のような形です。

これによってどのようなデータが取得出来るのかについては、フィールド形式 のページを確認しましょう。テーブルのレスポンスデータについては、カスタムフィールドのテーブルの欄に記載があります。

テーブル SUBTABLE
  • 取得時のレスポンスのデータ
"<フィールドコード>": {
    "type": "SUBTABLE",
    "value": [
        {
            "id": "48290",
            "value": {
                "文字列__1行__0": {
                    "type": "SINGLE_LINE_TEXT",
                    "value": "サンプル1"
                },
                "数値_0": {
                    "type": "NUMBER",
                    "value": "1"
                },
                "チェックボックス_0": {
                    "type": "CHECK_BOX",
                    "value": [
                        "選択肢1"
                    ]
                }
            }
        },
        {
             "id": "48291",
             "value": {
                 "文字列__1行__0": {
                     "type": "SINGLE_LINE_TEXT",
                     "value": "サンプル2"
                 },
                 "数値_0": {
                     "type": "NUMBER",
                     "value": "2"
                 },
                 "チェックボックス_0": {
                     "type": "CHECK_BOX",
                     "value": [
                         "選択肢2"
                     ]
                 }
             }
        }
    ]
}

 

試しに、テーブルにある2件目のレコードの商品名を取得してみましょう(^^♪
ここで注意したいのが、配列の要素は0から数えるのでテーブルの2件目のデータは配列では1番目となる点です。

無事、2件目の商品名「食パン」が取得出来ました!\(*^▽^*)ノ

上記のキャプチャでも分かると思いますが、alertの出力はテーブルのレコードを表示するより先に出ています。つまり、'app.record.detail.show'イベントはテーブルのデータ表示より先に実行されているという事ですね。ここについては、今後取得したテーブルのデータを利用して高度な事をするときのために覚えておいた方が良いかも知れません。

カテゴリ別の合計を算出する

Jおじさんとしては、材料の仕入れなどの都合でパンとそれ以外の売れ行きを別々に知りたいという事なので、それぞれのカテゴリ別に売上を集計してスペースフィールドに表示するスクリプトを作ってみましょう。ここまではじめようシリーズを読んで下さった皆さんには詳しい説明はいらないかと思いますが、以下はそのサンプルです。

今回も簡単に出来ました!!

 Jおじさんの悩みもこれで解決できましたね。Σd=(・ω-`o)グッ♪

最後に

ここでは取り上げませんでしたが、テーブルのデータの集計には、自動計算機能を利用する方法もあります。そちらも是非マスターしておいた方が便利な機能ではありますが、今回のように何かの条件を加えて自由な計算をするにはJavaScriptを利用したほうが色々な事が出来るかと思います。目的に応じて必要なものを選べるようなkintoneマスターを是非目指していきましょう!

Let’s kintoneカスタマイズ\(^o^)/

このTipsは、2022年7月版で確認したものになります。

<<第5回 レコードの値を利用してみよう(一覧画面編)  | 第7回 カスタマイズビューを利用してみよう>>

デモ環境

こちらのデモ環境から実際に動作を確認できます。
https://dev-demo.cybozu.com/k/11/

デモ環境の利用は、事前に cybozu developer network のメンバー登録が必要です。画面右上の「サインイン」ボタンよりご登録ください。
デモ環境アカウントとパスワードは、サインイン後にこちらのページでご確認ください。

記事に関するフィードバック

記事のコメント欄は記事に対するフィードバックをする場となっております。
右の記事フィードバックのためのガイドを参照してコメントしてください。
記事のリンク切れなど、気になる点がある場合も、こちらのフォームからフィードバックいただけますと幸いです。

Avatar
h.kaburagi

テーブル内にボタンを設定して、その行内で計算させて表示するような使い方はできないでしょうか?

 

Avatar
cybozu Development team

鏑木様

記事のシナリオと異なる追加要望の場合は、今後はコミュニティの方に投稿をお願いいたします。

その上で、類似のご質問がコミュニティにございますのでご参考ください。

https://developer.cybozu.io/hc/ja/community/posts/206744026

ご要望と異なる場合は、上記の投稿と同様のイメージで、新規にコミュニティの方に投稿をお願いいたします。

Avatar
h.kaburagi

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

Avatar
近藤史人

テーブル内の金額をprice、テーブル外に合計を表示するamountというフィールドコードをつけて、下記のプログラムを書きましたが、金額の合計が文字タイプのように表示されます。

1行目に5を入れ、2行目に14を入れると0514となります。

何がおかしいのでしょうか?

ちなみに合計欄に表示もされず、confirmで確認しています。

(function() {
"use strict";
kintone.events.on('app.record.detail.show', function(event) {

if (!event.record) {
return;
}

var record = event.record;
var table = record.order_items.value;
var subTotals = new Number();

confirm('price1= '+table[0].value['price'].value)
confirm('price2= '+table[1].value['price'].value)

for (var i = 0; i < table.length; i++) {

subTotals = subTotals + table[i].value['price'].value;

}
confirm('subTotals= '+subTotals);

record.amount.value = subTotals;

confirm('amount= '+record.amount.value);

return event;
});

})();

 

Avatar
近藤史人

テーブルの中のpriceを整数に変換することでうまく動きましたが、この解決方法で正しいのでしょうか?

(function() {
"use strict";

var events = ['app.record.detail.show','app.record.create.submit',
'app.record.edit.submit'];

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

if (!event.record) {
return;
}

var record = event.record;
var table = record.order_items.value;
var subTotals = new Number();

for (var i = 0; i < table.length; i++) {
subTotals = subTotals + parseInt(table[i].value['price'].value);
}

record.amount.value = subTotals;
return event;
});

kintone.events.on(['app.record.edit.show', 'app.record.create.show'], function (event) {
event.record['amount'].disabled = true;
return event;

});
})();

Avatar
cybozu Development team

近藤史人 様

解決したとのことで何よりです。

 

整数処理のために、paeseInt()を用いたので問題ないかと思います。

 

なお、今後は技術的な質問に関してはcybozu developer コミュニティをご活用頂けると幸いです。

有志の開発者から回答が頂けるかと思います。

 

宜しくお願い致します。

Avatar
近藤史人

了解しました。

Avatar
t-kojima

サンプルコードについて質問させて下さい。

kintone.events.onに渡すコールバック関数の最初で、event.recordのnullチェックをしていますが

event.recordがnull(undefined)になることはありますか?

(他のチュートリアル記事では他にnullチェックしているものが無かったように思います)

もしnullになり得るのであれば、自分がカスタマイズする場合も考慮すべきと思い質問させて頂きました。

 

宜しくお願いいたします。

Avatar
cybozu Development team

t-kojima 様

お世話になっております。
cybozu development 運用事務局です。

record プロパティが返ってくるとされるイベントでは、event.record は存在する前提になっています。
そのため、null または undefined のチェックは不要です。

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

Avatar
t-kojima

cybozu Development team 様

回答ありがとうございます!

event.recordはnullになり得ないのですね。nullチェック不要な点了解しました。

 

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

Avatar
高原 直樹

ダッシュボードサンプルをベースにカスタマイズを行っており、その中で取得元のアプリでサブテーブル(売上管理表)を利用しています。

そのサブテーブルからのデータ取得というか表示が上手くいきません。

JSON経由で売上管理表サブテーブルの値も取得できているところまでは確認しています。

下記がソースの一部ですが、どこかおかしいところはありますでしょうか?

Chrome CONSOLEに「Uncaught (in promise) TypeError: Cannot read property '売上管理表' of undefined」と表示されます。

 

fetchRecords(SALES_APPID, '契約期間終了 <= ' + maxMonth + ' or 契約期間開始 >= "' + minMonth + '" order by OMS顧客コード asc')
.then(function(canvas1Rec) {

var data = [];
data[elevenMonthsBefore] = 0;
data[tenMonthsBefore] = 0;
data[nineMonthsBefore] = 0;
data[eightMonthsBefore] = 0;
data[sevenMonthsBefore] = 0;
data[sixMonthsBefore] = 0;
data[fiveMonthsBefore] = 0;
data[fourMonthsBefore] = 0;
data[threeMonthsBefore] = 0;
data[twoMonthsBefore] = 0;
data[oneMonthBefore] = 0;
data[thisMonth] = 0;

for (var i = 0; i < canvas1Rec.length; i++) {
var month;
var tableRecords = canvas1Rec[i].売上管理表.value;
for (var n = 0; n < tableRecords.length; n++) {
var date = tableRecords[n].value['売上月'].value.split("-");
if (date[1].charAt(0) === "0") {
month = date[1].charAt(1) + "月";
} else {
month = date[1] + "月";
}
if (tableRecords[n].value['売上月'].value <= moment()) {
data[month] += parseInt(tableRecords[n].value['実績請求額'].value, 10);
} else if (tableRecords[n].value['売上月'].value > moment()) {
data[month] += parseInt(tableRecords[n].value['予測額'].value, 10);
}
}
}

高原 直樹により編集されました
Avatar
cybozu Development team

高原 直樹 様

お世話になっております。
cybozu developer network 事務局です。

ご質問いただいた件ですが、
こちらのコメント欄は記事へのフィードバック用となります。

カスタマイズ方法等についてはぜひコミュニティをご活用ください。
https://developer.cybozu.io/hc/ja/community/topics

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

Avatar
takegawa

>テーブルの作り方は、フォームに表(テーブル)を追加する を参考にしてください。
リンク切れてました。

Avatar
cybozu Development team

takegawa 様

お世話になっております。
cybozu developer network 事務局です。

ご指摘いただき誠にありがとうございました。

ご指摘のリンクを修正いたしました。

お手数をおかけしまして申し訳ありませんが、ご確認お願いします。

今後ともcybozu developer networkよろしくお願いします。

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