![見出し画像](https://assets.st-note.com/production/uploads/images/143743328/rectangle_large_type_2_fc798e88c2971b060364ca5d653f8319.png?width=1200)
【GAS活用術⑩】過ぎた日付の予定行を「毎日」自動的に削除・移動する
Google Apps Script (GAS)を、もっと身近に、日々の暮らしに。
今回は、以下のような予定表で、予定の日付が過ぎたら、その予定行を削除・移動する方法についてです。
![](https://assets.st-note.com/img/1717592072586-uCC41qk8ql.png)
上記の「日付」、「区分」、「予定」と3列だけのシンプルな予定表ですが、これを私は以下のようにフル活用しています。
![](https://assets.st-note.com/img/1718193967651-aEicw4WmmO.png?width=1200)
翌日の予定が見つかったら指定のLINEグループに通知する時の元データ(【GAS活用術①】)
フォームのプルダウンの選択肢を自動生成する時の元データ(【GAS活用術⑦-2】)
Googleカレンダーに終日イベントを一括登録する時の元データ(【GAS活用システム⑦】)
予定表をウェブに公開して、カレンダーと一緒にサイトに埋め込む(【GAS活用システム⑦】)
このフルフルに活用している予定表ですが、以前は、過去日付の予定行を手動で削除していました。月に数回程度だし、まぁ、いいかと。。
が、最近になって、それまで裏方だったこの予定表を、表舞台となるサイトで表示するようになり、ようやく自動的に過去日付の予定行を削除したり、移動したりするGASについて考えることにしました。
これが、単純なようで、意外に深かったので、備忘録をかねて記事として残しておくことにします。
今回は「毎日」チェックバージョン
今回は、削除・移動すべき予定があるか毎日、チェックすることを考えてみます。
もちろん、毎日チェックするのは私ではなく、GASです。正確には、日付ベースのトリガーを設定して、毎日、同じ時間帯に、GASの関数(対象の予定があるかをチェックして、条件にあえば予定行を削除・移動する)が実行されるようにします。
過去日付の予定行を「削除」するなら
削除と移動の2パターン紹介しますが、先に削除する方を説明していきます。
具体的に、「毎日、夜中の1~2時に起動するトリガーを設定して、朝起きたら、昨日の予定データが消えている」、これを実現するにはどうしたらいいか考えてみましょう。
予定表は日付順に並んでいて、かつ、毎日、古くなった予定データは削除されることを前提とすると、一番上の日付データだけ、削除すべきかどうかチェックすればよいことになります。
この予定表でいえば、日付データはA列にあり、1行目のヘッダー行は除くので、A2のセルの日付データを見て、過去日付かどうか判断し、過去日付であれば2行目だけを削除すればいいわけです。
![](https://assets.st-note.com/img/1717593942545-2exSuLeYUa.png)
この時、まず気を付けたいのが、予定表の2024/06/05(水)の日付は2024/06/05 00:00:00と、実際は時間を含む日時データとして認識されることです。
そのため、例えば、トリガーが実行されるのが2024/06/05の午前1時~2時だとしたら、予定表の2024/06/05(水)は2024/06/05 00:00:00と認識されるので、単純にトリガーの実行日時と予定の日付と比較すると、予定表の2024/06/05(水)の方が古いと判断され、削除対象となってしまいます。
![](https://assets.st-note.com/img/1717982683633-6Mu45IpbTX.png?width=1200)
つまり、夜中の1時〜2時に、肝心の当日の予定を削除することになり、朝起きたら当日の予定が消されている!?という事態に陥ります。
それではまずいので、トリガーが実行された日時を一日前にずらして、それより過去のデータであれば削除する、ということにします。
![](https://assets.st-note.com/img/1717899959316-bZAtDPzXL8.png?width=1200)
もし、少し余裕を持たせて、予定日を3日過ぎてから消したいのであれば、4日前の日付にしてから削除する、という風に考えればいいわけですね。
ということで、この場合のGASは以下のような感じになります。
function deleteOldPlan(){ //古くなった予定行を削除
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getSheetByName("予定表"); //「予定表」シートを取得
const date = new Date(); //トリガー実行時の現在日時を取得
date.setDate(date.getDate() -1); //1日前の日付に変更
const planDate = sh.getRange(2,1).getValue(); //A2セルの値を取得
if ( planDate !== '' && planDate < date ) {
sh.deleteRow(2); //2行目を削除
//ここにこのタイミングで実行したい関数があれば記述する
//updateDateList(); //フォームのプルダウンの日付の選択肢を更新
}
}
予定表にまったく予定がない場合のことも考えて、if文の条件として”A2セルが空白でない”「planDate !== ''」も追加しています(私の所属する読み聞かせボランティアの活動は、小学校が夏休みなど長期休暇の時は、一か月ほどお休みになることもあります)。
1行のみ削除する場合は、deleteRowメソッドで。削除する行番号の2を指定します。
また、コメントアウトしていますが、もし予定データを削除した後、何らかの関数を実行をしたい場合は、if文の中に入れておきます。
私の場合、予定表の日付データから、フォームのプルダウンの選択肢を生成しているので、updateDateList() という関数をコールしています(詳細は【GAS活用術⑦-2】を参照)。
後は、このdeleteOldPlan関数を、毎日、深夜1~2時に自動実行されるトリガーを仕込んでおけば、朝起きたら、古い予定が消えてるわけですね。
![](https://assets.st-note.com/img/1717983307057-s89UB4qSDq.png)
過去日付の予定行を別シートに「移動」するなら
上ではざくっと予定を削除しましたが、場合によってはその予定を別シートに残しておきたいときもあると思います。
次は、「毎日、夜中の1~2時に起動するトリガーを設定して、朝起きたら、昨日の予定データが別のシートへ移動している」を考えてみます。
まず、移動先のシートを用意しましょう。基本的には「予定表」シートをコピーして、ヘッダー行だけ残して、データ行のデータを消去して、シート名を「アーカイブ」などわかりやすい名前に変えておけばOKです。
![](https://assets.st-note.com/img/1718109944012-a57aQZOYuK.png?width=1200)
続けて、GASのコードですが、実はこれ、削除バージョンを少し変更するだけでいけます。
というのは、移動といいましたが、実際は、対象データを、移動先のシートへコピーし、その後、元のデータを削除することになります。コピー+削除=移動、ってことですね。
はじめ、moveRowsメソッドが使えるかと思いましたが、パラメータの指定方法が複雑な上に、移動先が同じシートでないと駄目なようです。
調べた結果、セル範囲のデータを別のセル範囲にコピーする、copyToメソッドの使い勝手がよさそうです。使用方法は、図にすると、↓こんな感じです。
![](https://assets.st-note.com/img/1718111196931-DvzuUDmStS.png?width=1200)
getValuesしてsetValuesする必要はなく、「コピー元の範囲.copyTo(コピー先の範囲)」でOKとのこと。これだけで、値と書式設定の両方をコピーしてくれます。
なお、リファレンスには、コピー先の範囲指定では、「左上のセル位置のみ有効です」とあり、初めは?と思いましたが、左上のセルの位置だけ指定すれば、コピー元の範囲にあわせてペーストしてくれるようです。うーん、便利。
ということで、以下が移動(コピー+削除)バージョンのGASのコードです。
function moveOldPlan(){ //古くなった予定行を別シートへ移動
const ss = SpreadsheetApp.getActiveSpreadsheet();
const org_sh = ss.getSheetByName("予定表"); //「予定表」シートを取得
const arc_sh = ss.getSheetByName("アーカイブ"); //「アーカイブ」シートを取得
const date = new Date(); //トリガー実行時の現在日時を取得
date.setDate(date.getDate() -1); //1日前の日付に変更
const planDate = org_sh.getRange(2,1).getValue(); //元シートのA2セルの値を取得
if ( planDate !== '' && planDate < date ) {
const lastCol = org_sh.getLastColumn(); //元シートの最終列を取得
const arc_lastRow = arc_sh.getLastRow(); //アーカイブ先シートの最終行を取得
//元シートの2行目の範囲を取得後、copyToでアーカイブ先シートの最終行+1のA列のセルにコピー
org_sh.getRange(2,1,1,lastCol).copyTo(arc_sh.getRange(arc_lastRow+1,1));
//アーカイブ先シートの交互の背景色を拡張させるために一行挿入
arc_sh.insertRowAfter(arc_lastRow+1);
org_sh.deleteRow(2); //2行目を削除
//ここにこのタイミングで実行したい関数があれば記述する
//updateDateList(); //フォームのプルダウンの日付の選択肢を更新
}
}
コピー部分が追加されているので、削除バージョンよりは長くなりましたが、結構、共通している所は多いと思います。
このmoveOldPlan関数を、日付ベースのトリガーを設定して、毎日、同じ時間帯に実行するようにすれば、朝起きたら昨日の予定がアーカイブシートに移動していて、予定表シートには常に次の予定が一番上に来ているわけです。
夜中に小人(こびと)さんが、せっせと過日付の予定を別シートに移動してくれてるようなイメージをもつのは、私だけでしょうか。。
こんな仕組みを無料で提供してくれるGoogleさん、本当に素晴らしいです。
おわりに
今回の内容に興味があるのは、まったくのGAS初心者ではないと思ったので、おもいきってGASの登録方法や実行方法、プロジェクトの承認方法、トリガーの設定方法などは省いちゃいました。
必要でしたら、下記の記事など参考にしてください。
GASの登録方法や実行方法、プロジェクトの承認方法は、↓こちら。
トリガーの設定については、↓こちら。
次回は、「毎日」ではなくて、「週に一度、過ぎた日付の予定行をまとめて削除・移動する」GASについてみていきたいと思います。
この記事が気に入ったらサポートをしてみませんか?