関連記事
3つの記事に分けていますので参考にしてください
- 業務スケジュールパターン
- 業務スケジュール設計(今回の記事)
- 業務スケジュール実装
業務スケジュール生成システム 設計ドキュメント
目次
概要
本システムは、Office Scripts for Excelを利用して、企業や組織における日常的な業務スケジュールを自動生成するためのツールです。業務一覧テーブルに定義された様々な条件に基づいて、特定の日付に実行すべき業務を判定し、スケジュールとして出力します。
システムの背景には、以下のような課題があります:
- 日次・週次・月次・年次など様々な周期で実行される業務の管理が煩雑
- 手動での業務スケジュール作成に時間と労力がかかる
- 実行条件の複雑さ(営業日基準、暦日基準、曜日指定など)による漏れや誤りのリスク
- 祝日や休業日に当たる場合の振替処理の対応
これらの課題を解決するために、本システムでは以下の特徴を持つスケジュール生成機能を実現しています:
- 多様な業務パターンへの対応(日次、週次、月次、年次、特定日付、特定曜日など)
- 営業日・非営業日を考慮した業務スケジュール生成
- 非営業日の場合の振替ルール(直前営業日、直後営業日、振替なし)
- 詳細なデバッグ機能によるトラブルシューティングのサポート
- Excelテーブルとの連携による使いやすいインターフェース
本システムの利用により、業務スケジュールの作成時間の大幅な削減、業務漏れの防止、業務実行の標準化と効率化を実現し、組織の業務品質向上に貢献します。
システム構成
データ構造
システムは以下の3つの主要なデータテーブルを使用します:
1. カレンダーテーブル
- 日付ごとの営業日情報を格納
- 列構成:
- 年月日(YYYY-MM-DD形式):カレンダーの基準日
- 営業日フラグ(TRUE/FALSE):営業日かどうかを示すフラグ
- 備考(祝日名など):休日理由や特記事項
- 曜日:月、火、水、木、金、土、日
- 営業日:月内での営業日番号(1始まり)
- 逆算営業日:月末からの営業日カウント(最終営業日=0)
2. 業務一覧テーブル
- 業務の基本情報と実行条件を格納
- 列構成:
- 業務ID(一意の識別子):各業務を識別する一意のID
- 業務名:業務の名称
- 業務詳細:業務内容の詳細説明
- 業務種別:「定常」「依頼」など業務の種類
- 周期・頻度(日次/週次/月次/年次):業務の実行周期
- 基準:業務実行の基準日の決定方法
- 暦日:暦上の日付による指定
- 営業日:営業日カウントによる指定
- 暦日(n日指定):毎月特定の日(例:毎月15日)
- 営業日(n日指定):特定の営業日(例:第3営業日)
- 暦日(月末逆算):月末からの逆算(例:月末3日前)
- 営業日(月末逆算):月末からの営業日カウント(例:最終営業日から2営業日前)
- 暦日(曜日):特定の曜日(例:毎週月曜)
- 月(特定月を指定、年次業務の場合):1~12の月指定
- 週番号(第何週か、1-5):第何週かを指定
- 曜日(月-日):曜日指定
- n日(日にちや営業日番号):何日目かを指定
- 非営業日振替規則:非営業日だった場合の振替方法
- 直前営業日:非営業日なら直前の営業日に振替
- 直後営業日:非営業日なら直後の営業日に振替
- 振替しない:非営業日でも日付変更しない
- 優先度:業務の優先順位(高/通常/低など)
- 有効開始日:業務の有効期間開始日
- 有効終了日:業務の有効期間終了日(空欄は無期限)
- 備考:その他補足情報
3. スケジュールテーブル
- 生成された業務スケジュールを格納
- 列構成:
- スケジュールID(一意の識別子):各スケジュールの一意のID
- 業務ID(業務一覧の業務を参照):業務一覧テーブルの業務ID
- 予定日:業務の予定実施日
- 作業者:担当者名(手動入力項目)
- 開始予定時刻:予定開始時間(手動入力項目)
- 実開始時刻:実際の開始時刻(手動入力項目)
- 実終了時刻:実際の終了時刻(手動入力項目)
- ステータス:「未実施」「進行中」「完了」など(手動入力項目)
- メモ:作業メモや結果(手動入力項目)
テーブルの関係図
ファイル構成
-
scheduler.osts
: Office Scripts for Excelのメインスクリプトファイル - Excelファイル: 上記3つのテーブルを含むExcelファイル
システム全体構成図
データフロー概要
機能仕様
業務スケジュール生成機能
- 機能概要: 指定された日付に実行すべき業務を判定し、スケジュールを生成
- 入力: 対象日付(YYYY-MM-DD形式、YYYY/MM/DD形式、またはM/D/YYYY形式)
- 出力: スケジュールテーブルへの業務登録
-
処理内容:
- 入力日付の正規化(複数の日付形式に対応)
- カレンダー情報の読み込み
- 業務一覧データの取得
- 既存スケジュールの確認(同日のスケジュールが存在する場合は処理中断)
- 業務条件判定(通常判定)
- 振替判定(他の日付からの振替対象かどうか)
- 対象業務のスケジュールテーブルへの登録
- 処理結果のログ記録
日付処理機能
- 機能概要: 様々な形式の日付を扱うためのユーティリティ関数群
-
主要機能:
- 日付形式変換(Excel日付⇔文字列)
- 特定の日付の情報取得(年、月、日、曜日など)
- 月末日の取得
- 月の第n曜日の取得
- 月のn営業日目の取得
- 月末からn営業日前の日付取得
営業日判定機能
- 機能概要: カレンダーデータに基づく営業日関連の処理
-
主要機能:
- 指定日が営業日かどうかの判定
- 特定日の直前/直後の営業日の取得
- 月内での営業日情報(何営業日目か、月末から何営業日前か)の取得
業務条件判定機能
-
機能概要: 業務データの実行条件に基づく判定
-
対応条件:
-
日次業務
- 暦日指定(毎日)
- 営業日指定(営業日のみ)
-
週次業務
- 暦日(曜日)指定(特定の曜日)
-
月次業務
- 暦日(n日指定)(例:毎月10日)
- 暦日(月末逆算)(例:月末、月末から3日前)
- 営業日(n日指定)(例:毎月第3営業日)
- 営業日(月末逆算)(例:毎月最終営業日)
- 暦日(曜日)(例:毎月第2火曜日)
-
年次業務
- 特定月 + 上記の月次条件(例:3月の第2営業日)
-
-
追加条件判定:
- 有効期間: 有効開始日~有効終了日の範囲内であることを確認
- オリジナル条件判定: 振替先を判定するため、基本条件のみに基づいた判定も実施
- 複合条件: 複数の条件を組み合わせて(例:特定月の特定曜日)業務対象日を判定
振替規則処理機能
- 機能概要: 非営業日に当たる業務の振替処理
-
振替規則:
- 直前営業日: 非営業日の場合、直前の営業日に振替
- 直後営業日: 非営業日の場合、直後の営業日に振替
- 振替しない: 非営業日でも振替を行わない
-
振替処理の方向:
- 本来の実行日から振替日を算出(通常の条件判定)
- 振替先の日付から元の日付を検証(振替対象日判定)
- これにより、もとの日付が検索対象外の場合でも振替が適切に処理される
デバッグ機能
- 機能概要: 処理中のログを記録
-
処理内容:
- デバッグシートの作成・管理
- ログレベル(info/warning/error)に応じたログ記録
- 処理の各ステップでの状態記録
処理フロー
メイン処理フロー
業務条件判定フロー
振替規則処理フロー
振替先の日付を検証するフロー
型定義
システムで使用される主要な型定義:
/**
* カレンダー情報を保持する型
* 日付文字列をキー、営業日フラグを値とするマップ
*/
type CalendarInfo = { [date: string]: boolean };
/**
* 営業日情報を表す型
*/
type BusinessDayInfo = {
nth: number; // 月内での営業日番号(1始まり)
total: number; // 月内の営業日総数
reverse: number; // 月末から数えた営業日番号(最終営業日=0)
};
/**
* 日付情報を表す型
*/
type DateInfo = {
year: number; // 年
month: number; // 月(1-12)
day: number; // 日
dayOfWeek: number; // 曜日(0:日, 1:月, ..., 6:土)
isBusinessDay: boolean; // 営業日かどうか
};
関数仕様
システムの主要関数は以下の通りです(抜粋):
メイン関数
-
main(workbook: ExcelScript.Workbook, targetDate: string = "")
: スクリプトのエントリーポイント。業務スケジュールの生成を実行します。
日付処理関数
-
excelDateToString(excelDate: string | number | Date | boolean): string
: Excel形式の日付を標準的な日付文字列(YYYY-MM-DD形式)に変換します。 -
formatDate(date: Date): string
: 日付オブジェクトをYYYY-MM-DD形式の文字列に変換します。 -
formatDateBySlash(date: Date): string
: 日付オブジェクトをYYYY/MM/DD形式の文字列に変換します。 -
getDateInfo(dateStr: string, calendar: CalendarInfo): DateInfo
: 日付文字列から日付の詳細情報を取得します。
営業日判定関数
-
isBusinessDay(inputDate: string, calendar: CalendarInfo): boolean
: 指定日が営業日かどうかを判定します。 -
getBusinessDayInfo(inputDate: string, calendar: CalendarInfo): BusinessDayInfo
: 指定日の営業日情報を取得します。 -
getPreviousBusinessDay(inputDate: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): string
: 指定日の直前営業日を取得します。 -
getNextBusinessDay(inputDate: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): string
: 指定日の直後営業日を取得します。 -
getNthBusinessDayOfMonth(year: number, month: number, n: number, calendar: CalendarInfo, workbook: ExcelScript.Workbook): string
: 指定月のn営業日目の日付を取得します。 -
getReverseNthBusinessDayOfMonth(year: number, month: number, n: number, calendar: CalendarInfo, workbook: ExcelScript.Workbook): string
: 指定月の末日からn営業日前の日付を取得します。
業務条件判定関数
-
isTargetTask(inputDate: string, taskData: (string | number | boolean)[], headers: string[], calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 指定された業務が対象日に実行すべきかを判定します。 -
isDailyTask(inputDate: string, base: string, calendar: CalendarInfo): boolean
: 日次業務の判定を行います。 -
isWeeklyTask(inputDate: string, base: string, youbi: string): boolean
: 週次業務の判定を行います。 -
isCalendarDayNthTask(inputDate: string, n: number, furikae: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 暦日(n日指定)の判定を行います。 -
isCalendarDayEndOfMonthTask(inputDate: string, n: number, furikae: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 暦日(月末逆算)の判定を行います。 -
isBusinessDayNthTask(inputDate: string, n: number, calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 営業日(n日指定)の判定を行います。 -
isBusinessDayEndOfMonthTask(inputDate: string, n: number, calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 営業日(月末逆算)の判定を行います。 -
isCalendarDayWeekDayTask(inputDate: string, youbi: string, weekNum: number, furikae: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 暦日(曜日)の判定を行います。
振替規則処理関数
-
applyFurikaeRule(inputDate: string, rule: string, calendar: CalendarInfo, workbook: ExcelScript.Workbook): string
: 振替規則を適用して日付を計算します。 -
isTargetDateForFurikae(inputDate: string, taskData: (string | number | boolean)[], headers: string[], calendar: CalendarInfo, workbook: ExcelScript.Workbook): boolean
: 指定日が他の日付の振替先になっているかを判定します。
ユーティリティ関数
-
prepareCalendarMap(workbook: ExcelScript.Workbook): CalendarInfo
: カレンダーデータを準備します。 -
getScheduleSheet(workbook: ExcelScript.Workbook)
: 業務スケジュールシートを準備します。 -
getExistingScheduleInfo(scheduleSheet: ExcelScript.Worksheet): { lastRowIndex: number, maxScheduleId: number }
: 既存のスケジュールデータの最終行と最大スケジュールIDを取得します。 -
debugLog(workbook: ExcelScript.Workbook, message: string, level: "info" | "warning" | "error" = "info"): void
: デバッグログを記録します。 -
create_debug_sheet(workbook: ExcelScript.Workbook, isClear = false)
: デバッグシートを作成します。
エラー処理
システムは以下のエラー処理を実装しています:
- 例外捕捉: 主要な関数では例外をtry-catch文で捕捉し、エラー情報をデバッグログに記録
- エラーメッセージ: 重要なエラーはエラーメッセージとして表示
-
回復処理: 一部のエラー(テーブル取得エラーなど)では代替手段での処理を試行
- テーブルからのデータ取得失敗時にシートから直接取得を試行
- 日付変換に複数の形式対応
- 入力検証: 日付の形式検証や有効性確認を実施
- デフォルト値: エラー時には安全なデフォルト値を使用
- デバッグログ: すべての主要な処理ステップとエラーを詳細にログに記録
拡張性と制限事項
拡張性
- 新しい業務条件: 周期・頻度や基準の種類を追加することで、新しい業務条件への対応が可能
- 追加フィールド: 業務一覧やスケジュールテーブルに新しいフィールドを追加可能
- 処理カスタマイズ: 各種判定ロジックはモジュール化されており、カスタマイズが容易
-
将来の拡張可能性:
- 作業者マスター: 担当者情報を管理するテーブルを追加して作業者の割り当て機能
- Power BI連携: 生成されたスケジュールデータをPower BIで可視化
- 複数条件対応: 「第1と第3金曜日」のような複合条件への対応
- 繰り返し情報: 年次・月次等の識別情報をスケジュールに追加
- パフォーマンス指標: 作業時間や遅延率などのKPI測定
制限事項
- 日付範囲: カレンダーテーブルに登録されている日付範囲内でのみ正確に動作
- テーブル構造: 想定されるテーブル構造(列名など)に依存
- 処理速度: 大量の業務データや長期間のスケジュール生成では処理時間が増加する可能性
- 非営業日判定: カレンダーテーブルの営業日フラグに依存
-
既知の制限:
- 複数の条件を組み合わせた業務(例: 第1と第3金曜日)は別々のレコードとして登録が必要
- 非定型的な業務(特定の日付のみ、不規則なパターンなど)への対応には個別レコードが必要
- 依存関係のある業務(Aの完了後にBを実行など)のスケジューリングには非対応
運用方法
前提条件
- Excelファイルには、カレンダー、業務一覧、スケジュールの3つのシートが必要
- カレンダーデータは最新の休日情報で更新されていること
- 業務一覧には有効な業務データが登録されていること
使用手順
-
準備:
- Excelファイルを開く
- 必要に応じてカレンダーデータや業務データを更新
-
スケジュール生成:
- 「業務スケジュール」シートのB1セルに対象日付を入力
- スクリプトを実行
-
結果確認:
- 生成されたスケジュールを確認
- 必要に応じてデバッグログを確認
-
カスタマイズ:
- 業務一覧を編集して対象業務を追加・変更
- 振替規則や条件を調整
使用例
例1: 月初の業務スケジュール生成
// B1セルに「2025-05-01」を入力
// スクリプトを実行
// → 月初に実行すべき業務(毎日業務、営業日業務、月初業務、第1営業日業務など)が抽出される
例2: 月末の業務スケジュール生成
// B1セルに「2025-05-31」を入力
// スクリプトを実行
// → 月末に実行すべき業務(毎日業務、営業日業務、月末業務、最終営業日業務など)が抽出される
例3: 連休前の一括スケジュール生成
// 連休期間の各日付を順に入力し、それぞれに対してスクリプトを実行
// → 連休期間中の全ての業務が抽出され、必要に応じて営業日に振り替えられる