# 別アプリからのレコード情報の取得

**URL:** <https://community.cybozu.dev/t/topic/3247>\
**Category:** kintone 開発相談\
**Created:** [2018 年 8 月 2 日午前 11:46 UTC](https://community.cybozu.dev/t/topic/3247 "2018-08-02T11:46:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Legacy\_Account788](https://avatars.discourse-cdn.com/v4/letter/l/9fc29f/32.png) [@Legacy\_Account788](https://community.cybozu.dev/u/Legacy_Account788)\
**Post date:** [2018 年 8 月 2 日午前 11:46 UTC](https://community.cybozu.dev/t/topic/3247/1 "2018-08-02T11:46:58Z")

</div>

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

類似投稿を読み、いろいろ試してきましたが解決に至らず、投稿いたしました。

&nbsp;

やりたいこと

アプリA

アプリID 67

申請者名 文字列１行

勤務形態 ドロップダウン（”出勤”、”有休”）

残業時間 数値(分単位で記入しています)

アプリB

社員名 ユーザ選択

出勤日数 数値

残業時間 数値

があります。

このとき、アプリB：社員名＝アプリA：申請者名である

アプリAのレコードを取得し、

アプリA：勤務形態＝”出勤”のレコードの数をアプリB：出勤日数に、

アプリA：残業時間の総和をアプリB：残業時間に出力したいと考えております。

&nbsp;

まずは出勤日数だけ出力してみようと

下記Scriptを作成しましたが、うまくいきません。

お手数をおかけいたしますが、どこを修正すればいいか教えていただけないでしょうか。

コードからお察しいただけるかと思いますが、Kintone、JavaScriptともに初心者です。

&nbsp;

(function() {  
&nbsp;&nbsp;&nbsp; “use strict”;  
&nbsp;&nbsp;&nbsp; var events = [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; “app.record.create.show”, “app.record.edit.show”, “app.record.index.edit.show”  
&nbsp;&nbsp;&nbsp; ];  
&nbsp;&nbsp;&nbsp; kintone.events.on(events, function(event) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var record = event.record;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var appId = 67;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var recordId = record[‘対象社員’].value[0].name;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kintone.api(‘/k/v1/records’, ‘GET’, {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; app: appId,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query: ‘申請者1 = "’ + recordId + ‘"’,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fields: [‘勤務形態’,‘残業時間’],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function(resp) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var iDayCnt = 0;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i = 0; i \< resp.totalCount; i++) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(resp[‘records’][i][‘勤務形態’][‘value’] === “出勤”){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iDayCnt++;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; record[‘出勤日数’][‘value’]=iDayCnt;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return event;  
&nbsp;&nbsp;&nbsp; });  
})();  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![Legacy\_Account1517](https://avatars.discourse-cdn.com/v4/letter/l/4bbf92/32.png) [@Legacy\_Account1517](https://community.cybozu.dev/u/Legacy_Account1517)\
**Post date:** [2018 年 8 月 4 日午前 2:48 UTC](https://community.cybozu.dev/t/topic/3247/2 "2018-08-04T02:48:50Z")

</div>

aki さん

気になったところを上げてみます。

・アプリA タイムカード、 アプリB 月次勤務管理

アプリ名があると理解しやすく、処理もイメージしやすくなります。

勤務管理であれば、たぶん月の管理が必要だと思います。

・アプリB（月次勤務管理）に申請月（日付項目）を追加

勤務の締め日によって、対象月の範囲が変わりますが申請月単位で管理します。

・アプリA（タイムカード） 申請者名（文字列１行）を 申請者（ユーザー選択）に変更（規定値をログインユーザー）

アプリA（タイムカード）とアプリB（月次勤務管理）で、社員を扱う項目は同じ形式にしましょう。

申請者名だと、同姓同名問題が発生します。 文字列だと、入力ミスもあります。

&nbsp;

・変数名は、中身にあったものをつけましょう。

var recordId = record[‘対象社員’].value[0].name;

社員名なら、recordId ではなく、employeeName 等の中身をあらわす名称にしましょう。

英語にこだわらずに、ローマ字でもいいと思います。

・配列の長さチェック

record[‘対象社員’].value[0]

配列の要素を参照する場合は、要素が存在するかチェックしましょう。

ユーザー選択であれば、マニュアルで選択を解除することもできます。

&nbsp;

・ resp.totalCount について

for (var i = 0; i \< resp.totalCount; i++) {

resp.totalCount は、kintone のアプリ上の対象レコード件数をあらわします。

API 呼び出し時、totalCount: true オプションを指定しないと値が設定されません。

実際に取得したレコード数を示すのは、resp.records.length になります。

API の規定値で レコード取得した場合は、最大 100 レコードになります。

対象レコード件数が 100 以上の場合、 resp.totalCount と resp.records.length が異なります。

今回は、社員別の勤務レコードなので、どちらでも同じ数値になると思いますが、意味が異なりますので使い分けましょう。

・ レコードの更新処理

record[‘出勤日数’][‘value’]=iDayCnt;

kintone.api は、非同期処理ですので、api が完了した時点では イベント処理が完了しています。

そのため、 event.record を書き換えても 実際の画面表示には反映されません。

"app.record.create.show"等は、Promise 非対応なので、api の完了を待ってからイベント処理を終了することもできません。

対応としては、kintone.app.record.set 関数を使って、画面表示を変更します。

&nbsp;

・サンプルアプリイメージです。

勝手なイメージですので、運用に合わせてカスタマイズしてください。

&nbsp;

&nbsp;

&nbsp;

・サンプルコード

勤務日数部分だけ実装してみました。

日付処理のため、moment.js を使っています。

参考 [Moment.js を利用して、日時フィールドのフォーマットをカスタマイズする](https://community.cybozu.dev/hc/ja/articles/204982474-Moment-js-%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6-%E6%97%A5%E6%99%82%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%82%92%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%81%99%E3%82%8B)

&nbsp;

```
/*
* 勤務管理集計サンプル
*/
(function() {
"use strict";

const TIMECARD_APPID = 281; // タイムカードアプリ

var events = [
"app.record.create.show", "app.record.edit.show", "app.record.index.edit.show",
"app.record.create.change.対象社員",
"app.record.edit.change.対象社員",
"app.record.index.edit.change.対象社員",
"app.record.create.change.申請月",
"app.record.edit.change.申請月",
"app.record.index.edit.change.申請月",
];
kintone.events.on(events, function(event) {
var record = event.record;
record['出勤日数']['disabled'] = true;
record['出勤日数']['value'] = 0;

moment.locale('ja');

// 勤務集計処理
if (!errCheck(record)) {
var employees = record['対象社員'].value[0].code
var startOfDate = moment(record['申請月'].value).startOf('month').format('YYYY-MM-DD');
var endOfDate = moment(record['申請月'].value).endOf('month').format('YYYY-MM-DD');
var query = '申請者 in (" USER", "' + employees + '")';
query += ' and 日付 >= "' + startOfDate + '"';
query += ' and 日付 <= "' + endOfDate + '"';
var param = {
app: TIMECARD_APPID,
query: query,
fields: ['勤務形態', '残業時間'],
};
kintone.api('/k/v1/records', 'GET', param).then(function(resp) {
var iDayCnt = 0;
for (var i = 0; i < resp.records.length; i++) {
if (resp['records'][i]['勤務形態']['value'] === "出勤") {
iDayCnt++;
}
}
record['出勤日数']['value'] = iDayCnt;
kintone.app.record.set({ record: record });
}).catch(function(error) {
console.log('record get err', error);
alert('タイムカードレコード取得エラー');
});
}

return event;
});

// レコードエラーチェック
function errCheck(record) {
var err = false;
if (record['対象社員'].value.length !== 1) {
record['出勤日数']['value'] = 0;
record['対象社員'].error = '１申請者を指定します';
err = true;
}
else {
record['対象社員'].error = null;
}
if (!record['申請月'].value) {
record['申請月'].error = '必須';
err = true;
}
else {
record['申請月'].error = null;
}
return err;
}
})();

```

---

<div class="post-metadata">

**Author:** ![Legacy\_Account788](https://avatars.discourse-cdn.com/v4/letter/l/9fc29f/32.png) [@Legacy\_Account788](https://community.cybozu.dev/u/Legacy_Account788)\
**Post date:** [2018 年 8 月 7 日午前 1:30 UTC](https://community.cybozu.dev/t/topic/3247/3 "2018-08-07T01:30:07Z")

</div>

**[rex0220様](https://community.cybozu.dev/hc/ja/profiles/435994154-rex0220)**

**コードの間違いの指摘にとどまらず、**

**アプリ作成のノウハウまで教えていただきありがとうございます。**

**また、昨日まで出張だったため、返信が遅くなったことお詫び申し上げます。**

&nbsp;

**さっそく、いただいた情報をもとにアプリを作成しなおしたいと思います。**

**作成する中で、またご相談させていただく場合もあるかもしれませんが、**

**その際はお時間の許す範囲でご支援いただけますと幸いです。**

&nbsp;

**ひとまず、いただいた情報を用いて自力で頑張ってみます。**

&nbsp;

**以上、よろしくお願いいたします。**
