Mac純正アプリだけでタイムレコーダーを作るプロジェクトの第3回目に突入します。どうも、私(@saosaoyamayama)です。
前回は稼働開始・終了時に押すスタート・ストップボタンを作成し、1稼働ごとのラップタイムを計算・出力させました。
今回は、1日の稼働集計や月間稼働を報告するショートカットのうち、主に計算を担う3つを作ります。
長丁場になるので、ご飯食べてから作業しましょう。
Contents
報告書出力ショートカット概要
今回作るのは4番目「報告」の中の「5・6・7」です。
ショートカット.appってファイル操作やリマインドなど「目に見える」便利機能が満載なわけですが、実は計算もできます。本当に万能。
私の仕事では、以下の項目を必ず報告しなければなりません。
- 稼働開始時刻・終了時刻◆1
- 1日の稼働時間◆1
- 当日までの合計稼働時間(当月)◆2
- 契約時間の残り時間◆2
- 契約時間超過の場合は超過時間◆2
- 次回稼働予定日時 ◆3
……計算が必要な項目ばかりです。
これらを1つのショートカットにまとめると、ミスが出た時の確認が煩雑になるため、報告出力ショートカットの中に当日集計(◆1)・月間集計(◆2)・次回稼働確認(◆3)の3つのショートカットを入れました。
出力結果は画像の右下。実務ではChatworkやSlackにそのまま貼り付けられるように、装飾コードや冒頭挨拶なども併せて出力しています。
それでは、◆1→◆2→◆3の順で解説しまーす!
◆1. 当日集計ショートカット作成
合計稼働時間を集計、稼働時刻とともに出力するショートカットです。ストップボタンで出力した当日予定のメモ欄のデータを使って計算するので、メモ欄に稼働時間(単位は「分」)が正しく出力されているか予め確認しておきましょう。
当日集計で面倒なのが、○分→「○時間○分」への変更です。この辺りはNotionでも苦労しました。計算にあたっては変数指定を間違えないようにご注意ください。
- 当日分の予定をすべて抽出
- メモ欄の情報をすべて取得
- メモ欄から稼働時間を抽出・合計
- メモ欄から稼働時刻を抽出・連結
- 稼働時間をフォーマット
- 報告テキストにまとめる
こんな流れになっております。
当日使った予定(カレンダー.app)取得〜稼働時間合計
当日予定を検索・整列:変数1
《カレンダーの予定を検索》で、当日に作成(終了)した予定をすべてピックアップします。1日に複数回稼働した場合は複数あるはずですね。
検索条件設定のポイントは名前と制限と並び順。名前に「-終了」が付いている予定だけを拾えるようにフォーマットしています。
また予定の取得順序は「古い順」です。制限は「なし」にして、複数の予定が拾えるようにしました。古い順に並べる理由は後ほど解説します。集計するだけなら順序は問いません!
予定のメモ欄を取得:変数2
《カレンダーの予定の詳細を取得》を使い、ピックアップした予定(変数1)のメモ欄からすべての情報を抽出します。
変数を指定したらショートカットを動かして、データが取得できるかチェックしておきましょう。
複数回稼働した時は、出力エリアにページャー(ページ送りみたいなもの)が表示され、クリックすると別のデータが表示されます。
データが取得できない時は、カレンダーの予定に「終了」が付いているか、そもそも予定のメモ欄に稼働データが出力されているか確認してくださいね。
稼働時間を抽出・合計:変数4
予定メモ欄から取得したテキストのうち、★に挟まれたテキスト=稼働時間だけ抽出します。
《一致するテキスト》で「(?<=[★]).*?(?=[★])」という正規表現を使うと、★を除くテキストだけ取り出せました(変数3)。
この時のために稼働時間を「★」で括ったんですよ! でも正規表現に詳しい人は別の方法で大丈夫です。私、正規表現ビギナーなので……。
たとえば、稼働時間が60分・20分の2回だったら「60 20」が変数3に入っています。コレを合計すれば、当日の稼働時間が算出できますね!
ということで《統計を計算》を使って変数3の合計を算出しました。ここでショートカットのチェックをしておくと安心です。
当日の稼働状況取得〜報告テキスト作成
稼働時刻の抽出・連結:変数6
ここでいう稼働時刻ってのは「9:54〜10:35」を指します。複数回稼働した日は複数個あるはずですね。
まずテキストの抽出には正規表現の一致を使いました。《一致するテキスト》で「.*〜.*」を使うと、「〜」を含めて取り出せます。これを変数5としました。
次に、取得した時刻を「9:54〜10:35,12:15〜14:30」のようにカンマ区切りで並べます。ここで使うのは《テキストを結合》です。
変数5のデータを「,」で結合させればOK。稼働が1回の場合はカンマが付きません。気が利いていますな!
なお、変数1で予定の並び順を「古い順」に指定したので、時刻データは勝手に古い順に並びます。
稼働時間のフォーマット:変数8・10
変数4として、稼働時間の合計を取得しました。この単位は「分」です。しかし報告書には「○時間○分」で記載したい。ここで計算の登場です。
- 稼働(分)÷60=○時間…あまりを切り捨て:変数8
- 稼働(分)-(○時間×60)=○分:変数10
これをやっています。使うのは《計算》《端数を処理》の2アクションです。図を参考にして組み立ててみてください〜。
ポイントは《端数を処理》のモード変更です。「表示を増やす」をクリックするとモードが選択できますので「常に切り捨て」を選びましょう。
報告テキスト作成
最後に、変数8・10・6を《テキスト》に入れて、報告文面のパーツを作ります。変数とテキストを組み合わせて好きなように整えましょう。
これで「当日集計」のショートカットは完成です!
◆2:月間集計ショートカット作成
今月(当月)何時間働いたのか、契約時間に対して残りは何時間なのか、何時間超過しているのか、を算出・出力するショートカットです。
- 必要な変数パーツ作成
- 当月の全予定を抽出
- メモ欄の情報をすべて取得
- 稼働時間を合計してフォーマット
- 残時間を計算してフォーマット
- 超過判定
- 超過していたら時間を計算してフォーマット
- 報告テキストにまとめる
これまで解説してきたアクションを組み合わせるだけですが、とにかく計算結果が大量に発生するので変数指定の間違いが起きやすいかもしれません。
長いので3つに分けて説明します。
当月の予定ピックアップ〜メモ欄取得
変数パーツ作成:変数1〜3
まずは《数字》に契約時間を「分」で入力しました(変数1)。仕事の契約が1ヵ月○時間以上働くという形なので、これが必須です。
画像では月20時間契約、「分」に換算すると1,200分なので「1200」と入力してあります。
※つい最近「○時間○分」というテキストを入力して自動的に「分」に変更できるように改良しました。
次に「当月」を定義する日付を変数2・3として設定します。ここはめちゃくちゃ苦労したポイントです……。
1ヵ月の集計をする場合、月初1日〜月末日のデータを使いますが、毎月手打ちで日付を入力せず、自動で集計月が切り替わるようにしたい。そうすると常に「今」を追っている「現在の日付」を起点に考える必要があります。
まず月初1日については《日付を調整》が使えました!「現在の日付」から「開始の月を取得」で当月1日を取得してくれます(変数2)。
月末日を取得するアクションが見つからなかったので《日付を調整》で翌月1日を取得し、代用することに(変数3)。
当月分の予定のメモ欄取得:変数5
今月の稼働に関与している予定をすべて取得します。変数2(当月1日)〜変数3(翌月1日)の予定で「終了」が付いているものですね。
ここで重要なのが、月初1日(変数2)のフォーマットです。フォーマットせずに使うと、月初1日目のデータが漏れるケースがありました。
カレンダーでやり取りされる日付は、かならず時間の概念を持っています。そのため「開始の月を取得」で取得した月初日も同様です。そして「月初」だからって時間が「00時00分」とは限りません。
当月1日を指定する時は、カスタムフォーマットで時刻を「00:00」に指定しましょう。
ということで、当月1日についてはカスタムフォーマットを使って「yyyy/MM/dd 00:00」にしました。これで今のところ漏れなく取得できています。
※なお、時間のフォーマットをナシにすれば良いのでは? と思ってやってみましたが、うまくいかず……。
続いて、検索で得たすべての予定のメモ欄から、テキストを取得します。これを変数5としてこの後使ってきますよ。
稼働時間・残時間計算〜成形
当月の合計稼働時間と、契約残時間を集計するショートカットです。やっていることは当日集計と同じなので、細かい指定やフォーマットは当日集計の項目を参考にしてくださいね。
まず月間の合計稼働時間は、★に挟まれた数字を1ヵ月分抽出して合計し(変数6)、○時間○分に変更しました。これで変数16(時間)・17(分)ができあがります。
契約残時間については、冒頭で作った契約時間(変数1)の出番です。契約時間から当月稼働時間(変数6)を引き算して成形するだけ。これで変数18(時間)・19(分)のできあがり。
超過判定〜報告テキスト作成
契約時間に対して超過しているかどうかを判定し、超過していたら超過時間を計算、報告文面を作るまでのショートカットです。
ここでは「ややこしい of ややこしい」でお馴染みのIF文を使います。変数6(合計稼働時間)と変数1(契約時間)を比較して、稼働時間のほうが大きければ超過です。
《IF文》を1つ追加すると、アクションブロックが3段表示されます。段の間に必要なアクションをポンポン入れていきましょう。
まず超過していると判断した場合、稼働時間から契約時間を引いて「○時間○分」に変更、《テキスト》で報告文面のパーツを作っておきます。
超過していない場合は「00時間00分」が出力できるように《テキスト》に記入しておきました。IFの結果がどちらになっても、最終的に「テキスト」が出力されますね。
そして最後に、合計稼働の変数16(時間)・17(分)、残時間の変数18(時間)・19(分)、超過時間には「IF文の結果」という変数を指定して報告テキストを作成したら完了です!
◆3:次回稼働日判定のショートカット作成
報告書に「次回稼動予定日時」を記載したいので、判定&テキスト作成ショートカットを作ります。
- 今日が金曜日:3日後(月曜)の日付を出力
- 今日が金曜日以外:1日後の日付を出力
これを叶えるために、IF文を使うことにしました。出力結果を《テキスト》にまとめて完了です。
祝日判定をする場合、カレンダーに入っている「祝日カレンダー」を使うことになるかなと思います。
次回は次回稼働確認&報告書を作ります!
次回はいよいよ最終回です。
報告書を出力するボタンの本体と、ショートカットをカンタンに発動できるようにアプリ化しますよ〜!
うまく動かない・もう少し詳しく聞きたい……などあれば、お問い合わせからご連絡いただくか、X(@saosaoyamayama)のDMでご連絡くださいませ。