LoginSignup
2
4

More than 3 years have passed since last update.

【GAS】年間行事予定表を1年間分まとめてカレンダーに書き込む

Last updated at Posted at 2021-03-28

学校の年間行事予定表を1年間分まとめてカレンダーへ書き込むGASです。

Googleが指定するcsv形式で予め作成した予定一覧をカレンダーのインポート機能を使って読み込めば、カレンダーに予定をまとめて書き込むことはできるのですが、それも億劫になってきたので今回GASで一気に書き込めるようにしました。

ごく初歩的な機能だけで十分なため、GASプログラミング未経験者にも理解しやすいコードだと思います。

特徴

  • 1年間分まとめてカレンダーへ書き込める。
  • 特定の日に複数の行事がある場合には行事1と行事2に分けて入力することにより、同日最大2つまで行事を書き込むことができる。
  • 行事は全て全日扱いで書き込む。
  • 各学校毎に行事予定表のレイアウトが違っても、ダウンロードしたシートに適切にマッピングさせれば幅広く対応可能。

簡単な使い方

  1. 年間行事予定表toカレンダー(公開用)をクリックし、コピーをドライブ上へ作成
  2. シートの中で変更して良いのは背景が灰色の部分(年度、行事)のみ。行事の入力が済んだら、メニューバーの「ツール」->「スクリプトエディタ」を開く。※ ここで別シートに各学校毎のカレンダーを貼り付けておき、対応するデータをマッピングさせておけば毎年の更新作業が楽です。
  3. 13行目のカレンダーIDを年間行事予定表を書き込みたいカレンダーのカレンダーIDへ変更して保存。カレンダーIDの場所は例えば、カレンダーの種類やアドレスを確認する方法
    を参照のこと。

  4. 実行ボタンを押すと、GASが各種アプリケーションに対する追加の権限を求めてくるので承認する。左下の「詳細を表示」を押すと、以下の画面になるので「YearScheduleForStudents(public)(安全ではないページ)に移動」をクリックして先に進めば良い。

承認画面.png
5. スプレッドシートに戻り、新たに出来たメニューバーの「toCalendar」->「カレンダーへ出力」を実行。
6. 確認ウィンドウが表示されるので問題なければ「OK」で指定したカレンダーへ行事予定表が書き込まれる。
7. 実行中にエラーが発生した場合、ウィンドウにエラーの詳細が表示され実行が止まる。

コード.gs
function onOpen() {
 const ui = SpreadsheetApp.getUi();
 const menu = ui.createMenu("toCalendar");
 menu.addItem("カレンダーへ出力", "myFunction");
 menu.addToUi();
}

function myFunction() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName('年間行事予定表');
  const range = sheet.getDataRange().getValues();

  const id = 'カレンダーID'
  const calendar = CalendarApp.getCalendarById(id);
  const days = [];

  // イベント作成時にアイドル時間を作らないとGASが止まる。アイドル時間の200に根拠はない
  const THROTTLE_SLEEP_TIME = 200;

  // 日付を作成
  for(let i = 1; i < 276; i++){
    days.push(`${range[0][0]}/${range[i][0]}/${range[i][1]}`);
  }
  for(let i = 276; i < 367; i++){
    days.push(`${parseInt(range[0][0])+1}/${range[i][0]}/${range[i][1]}`);
  }

  range.shift();
  let result = Browser.msgBox("行事予定表をカレンダーに書き込みます。\\n 【注意】 この操作は取り消せません!",Browser.Buttons.OK_CANCEL);
  if(result == "ok"){
    try{
      for(let i = 0; i < days.length; i++){
        if(range[i][2] !== ''){
          const date = new Date(days[i]);
          calendar.createAllDayEvent(range[i][2], date);
          Utilities.sleep(THROTTLE_SLEEP_TIME);
        }
        if(range[i][3] !== ''){
          const date = new Date(days[i]);
          calendar.createAllDayEvent(range[i][3], date);
          Utilities.sleep(THROTTLE_SLEEP_TIME);
        }
      }
    }catch(e){
      Browser.msgBox(e);
    }
  }
}

補足(THROTTLE_SLEEP_TIMEについて)

どうもGAS実行時に意図的にアイドル時間(THROTTLE_SLEEP_TIME)を作らないと1日あたりの割り当て(カレンダーイベント作成数:無料アカウント5000個、G Suite Basic以上10000個)以内であるにも関わらずエラーで止まってしまいます。勤務校の行事予定表はTHROTTLE_SLEEP_TIME=200(ミリ秒)で問題なく動きましたが、この数値はイベント数次第です。新たに作成するイベントが少なければ0ミリ秒でもエラーが起こらないこともあります。実行時に

You have been creating or deleting too many calendars or calendar events in a short time. Please try again later.

あるいはこの日本語訳が表示されたら、スクリプトエディタで18行目のTHROTTLE_SLEEP_TIMEの値を調整してみて下さい。

これに関しては現状、スクリプト実行時間の6分制限を意識しながら調整するしかなさそうです。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4