> ## Documentation Index
> Fetch the complete documentation index at: https://help.dingtalk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 社員の日次勤怠レポートデータの取得

> 社員の日次勤怠レポートを取得する API です。出勤日数・遅刻・欠勤などの日次指標を取得し、月次・四半期・年次の集計や多次元分析に活用できます。

# 毎日の勤怠レポートの生成：日次統計と多次元データ分析

## 概要

本ソリューションは、社員の勤怠レポートデータの取得から集計までをエンドツーエンドで実現します。DingTalk Open Platform の勤怠レポート API を使って日単位で指標を収集し、ローカルで集計します。

### 背景

企業は、社員の勤怠データを定期的に把握し、分析する必要があります。主な指標は、出勤予定日数、実出勤日数、遅刻、早退、欠勤などです。DingTalk の管理コンソールでは勤怠レポートを可視化して確認できます。一方、人事システム、BI プラットフォーム、OA ダッシュボードなどの社内システムでは、次の目的のために API 経由でデータを自動取得する必要があります。

* **レポート生成の自動化**：月次・四半期・年次の勤怠集計レポートを、手作業ではなくスケジュールに沿って自動でエクスポートします。
* **システム間連携**：勤怠データを企業の ERP や給与システムに同期し、データの流れを一元化します。
* **詳細なデータ分析**：勤怠データを売上や顧客満足度などの業務データと関連付け、多次元で分析します。
* **エラーの監視とアラート**：部門別・個人別の勤怠エラーの傾向をリアルタイムに監視し、リスクを早期に検知します。

DingTalk Open Platform の勤怠レポート API は、月次集計表を返しません。日単位の基本指標値を返すため、開発者自身がデータを集計する必要があります。そのため、次のような課題があります。

* **学習コストの高さ**：API に不慣れな開発者は API の機能を誤解しやすく、月次集計結果が返ってくると想定しがちです。
* **開発コストの高さ**：日付範囲の反復処理、空値の補完、エラーの除外など、追加の集計ロジックを実装する必要があります。
* **パフォーマンスの課題**：社員数が 1,000 人を超える大規模組織では、1 か月分のクエリに数千回の API 呼び出しが必要になる場合があり、レート制限やタイムアウトが発生するおそれがあります。

### 主なメリット

本ソリューションは、社員の勤怠レポートデータの取得から集計までの全工程をカバーします。標準化された API 呼び出しフローとベストプラクティスにより、勤怠データの収集・分析の自動化を支援します。

* **標準化された統合フロー**：4 つのコア API の呼び出し順序（スマート統計の確認 → 列定義の取得 → 列値のクエリ → データ集計）を明確に定義し、学習コストを下げます。
* **柔軟なデータ粒度**：日・ユーザー・部門・勤怠グループ単位のクエリに対応し、さまざまな業務ニーズに応えます。
* **高性能なバッチ処理**：ページング、同時実行制御、キャッシュを活用し、大量データを安定して取得します。
* **充実したデータ検証**：整合性チェックを組み込み、日付の欠落、重複レコード、異常値を自動で検出します。

### ユースケース

本ソリューションは、次のような一般的な業務シナリオに適用できます。

* **人事月次レポートの自動化**：毎月 1 日に前月の全社勤怠集計を自動生成し、メールで経営層に送信します。
* **給与システムとの連携**：遅刻控除や残業時間などの勤怠データを給与システムに同期し、給与を自動計算します。
* **部門パフォーマンスダッシュボード**：出勤率や遅刻率の部門別ランキングをリアルタイムに表示し、経営判断を支援します。
* **個人勤怠照会アプリ**：社員が自分の勤怠履歴を自ら照会できるようにし、人事部門への問い合わせを減らします。

## 代表的な業務シナリオ

### シナリオ 1：人事月次勤怠レポートの自動化

#### 課題

従来、人事担当者は毎月初めに DingTalk の管理コンソールにログインし、前月の全社勤怠レポートを手作業でエクスポートしていました。その後、Excel でデータのクレンジング、集計、書式設定を行います。この作業には 2〜3 時間かかり、ミスも起こりがちです。社員数が 1,000 人を超えると、手作業での処理はほぼ不可能になります。

