こんにちは。ITライターのもり(@moripro3)です!GoogleAppsScriptの記事をお届けしています!
連載シリーズ「GASとスプレッドシートで作る勤怠管理ツール」では、勤怠管理ツールを題材としたGASの活用事例を紹介しています。
前回の記事がこちら。月末のタイムシート締めの処理として「シート保護」の方法を紹介しました。
シリーズ第3回目のこの記事から、「【自動化その2】翌月シートの一括作成」の処理を数回に分けて紹介していきます。
スプレッドシートの処理をGASで自動化して、わずらわしい手作業から解放されましょう!
勤怠管理ツール・翌月シートの一括作成
このシリーズで紹介する「勤怠管理ツール」は2種類のスプレッドシートで構成されています。
部下の勤怠をチェックする「管理者用」と、毎日の勤怠を入力する「社員用」です。
- タイムシート集計(管理者用)
- 勤怠表(社員用)
①と②のスプレッドシートは関数でリンクしています。
※連載シリーズの最後で実物のファイルを公開しますので、関数の仕組みはそちらをご覧ください
勤怠表は1か月・1シートの構成なので、月が変わるたびに、各自が翌月分のシートを新しく作成する必要があります。
各社員がそれぞれ手作業でコピー複製することもできますが、翌月シートの作成に1分かかるとして、60人が同じ作業をしていたら、会社全体で「1時間」もムダになっちゃいますね。こういったひとりひとりの手間を省くのがGASの力です!
2019年9月→2019年10月に月が変わる場合、「201909」シートをコピーして「201910」シートを作成します。
「翌月分のシート作成」という作業を「処理」に分解してみます。
- 「当月のシート名(201909)」から「翌月のシート名(201910)」の文字列を作成する
- 「201909」シートをコピーして新しいシートを作成し、スプレッドシートの一番左に移動する
- 新しいシートのシート名を、①で作成した文字列「201910」に設定する
- 「201910」シートの、前月分の入力値をクリアする
この記事では、①の「当月のシート名(201909)」から「翌月のシート名(201910)」を作成する関数を作ります。
それではGASを書いていきましょう!
当月の年月(YYYYMM)から翌月の年月(YYYYMM)を作成する関数
この項では「受け取った年月(YYYYMM)」の「翌月の年月(YYYYMM)」を作成する関数を作ります。
「9月」から「10月」になる時は、9月のシート名「201909」から、翌月の「201910」という文字列を作りたいわけです。
関数名・仮引数・戻り値はそれぞれこのようにします。
- 関数名:createNextYYYYMM
- 仮引数:当月の年月(YYYYMM)例:201909
- 戻り値:翌月の年月(YYYYMM)例:201910
「仮引数」とは、呼び出し元の関数から受け取る引数のことです。
2019年12月の場合は「201912」 → 「202001」となるよう、年またぎの考慮も必要です。「日付の処理」がポイントになりますね。
処理を3ステップに分けて書いていきます。
- 【処理1】受け取った文字列を「年」「月」に分ける
- 【処理2】当月の「年」「月」の値から、翌月日付(1日)を作成する
- 【処理3】翌月日付(1日)をYYYYMM形式に整形する
【処理1】受け取った文字列を「年」「月」に分ける
まずは、受け取った文字列である6桁の数値(YYYYMM)を「年」「月」に分ける処理です。
当月のシート名(6桁の数値:YYYYMM)が仮引数です。この仮引数のデータ型は「文字列」です。
この「6桁の文字列」から、2種類の値を取得します。
- 1桁目~4桁目 → 年
- 5桁目~6桁目 → 月
文字列から「指定の桁数の文字」を取得するStringオブジェクトのsliceメソッドを使用します。
文字列.slice(開始位置,終了位置)
文字列の指定桁数の文字を取得します。取得したい文字の「開始位置」と「終了位置」を指定します。
コードがこちらです。受け取った文字列が ‘201909’ の場合です。
//仮引数 this_YYYYMM = '201909' の場合、 var year = this_YYYYMM.slice(0,4); //YYYY var month = this_YYYYMM.slice(4,6); //MM Logger.log(year); //2019 Logger.log(month); //09
sliceメソッドの引数の「開始位置」と「終了位置」の指定がポイントですね。
1桁目~4桁目を取得する場合、引数をこのように指定します。
- 開始位置 = 0
- 終了位置 = 4
5桁目~6桁目を取得する場合は、このように指定します。
- 開始位置 = 4
- 終了位置 = 6
これで、当月の「年」「月」が取得できました。
- 変数year = 2019
- 変数month = 09
【処理2】当月の「年」「月」の値から、翌月日付(1日)を作成する
当月の「年(YYYY)」「月(MM)」の値を使用して、「翌月」のデータを作成します。
12月→1月の年またぎも考慮するので、「日付処理」がポイントになります。
日付データを操作するDateオブジェクトを使用します。手順は、
- ①「年(YYYY)」「月(MM)」を使用してDateオブジェクトを作成する
- ②Dateオブジェクトの「翌月の数値」を求める
- ③Dateオブジェクトに「翌月の数値」をセットする
それでは①~③を順番にみていきましょう。
①「年(YYYY)」「月(MM)」を使用してDateオブジェクトを作成する
日付データを扱うDateオブジェクトを使用します。
var 変数 = new Date(年,月 [,日,時,分,秒,ミリ秒])
※「月」の指定は0-11(1-12月)です。
(例)「10月」のDateオブジェクトを作る場合「9」を指定します。
※仮引数(シート名:YYYYMM)のデータ型は「文字列」なので、そこから切り出したYYYYとMMのデータ型も「文字列」です。Dateオブジェクトの引数のデータ型は、「数値」でなく「文字列」でも可能です。
引数指定は「年」と「月」の2つのみで作成可能です。「年」「月」のみを指定すると、1日0時のDateオブジェクトが作成されます。
サンプルコードです。「2019年10月1日」のDateオブジェクトが作成されます。
var date = new Date(2019, 9); //monthの値は0~11(1月~12月) Logger.log(date); //Tue Oct 01 00:00:00 GMT+09:00 2019
仮引数から取得した「年(YYYY)」「月(MM)」は、変数yearとmonthに格納されています。この2変数を使用して、当月のDateオブジェクトを作成します。
※「月」の指定は0-11(1-12月)なので、月指定を -1 するのがポイントです。
var date = new Date(year, month-1); Logger.log(date); //Sun Sep 01 00:00:00 GMT+09:00 2019
これで「2019年9月」の1日日付のDateオブジェクトが作成できました。
②Dateオブジェクトの「翌月の数値」を求める
変数dateにDateオブジェクトが作成されました。このDateオブジェクトを操作して、目的の年月を作ります。
「翌月の数値」を求めるために、まずはDateオブジェクトのgetMonthメソッドで「月」を取得します。
Dateオブジェクト.getMonth()
Dateオブジェクトの「月」を取得します。※0-11(1月-12月)の数値が返ります。
取得した「月」に1を加算して「翌月の数値」を求めます。
var nextmonth = date.getMonth()+1; Logger.log(nextmonth); //9
※getMonthメソッドの戻り値は0-11(1-12月)なので、変数nextmonthの値「9」は「10月」です。
さて、ここまでの処理で、(ややこしいな…)と感じそうですね。翌月データを作るなら、変数monthを +1 すればいいのでは?と思いそうですが、年またぎを考慮するために、このDateオブジェクトを使っているのです。
③Dateオブジェクトの「月」に「翌月の数値」をセットする
DateオブジェクトのsetMonthメソッドで、「月」の値を「翌月の数値」に設定(変更)します。
Dateオブジェクト.setMonth(n)
Dateオブジェクトの「月」を設定します。
※引数には、Dateオブジェクトの「今年の1月」を0とした場合の「nヶ月後」を指定します。
setMonthメソッドの引数の指定を詳しく説明します。
「今年の1月」を「0」とした場合の「nヶ月後」とは?
- 引数に「0 – 11」を指定した場合、その年の「1月 – 12月」が設定されます
(例)引数に「9」を指定 → 「今年の1月」を「0」とした場合の「9ヶ月後」は「10月」です。
- 引数に12以上の数値を指定した場合、翌年以降の月になります
(例)引数に「12」を指定 → 「今年の1月」を「0」とした場合の「12ヶ月後」は「翌年の1月」です。
このルールを表にしてみます。
setMonthメソッドの引数 |
設定される月 |
---|---|
0 | 今年の1月 |
1 | 今年の2月 |
… | … |
11 | 今年の12月 |
12 | 翌年の1月 |
13 | 翌年の2月 |
… | … |
setMonthメソッドのこの仕組みを利用することで、「年またぎ」のデータが作成できるのです。
コードがこちら。コメントアウトは、9月→10月の場合の値です。
var nextmonth = date.getMonth()+1; //9 date.setMonth(nextmonth); //今年の10月になる Logger.log(date); //Tue Oct 01 00:00:00 GMT+09:00 2019
【まとめ】当月の「年」「月」から翌月日付(1日)を作成する処理
ここまでの①~③の処理をまとると、
- ①「年(YYYY)」「月(MM)」を使用してDateオブジェクトを作成する
- ②Dateオブジェクトの「翌月の数値」を求める
- ③Dateオブジェクトの「月」に「翌月の数値」をセットする
①~③をまとめたコードがこちらです。
//①当月シート名のDateオブジェクトを作成 ※月は0~11(1月~12月)を指定 var date = new Date(year, month-1); //②Dateオブジェクトの「翌月の数値」を求める var nextmonth = date.getMonth()+1; //③Dateオブジェクトの「月」に「翌月の数値」をセットする date.setMonth(nextmonth); Logger.log(date); //Tue Oct 01 00:00:00 GMT+09:00 2019
②と③の処理は1行にまとめてもOKです。
date.setMonth(date.getMonth()+1);
これで、当月のシート名「201909」から、翌月1日「2019年10月1日」のDateオブジェクトが作成できました。
【処理3】翌月日付(1日)をYYYYMM形式に整形する
翌月1日付のDateオブジェクトから「3つの文字列」を作成します。
翌月のシート名の他に、「年」「月」の文字列も作ります。
- YYYYMM(シート名)
- YYYY(年)
- MM(月)
たとえば、①を作るには、Dateオブジェクトの表示形式をこのように整えたいわけです。
「Tue Oct 01 00:00:00 GMT+09:00 2019」→「201910」
①~③の文字列の、勤怠表での使いどころは下記のとおりです。
GASで日付データを整形するときに使うのがUtilitiesクラスです。文字列・日付の書式設定などができるメソッドがたくさん用意されています。(Google公式リファレンスはこちら)
UtilitiesクラスのformatDateメソッドを使用して、書式設定します。
Utilitiesクラス.formatDate(日付,タイムゾーン,フォーマット)
日付の書式設定をします。
このformatDateメソッドを使用して、①~③の文字列を作ります。引数の指定は下記の通りです。
- 第1引数(日付) = 変数date(翌月日付が格納されているDateオブジェクト)
- 第2引数(タイムゾーン) = ‘JST’ (日本時間)
- 第3引数(フォーマット) = ※設定したい書式によって異なる
①「年月」の文字列YYYYMMを作成する
第3引数のフォーマットは ’yyyyMM’ を指定します。※MMは大文字です
var next_YYYYMM = Utilities.formatDate(date, 'JST', 'yyyyMM'); Logger.log(next_YYYYMM); //201910
②「年」の文字列YYYYを作成する
第3引数のフォーマットは ’yyyy’ を指定します。
var next_YYYY = Utilities.formatDate(date, 'JST', 'yyyy'); Logger.log(next_YYYY); //2019
③「月」の文字列MMを作成する
第3引数のフォーマットは ’M’ を指定します。
var next_MM = Utilities.formatDate(date, 'JST', 'M'); //1~12の数字を作る Logger.log(next_MM); //10
※1桁の月(1~9月)に先頭ゼロを付与する場合は ’MM’ を指定します。
複数の変数を配列でまとめて返す
ここまでの処理で、必要な3つの値が揃いました。
- 翌月の「年月」(YYYYMM)
- 翌月の「年」(YYYY)
- 翌月の「月」(MM)※1桁の場合は先頭ゼロを付与しない
これら3つの変数を、呼び出し元の関数に戻します。
return文では、配列の指定が可能です。3つの変数を返す場合、このように書きます。
return [next_YYYYMM, next_YYYY, next_MM];
(参考)呼び出し元の関数も、変数を配列形式で指定します(今後の記事で詳しく紹介します)
var [a, b, c] = createNextYYYYMM(当月のシート名);
スクリプトまとめ
この記事で作成したコードのまとめです。ぜひご活用ください!
/* * 「当月の年月」から「翌月の年月」を作成する(シート名) * * @param {String} 当月の年月(YYYYMM) * @return {String} 翌月の「年月」(YYYYMM) * @return {String} 翌月の「年」(YYYYMM) * @return {String} 翌月「月」(MM) */ function createNextYYYYMM(this_YYYYMM) { /***** 【処理1】受け取った文字列を「年」「月」に分ける *****/ var year = this_YYYYMM.slice(0,4); //YYYY var month = this_YYYYMM.slice(4,6); //MM /***** 【処理2】「年」「月」の値から、翌月日付(1日)を作成する *****/ var date = new Date(year, month-1); //当月 ※月は0~11(1月~12月)を指定 var nextmonth = date.getMonth()+1; //翌月の数値 date.setMonth(nextmonth); /***** 【処理3】翌月日付(1日)をYYYYMM形式に整形する *****/ var next_YYYYMM = Utilities.formatDate(date, 'JST', 'yyyyMM'); //年月 var next_YYYY = Utilities.formatDate(date, 'JST', 'yyyy'); //年 var next_MM = Utilities.formatDate(date, 'JST', 'M'); //月 //配列でまとめて返す return [next_YYYYMM, next_YYYY, next_MM]; }
まとめ:GASとスプレッドシートで作る勤怠管理ツール
GASで「当月の年月」(YYYYMM)から「翌月の年月」を作る方法を紹介しました。
ポイントは、日付データを扱う「Dateオブジェクト」です!プログラムで日付処理をする時は、月またぎ・年またぎ・うるう年などの考慮が必須になりますよね。この「Dateオブジェクト」を使うことで、そのような処理を考慮してくれるのでミスなく処理ができるのです。
さて次回は、「シートをコピーして新しいシートを作成し、スプレッドシートの一番左に移動する」処理を紹介します。
【連載目次:GASとスプレッドシートで作る勤怠管理ツール】
- GASでスプレッドシートのシフト表を自動化するには?
- スプレッドシートのユーザー編集権限を変更する方法
- GASでスプレッドシート活用術。今月日付から翌月日付を作る
- GASでスプレッドシートをコピー、シート内の一番左に表示する方法
- GASで複数のスプレッドシートに対して同じ処理を繰り返す(※サンプルファイル公開あり)