みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
Googleカレンダーの記録をスプレッドシートに書き出して活用する方法についてお伝えしています。
前回の記事はこちら。
カレンダーイベントの場所、説明をスプレッドシートに書き出す方法をお伝えしました。
さて、イベント情報の出力から生産性を測るために、出力したイベントに対してスプレッドシート関数を使っていろいろと自動集計をかけたいところです。
そこで、GASでその計算をする数式も入力してしまおうと思います。
ということで、Google Apps Scriptで時刻計算と文字列抽出の数式を入力する方法をお伝えします。
では、行ってみましょう!
前回のおさらい
前回作成したスクリプトはこちらです。
const CALENDAR_ID = '**********'; //カレンダーID function getCalendarEvents() { const calendar = CalendarApp.getCalendarById(CALENDAR_ID); const startTime = new Date('2020/04/01 00:00:00'); const endTime = new Date('2020/05/01 00:00:00'); const events = calendar.getEvents(startTime, endTime); const values = []; for(const event of events){ const record = [ event.getTitle(), event.getStartTime(), event.getEndTime(), event.getLocation(), event.getDescription() ]; values.push(record); } SpreadsheetApp.getActiveSheet().getRange(2, 1, values.length, values[0].length).setValues(values); }
実行すると、以下のように指定した月のイベント情報をシートに書き出すことができます。
各列の役割はこちらです。
- A列: タイトル
- B列: 開始日時
- C列: 終了日時
- D列: 場所
- E列: 説明
数式で算出したいもの
今回、スプレッドシート関数の数式で算出したいものは2つあります。
ひとつは、イベントの工数です。
これは、終了日時から開始日時を引き算すれば計算可能です。
もうひとつは、イベントのカテゴリです。
シリーズ初回の記事でお伝えしているのですが、プロジェクトごとに【プロジェクトID】【コミュ】【ブログ】…というように、隅カッコでプロジェクトの目印を付与していました。
これをカテゴリとして別の列に抽出できれば、プロジェクトごとの集計ができるようになりそうです。
イベント情報と数式をシートに書き出すスクリプト
スクリプトを実行してイベント情報をシートに書き出す際に、これらの数式も追加で書き出すようにしていきます。
そうすれば、書き出したそばから自動でそれらの計算をしてくれますよね。
まず、そのようにしたスクリプトを紹介しましょう。
こちらです。
const CALENDAR_ID = '**********'; //カレンダーID function getCalendarEvents() { const calendar = CalendarApp.getCalendarById(CALENDAR_ID); const startTime = new Date('2020/04/01 00:00:00'); const endTime = new Date('2020/05/01 00:00:00'); const events = calendar.getEvents(startTime, endTime); const values = []; for(const event of events){ const record = [ event.getTitle(), event.getStartTime(), event.getEndTime(), event.getLocation(), event.getDescription(), '=INDIRECT("RC[-3]",FALSE)-INDIRECT("RC[-4]",FALSE)', '=IFERROR(SUBSTITUTE(LEFT(INDIRECT("RC[-6]",FALSE),FIND("】",INDIRECT("RC[-6]",FALSE))-1),"【",""),"")' ]; values.push(record); } SpreadsheetApp.getActiveSheet().getRange(2, 1, values.length, values[0].length).setValues(values); }
19, 20行目をご覧ください。
19行目が、イベントごとの所要時間を算出する数式。
20行目が、イベントタイトルからカテゴリを抽出する数式です。
ご覧の通り、配列内に数式を含める場合、それをダブルクォーテーションで囲めばOKです。
各数式について、以下解説をしていきます。
イベントの所要時間を算出する
まずはイベントの所要時間の算出からです。
これは、終了日時から開始時間を減算する簡単な数式で実現可能です。
ただ、通常のスプレッドシート関数であれば、ひとつの式を入力して、別の行にコピーをしていけば、相対参照の機能で、その数式で指し示す行数も自動でずれていってくれるのですが、今回はそうはいきません。
そこで、A1形式ではなくて、R1C1形式を使います。
R1C1形式を使うと、現在のセルを起点にして、参照するセルを「今のセルから左に3列」といった指定の仕方が可能になります。
それを実現しているのが、INDIRECT関数です。
第二引数をFALSEにすれば、A1形式ではない、つまりR1C1形式になります。
Rは行、Cは列を表しますので、行は同じで列は今のセルから左に3つであれば、その文字列は「RC[-3]」となります。
所要時間をF列に出力するなら、終了日時は-3列、開始日時は-4列ですから、以下の数式で計算可能です。
'=INDIRECT("RC[-3]",FALSE)-INDIRECT("RC[-4]",FALSE)'
文字列から墨付きカッコ内のテキストを抜き出す
続いて、イベントのカテゴリをA列のイベント名隅カッコの中から抜き出します。
例えば、タイトルが「【勉強】jQuery」であれば「勉強」と出力したいわけです。
この場合、スプレッドシートの5つの関数を駆使します。
FIND関数で特定の文字の位置を調べる
まず、最初の手順として「閉じる方の」墨付きカッコ、つまり「】」の位置を調べて、その手前までを切り取って抜き出すということをします。
特定の文字の位置を調べるにはFIND関数を使います。
文字の位置なので、その文字が何文字目かを返します。
以下のようにすれば、閉じる方の墨付きカッコは4文字目ですから「4」という値が返ります。
今回、例えばA2セルに「【勉強】jQuery」が入力されているとすると、以下のようになります。
=FIND("】", A2)
LEFT関数で文字列を指定位置まで切り取る
FINDのおかげで、閉じる法の墨付きカッコの位置がわかりましたので、文字列をそこまでで切り取ってしまいます。
文字列を左から切り取るにはLEFT関数を使います。
今回は、隅カッコ「】」は除外したいので、FIND関数の戻り値のマイナス1までをLEFT関数で切り取ります。
=LEFT(A2, FIND("】", A2) - 1)
これで「【勉強」という文字列が返ります。
SUBSTITUTE関数で文字を置き換える
続いて「始まる方の」墨付きカッコが残っているので、これを削除します。
特定の文字を削除するにはSUBSTITUTE関数を使います。
今回の場合は検索文字列は「【」、置換文字列は空文字にすればOKですから、以下のようにします。
=SUBSTITUTE(LEFT(A2, FIND("】", A2) - 1), "【", "")
これで「勉強」が返りますね。
IFERROR関数でエラー時に空欄にする
しかし、A2セルに隅カッコがない場合は、数式の計算結果が「#VALUE!」となってしまいます。
これは、FIND関数で目的文字「】」が見つからないからです。
そこで、エラー値のときは空欄になるようにIFERROR関数も使っておきます。
IFERROR関数は、式の結果がエラー値の際に代替の値を返すというものです。そうでない場合は、式の結果をそのまま返します。
以上をまとめるとこうなります。
=IFERROR(SUBSTITUTE(LEFT(A2, FIND("】", A2) - 1), "【", ""), "")
INDIRECT化する
さらに、「A2」のようにA1形式は使えませんので、R1C1形式を使います。
今回の場合、G列に書き出したいので、対象となるA列は列方向にマイナス6です。
ですから、「A2」の代わりに、以下を使います。
INDIRECT("RC[-6]", FALSE)
つまりこうなります。
=IFERROR(SUBSTITUTE(LEFT(INDIRECT("RC[-6]", FALSE), FIND("】", INDIRECT("RC[-6]", FALSE)) - 1), "【", ""), "")
これで数式の完成です!
イベントの情報と数式をシートに書き出す
では、スクリプトを実行してみましょう。
出力結果はこうなります。
小数の桁数が多いので、以下のように小数点以下を2桁などにしておくと見やすいです。
ちなみに、表示形式で「経過時間」に変更をしないようにしておきましょう。
あとでQUERY関数を使うのであれば、その集計するときに困りますので。
その辺は後の記事で紹介します。
まとめ
以上、Google Apps Scriptで時刻計算と文字列抽出の数式を入力する方法をお伝えしました。
二次元配列に数式を入れるだけならなんてことないですが、数式自体がなかなか複雑でしたね…!
でも一度作ってしまえばあとは楽ですから。
さて、次回は任意の月について書き出せるようにスクリプトを改善していきます。
どうぞお楽しみに!
連載目次:GASとカレンダーの記録を活用して過去の仕事を振り返る
企業ではスプレッドシートを勤怠管理やプロジェクト進捗管理などに使っている場合も多いと思います。このシリーズでは、カレンダーとスプレッドシート、そしてGoogle Apps Scriptを使って仕事の生産性を測定する方法についてお伝えしています。- GASで仕事の生産性を測定して振り返るためのGoogleカレンダーの使い方
- Google Apps ScriptでGoogleカレンダーを操作する最初の一歩のスクリプト
- Google Apps Scriptで特定月のカレンダーのイベント情報を取得する
- Google Apps ScriptでGoogleカレンダーの記録をスプレッドシートに出力する
- Google Apps ScriptでGoogleカレンダーの場所・説明を取得する方法
- Google Apps Scriptで時刻計算と文字列抽出の数式を入力する方法
- Google Apps Scriptで任意の月のカレンダーデータをスプレッドシートに書き出す方法
- Googleカレンダーの記録を活用してスプレッドシートに業務別の工数計算