#### 導入効果

* **自動化された作業フロー**

  月次レポートの自動化パイプラインは、次の 5 ステップで実行されます。

  1. 毎月 1 日の早朝にスケジュールタスクが起動します。
  2. DingTalk Open Platform の API を呼び出し、勤怠データの列定義と列値を一括取得します。
  3. ローカルでデータをクレンジング・集計し、月次指標を計算します。
  4. Excel（数式付き）、PDF（押印版）、HTML（オンラインプレビュー）の複数形式でレポートを生成します。
  5. レポートをメールで経営層に自動送信します。CC と権限制御にも対応しています。
* **主な利点**

  * **完全自動生成**：毎月 1 日の早朝にスクリプトが自動実行され、Excel と PDF のレポートを生成して指定の宛先にメール送信します。手作業は不要です。
  * **複数の出力形式**：Excel（数式付き）、PDF（押印版）、HTML（オンラインプレビュー）に対応し、さまざまな配布ニーズに応えます。
  * **カスタム指標**：組織に合った指標を選択できます。たとえば、「遅刻 + 欠勤日数」のみを集計し、その他のフィールドを無視できます。
  * **過去データとの比較**：前年同月比・前月比を自動計算し、ある部門の遅刻率が前月比で 20% 上昇した場合など、異常な変化を通知します。

### シナリオ 2：勤怠データの給与システムへの同期

#### 課題

給与計算には、遅刻控除や残業代の算定基礎など、正確な勤怠データが欠かせません。しかし、DingTalk と給与システムの間には標準的なデータインターフェースがありません。人事担当者は毎月、勤怠明細を手作業でエクスポートし、Excel の VLOOKUP で社員番号を照合してから、給与システムにインポートする必要があります。この作業は時間がかかるうえ、社員番号の不一致によってデータの不整合が生じることもあります。

#### 導入効果

* **自動化された作業フロー**

  自動同期は、次の 5 ステップで実行されます。

  1. 社員の打刻後、T+1 日目に同期タスクが起動します。
  2. DingTalk Open API を呼び出して暦日単位で勤怠列値をクエリし、元の打刻記録を取得します。
  3. DingTalk の **userId** を企業の**社員番号**にマッピングし、統一された ID の関連付けを確立します。
  4. エラー検出を実行し、人事担当者が対応するための確認チケットを生成します。
  5. 確認が承認されると、データが給与システムのデータベースに自動で書き込まれ、同期が完了します。
* **主な利点**

  * **タイムリーな同期**：打刻データは T+1 日目に給与システムへ同期されるため、月次給与は常に最新データに基づいて計算されます。
  * **正確な照合**：DingTalk の userId と社員番号のマッピングテーブルにより、データの関連付けを 100% 正確に行い、手作業による照合ミスをなくします。
  * **エラーの遮断**：1 日の打刻が 24 時間を超える、7 日間連続で打刻記録がないなど、異常なデータを自動で検出します。システムが確認チケットを生成し、人事担当者が確認した後にのみデータが同期されます。
  * **監査証跡**：同期のたびに、タイムスタンプ、データ件数、失敗レコードを含む完全なログを記録し、財務監査の要件を満たします。

## 実装ガイド

### 技術アーキテクチャ

本ソリューションは、DingTalk Open Platform のサーバー API を基盤に構築されています。主な技術コンポーネントは次のとおりです。

* **認証レイヤー**：`Client ID` と `Client Secret` を使って `access_token` を取得し、API 呼び出しの安全性を確保します。
* **スマート統計確認レイヤー**：API を呼び出して組織でスマート統計が有効になっているかを確認し、後続の API 呼び出しの失敗を防ぎます。
* **列定義管理レイヤー**：利用可能なすべての勤怠レポート列の ID と名前を取得し、後続のクエリの基本メタデータとして使用します。
* **列値クエリエンジン**：列 ID、ユーザー ID、日付範囲に基づいて、指標値を日ごとにクエリします。ページングとバッチ処理に対応しています。
* **データ集計・検証レイヤー**：日単位の元データを集計（合計、平均、カウント）し、データ整合性チェックを実行します。

