みなさん、こんにちは!
タカハシ(@ntakahashi0505 )です。
Googleカレンダーの記録をスプレッドシートに書き出して活用する方法 についてお伝えしています。
前回の記事はこちら。
Google Apps ScriptでGoogleカレンダーの場所・説明を取得する方法
Googleカレンダーの記録をスプレッドシートに書き出して活用する方法についてお伝えしています。今回はGoogle Apps Scriptで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関数 です。
INDIRECT (セル参照の文字列, [A1形式にする])
第二引数をFALSEにすれば、A1形式ではない、つまりR1C1形式になります。
Rは行、Cは列を表しますので、行は同じで列は今のセルから左に3つであれば、その文字列は「RC[-3]」となります。
所要時間をF列に出力するなら、終了日時は-3列、開始日時は-4列ですから、以下の数式で計算可能です。
'=INDIRECT("RC[-3]",FALSE)-INDIRECT("RC[-4]",FALSE)'
文字列から墨付きカッコ内のテキストを抜き出す
続いて、イベントのカテゴリをA列のイベント名隅カッコの中から抜き出します。
例えば、タイトルが「【勉強】jQuery」であれば「勉強」と出力したいわけです。
この場合、スプレッドシートの5つの関数を駆使します。
FIND関数で特定の文字の位置を調べる
まず、最初の手順として「閉じる方の」墨付きカッコ、つまり「】」の位置を調べて、その手前までを切り取って抜き出すということをします。
特定の文字の位置を調べるにはFIND関数 を使います。
FIND (検索文字列, 検索対象のテキスト)
文字の位置なので、その文字が何文字目かを返します。
以下のようにすれば、閉じる方の墨付きカッコは4文字目ですから「4」という値が返ります。
今回、例えばA2セルに「【勉強】jQuery」が入力されているとすると、以下のようになります。
=FIND("】", A2)
LEFT関数で文字列を指定位置まで切り取る
FINDのおかげで、閉じる法の墨付きカッコの位置がわかりましたので、文字列をそこまでで切り取ってしまいます。
文字列を左から切り取るにはLEFT関数 を使います。
LEFT (文字列, 文字数)
今回は、隅カッコ「】」は除外したいので、FIND関数の戻り値のマイナス1までをLEFT関数で切り取ります。
=LEFT(A2, FIND("】", A2) - 1)
これで「【勉強」という文字列が返ります。
SUBSTITUTE関数で文字を置き換える
続いて「始まる方の」墨付きカッコが残っているので、これを削除します。
特定の文字を削除するにはSUBSTITUTE関数 を使います。
SUBSTITUTE (検索対象のテキスト, 検索文字列, 置換文字列)
今回の場合は検索文字列は「【」、置換文字列は空文字にすればOKですから、以下のようにします。
=SUBSTITUTE(LEFT(A2, FIND("】", A2) - 1), "【", "")
これで「勉強」が返りますね。
IFERROR関数でエラー時に空欄にする
しかし、A2セルに隅カッコがない場合は、数式の計算結果が「#VALUE!」となってしまいます。
これは、FIND関数で目的文字「】」が見つからないからです。
そこで、エラー値のときは空欄になるようにIFERROR関数 も使っておきます。
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で時刻計算と文字列抽出の数式を入力する方法 をお伝えしました。
二次元配列に数式を入れるだけならなんてことないですが、数式自体がなかなか複雑でしたね…!
でも一度作ってしまえばあとは楽ですから。
さて、次回は任意の月について書き出せるようにスクリプトを改善していきます。
どうぞお楽しみに!
連載目次:チャットワークのメッセージ送信で出勤・退勤の打刻をする
本シリーズはチャットワークの特定のグループチャットで出勤や退勤の打刻が可能になる勤怠システムをGoogle Apps Scriptとスプレッドシートを用いて作っていきます。これからはチャットというインターフェースがトレンドになってきますので、良い練習になると思いますよ!
Google Apps Scriptでチャットワークでのチャット打刻システムを作る
Google Apps ScriptでのDateオブジェクトの各生成方法、日付と時刻を分ける
Google Apps Scriptでチャットワークからの打刻情報をシートの最終行に追加する方法
Google Apps Scriptでスプレッドシート内を検索して行番号を返す関数(高速版)
Google Apps Scriptでチャットワークからの出勤・退勤の打刻データを様々な条件分岐を駆使して処理する