**データフロー**：access\_token を取得 → スマート統計が有効であることを確認 → 列定義（列 ID のリスト）を取得 → 日付範囲を反復処理して列値を日ごとにクエリ → ローカルで集計（月次・四半期・年次）→ 最終レポートを出力。

### 前提条件

ソリューションを実装する前に、次の要件を満たしていることを確認してください。

* **アプリの準備**：社内アプリを作成して設定します。詳細は「アプリの作成と設定」を参照してください。
* **権限**：DingTalk の組織管理者またはサブ管理者の権限が必要です。
* **開発環境**：Java 開発環境（JDK 1.6 以降）と Maven ビルドツールをインストールします。
* **SDK の準備**：DingTalk のサーバーサイド SDK をダウンロードします。詳細は「サーバーサイド SDK のダウンロード」を参照してください。SDK は Java、Python、Go などの言語に対応しています。
* **スマート統計の有効化**：組織の勤怠アプリでスマート統計が有効になっていることを確認します。旧バージョンの UI では有効になっていない場合があるため、API を呼び出して確認してください。

### コード実装

1. ステップ 1：アプリ認証情報（クライアント ID と Client Secret）を取得します。

   ステップ 2：アプリのアクセス認証情報を取得します。詳細は [社内アプリの access\_token を取得する](https://help.dingtalk.io/ja/open/development/obtain-orgapp-token) を参照してください。API を呼び出す際、アクセストークンによって呼び出し元の ID が認証されます。

   ステップ 3：勤怠 API を呼び出します。

   1. サーバー API [スマート統計レポートが有効かどうかを確認する](https://help.dingtalk.io/ja/open/development/determine-whether-to-enable-attendance-intelligent-report.md) を呼び出し、スマート統計が有効であることを確認します。
   2. サーバー API [勤怠レポートの列定義を取得する](https://help.dingtalk.io/ja/open/development/queries-the-enterprise-attendance-report-column.md) を呼び出し、勤怠レポート列の `ID` を取得します。
   3. 勤怠レポート列の `ID` を使ってサーバー API [勤怠レポートの列値を取得する](https://help.dingtalk.io/ja/open/development/queries-the-column-value-of-the-attendance-report.md) を呼び出し、各列定義の値を取得します。
   4. 日単位の元データをローカルで集計し、月次・四半期・年次レポートを生成します。

## 実装手順

### **ステップ 1：アプリ認証情報を取得する**

1. [DingTalk 開発者コンソール](https://open-dev.dingtalk.io/) にログインします。
2. 対象のアプリを選択し、詳細ページを開きます。
3. **基本情報** > **認証情報と基本情報** をクリックします。
4. アプリの `Client ID` と `Client Secret` を控えておきます。

### 注意

`Client Secret` は安全に管理し、第三者と共有しないでください。ハードコーディングせず、環境変数や鍵管理システムに保存してください。

### **ステップ 2**：アクセス認証情報（access\_token）を取得する

ステップ 1 で取得した Client ID と Client Secret を使って、アプリのアクセス認証情報を取得します。詳細は [社内アプリの access\_token を取得する](https://help.dingtalk.io/ja/open/development/obtain-orgapp-token) を参照してください。

```java theme={"theme":{"light":"github-light","dark":"github-dark"}}
public void getAccessToken() throws ApiException {
  DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.io/gettoken");
  OapiGettokenRequest req = new OapiGettokenRequest();
  req.setAppkey("dingxxxxxxxxxhgn");
  req.setAppsecret("9G_xxxxxxxxxxxxxxx1JDf0Qq3nexxxxxxxxGIO");
  req.setHttpMethod("GET");
  OapiGettokenResponse rsp = client.execute(req);
  System.out.println(rsp.getBody());
}
```

**ベストプラクティス**：

* **キャッシュ**：`access_token` の有効期間は 2 時間です。メモリまたは Redis にキャッシュし、有効期限の 5分前に事前に更新してください。
* **同時実行制御**：複数のスレッドが同時にトークンを更新して競合しないよう、分散ロックを使用してください。
* **エラー時のリトライ**：ネットワークが不安定な場合は、間隔を段階的に延ばしながら（1 秒 → 2 秒 → 4 秒）最大 3 回まで自動でリトライしてください。

### ステップ 3：コア API を呼び出す

1. **スマート統計レポートが有効かどうかを確認する**：サーバー API [スマート統計レポートが有効かどうかを確認する](https://help.dingtalk.io/ja/open/development/determine-whether-to-enable-attendance-intelligent-report.md) を呼び出し、組織でスマート統計が有効になっていることを確認します。

### 注意

現在、勤怠アプリではスマート統計が有効になっています。ただし、旧バージョンの UI では有効になっていない場合があります。機能が無効なために後続の API 呼び出しが失敗しないよう、この API を呼び出して確認してください。

```java theme={"theme":{"light":"github-light","dark":"github-dark"}}
public void checkIsopensmartreportEnabled() throws ApiException {
  DingTalkClient client = new DefaultDingTalkClient("https://api.dingtalk.io/topapi/attendance/isopensmartreport");
  OapiAttendanceIsopensmartreportRequest req = new OapiAttendanceIsopensmartreportRequest();
  OapiAttendanceIsopensmartreportResponse rsp = client.execute(req, access_token);
  System.out.println(rsp.getBody());
   // レスポンスを解析し、enabled フィールドが true かどうかを確認する
}
```

2. **勤怠レポートの列定義を取得する**：サーバー API [勤怠レポートの列定義を取得する](https://help.dingtalk.io/ja/open/development/queries-the-enterprise-attendance-report-column.md) を呼び出し、利用可能なすべての勤怠レポート列の ID と名前を取得します。

### 注意

列定義には休暇申請の情報は含まれません。レポート内の休暇統計を取得するには、[レポートから休暇データを取得する](https://help.dingtalk.io/ja/open/development/obtains-the-holiday-data-from-the-smart-attendance-report.md) API を呼び出してください。

```java theme={"theme":{"light":"github-light","dark":"github-dark"}}
 public void attendanceColumns() throws ApiException {
    DingTalkClient client = new DefaultDingTalkClient("https://api.dingtalk.io/topapi/attendance/getattcolumns");
    OapiAttendanceGetattcolumnsRequest req = new OapiAttendanceGetattcolumnsRequest();
    OapiAttendanceGetattcolumnsResponse rsp = client.execute(req, "access_token");
    System.out.println(rsp.getBody());
}
```

3. **勤怠レポートの列値を取得する（日次）**：勤怠レポートの列 ID、ユーザー ID、日付を使ってサーバー API [勤怠レポートの列値を取得する](https://help.dingtalk.io/ja/open/development/queries-the-column-value-of-the-attendance-report.md) を呼び出し、各列定義の値を取得します。

   ```java theme={"theme":{"light":"github-light","dark":"github-dark"}}
    public void attendanceColumnsValue() throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://api.dingtalk.io/topapi/attendance/getcolumnval");
        OapiAttendanceGetcolumnvalRequest req = new OapiAttendanceGetcolumnvalRequest();
        req.setUserid("01472825524039877041");
        req.setColumnIdList("184678999,184727001");
        req.setFromDate(StringUtils.parseDateTime("2022-10-24 00:00:00"));
        req.setToDate(StringUtils.parseDateTime("2022-10-25 00:00:00"));
        OapiAttendanceGetcolumnvalResponse rsp = client.execute(req, "access_token");
        System.out.println(rsp.getBody());
   }
   ```
4. **データを集計・検証する**：日単位の元データをローカルで集計し、月次・四半期・年次レポートを生成します。

   ```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
   public Map aggregateMonthlyData(String userId, List columnIds, String startDate, String endDate) {
     Map result = new HashMap<>();

     // 各列の累計値を初期化する
     for (String columnId : columnIds) {
       result.put(columnId, 0.0);
     }

     // 日付範囲を反復処理する
     LocalDate start = LocalDate.parse(startDate);
     LocalDate end = LocalDate.parse(endDate);
     for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) {
       String workDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

       for (String columnId : columnIds) {
         try {
           double value = getColumnValue(userId, columnId, workDate);
           result.merge(columnId, value, Double::sum);
         } catch (Exception e) {
           log.warn("Query failed: userId={}, columnId={}, date={}", userId, columnId, workDate, e);
         }
       }
     }

     return result;
   }
   ```

**実装チェックリスト**：

* ✅ スマート統計が有効であることを確認済み。
* ✅ 利用可能なすべての列 ID のリストを正常に取得済み。
* ✅ 日次の列値 API が正常に動作し、有効なデータを返している。
* ✅ ローカルの集計ロジックがテストに合格し、結果が DingTalk の管理コンソールと一致している。
* ✅ エラーデータの処理が完了している（欠落した日付は 0 で補完、重複レコードは削除）。

## よくある質問

* **Q1：月次集計表を直接取得できないのはなぜですか？**

  A：DingTalk Open Platform は、定義済みの集計レポートではなく、**アトミックなデータ機能**を提供する設計になっています。理由は次のとおりです。

  * 柔軟性：「月次集計」の定義は組織によって異なります。暦月を使う組織もあれば、勤怠サイクルを使う組織もあります。オープン API により、開発者は独自の集計ロジックを定義できます。
  * パフォーマンス：社員数 1,000 人以上の組織の月次集計を 1 回のレスポンスで返すと、タイムアウトが発生するおそれがあります。日次クエリであれば、ページングやキャッシュを容易に適用できます。
  * データの鮮度：日次クエリはリアルタイムに最新データを返します。一方、月次集計表は通常 T+1 日目に更新されます。

    **推奨事項**：ローカルにデータウェアハウスを構築し、日次データを定期的に同期して、よく使う集計指標を事前に計算しておくと、鮮度とパフォーマンスを両立できます。
* **Q2：社員数 1,000 人以上の組織の月次データを効率よくクエリするには？**

  A：次の最適化戦略を活用してください。

  1. **並列バッチ処理**：社員リストを 1 バッチあたり 50〜100 人、計 10〜20 バッチに分割し、スレッドプールで並列にクエリします。
  2. **日付範囲の絞り込み**：営業日のデータのみが必要な場合は、先に週末と祝日を除外します。これにより、不要なクエリを 30%〜40% 削減できます。
  3. **キャッシュの活用**：同じ日付範囲内で同じ列 ID のクエリ結果をキャッシュし、重複した呼び出しを避けます。
  4. **増分同期**：初回の全件同期後は、新規または変更されたデータのみを毎日同期し、日常的な運用コストを大幅に削減します。
* **Q3：期間の途中で入社・退職した社員の日付が欠ける場合はどう処理しますか？**

  A：勤怠レポート API は、各社員の実際の在籍期間に基づいてデータを自動で返します。

  * **入社前の日付**：空値または 0 が返されます。ローカルのロジックでこれらの日付をスキップしてください。
  * **退職後の日付**：同様に空値または 0 が返されます。
* **Q4：列 ID は変わりますか？定期的に再取得する必要がありますか？**

  A：組織でスマート統計を有効にした後、列 ID は通常は変わりません。ただし、次の場合に変わることがあります。

  * **DingTalk のバージョンアップ**：新しい統計指標が導入されると、新しい列 ID が追加されます。
  * **組織のカスタムフィールド**：組織でカスタムの勤怠ルールを設定すると、専用の列 ID が生成される場合があります。
  * **推奨事項**：「勤怠レポートの列定義を取得する」API を毎週または毎月呼び出し、ローカルの列 ID マッピングテーブルを更新して互換性を確保してください。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.