@hos13

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

複数のGoogleカレンダーを連携させるGASで「特定のタイトル」はコピーしない指示を書きたい。

解決したいこと

複数のGoogleカレンダーを連携させるGASで「特定のタイトル」はコピーしない指示を書きたい。

概要

複数の仕事をしており、"A"のGoogleカレンダーと"B"のGoogleカレンダーをお互い"毎日コピペ"するGASを組みたいと考えました。
実際に片方のコピペはできるところまで行ったのですが、両方にカレンダーを入れておかないとMTGなどが勝手に入ってしまうため、双方にコピペされる状態にしたいと考えています。

こちらの記事を参考にしながら、作成しています。
https://dev.classmethod.jp/articles/check-holiday-or-paid-leave-by-gas-with-gcal/

発生している問題

①A→Bにコピペ
②B→Aにコピペ
をすると②の際に①で反映した予定が二重でコピペされてしまう状態になっています。

解決のため、自分で試したこと

A→Bで飛ばす時:タイトルに「A」の予定と分かる表記
B→Aで飛ばす時:タイトルに「B」の予定と分かる表記
をつけるようにして、

if (event.getTitle().match(/A/)) {return

で、Aの予定は取得しないという設定にしました。
結果、最初のAの予定でプログラムが止まってしまいます。

該当するソースコード

/**
 * 複数のカレンダーの予定を別のカレンダーにコピーしていく関数
 * トリガーで1日1回実行することを想定
 */

function close_mergeCalendarEvents() {

//  入力欄 //
  /* 予定を結合させたいコピー先カレンダーのID */
  const idMergedCal = 'カレンダーA ID';

  /* 予定のコピー元のカレンダーの配列 */
  const idsCopyFrom = ['カレンダーB ID'];

////////////////////////////////////////

  /* 後で削除する時のためのタグのキーと値 */
  // https://developers.google.com/apps-script/reference/calendar/calendar-event#setTag(String,String)
  const key = 'gas'; 
  const tag = 'copied';


  /* 操作する期間を指定 */
  const term = 30; // 予定をコピーする期間(日数)を指定
  const now = new Date(); // 現在日時を取得
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0); // 今日の日付 00:00:00を取得
  const yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1, 0); // 昨日の日付 00:00:00を取得
  const endBefore = new Date(today.getFullYear(), today.getMonth(), today.getDate() + term, 0); // この日付の前日までの予定を操作

  // コピー先のカレンダーの取得
  const calMerged = CalendarApp.getCalendarById(idMergedCal);

  /* 過去に登録した予定でタグが付与されているものを重複防止の為に削除 */
  const overlapEvents = calMerged.getEvents(yesterday, endBefore); // yesterdayをtodayにすれば過去の予定は残る
  overlapEvents.forEach(event => {
    if (event.getTag(key) === tag) {
      event.deleteEvent();
      Utilities.sleep(1000); // カレンダーの連続操作はエラーになりやすい
    };
  });

  /* コピー元のカレンダーから予定をタグを付与してコピー */
  idsCopyFrom.forEach(id => {
    const calCopyFrom = CalendarApp.getCalendarById(id); // カレンダーオブジェクトをIDから取得
    copyEventsBlock_(calCopyFrom, today, endBefore, calMerged, key, tag);
  });

}

/**
 * タグを付与しながら指定期間のイベントを別のカレンダーにコピーしていく関数
 * 
 * @param   {Object}  calCopyFrom - 予定のコピー元カレンダーオブジェクト
 * @param   {Object}  startFrom - 予定コピーの開始日(Dateオブジェクト)
 * @param   {Object}  endBefore - 予定コピーの終了日(Dateオブジェクト)※操作対象日に含まれない
 * @param   {Object}  calCopyTo - 予定のコピー先カレンダーオブジェクト
 * @param   {string}  key - イベントオブジェクトに付与するキー(カレンダーUIでは不可視)
 * @param   {string}  tag - イベントオブジェクトに付与するキーとペアになる値(カレンダーUIでは不可視)
 * @return
 */

function copyEventsBlock_(calCopyFrom, startFrom, endBefore, calCopyTo, key, tag) {

  // コピーする予定を非公開に
  const visibility = CalendarApp.Visibility.PRIVATE;

  // カレンダー内の予定を取得
  const events = calCopyFrom.getEvents(startFrom, endBefore);

  // カレンダー内の予定を一つずつコピーしていく
  for (const event of events) {

    //タイトルに「A」の表記があればスキップ
    if (event.getTitle().match(/A/)) {return

    //終日イベントか時間単位イベントか判別
    }else if (event.isAllDayEvent()) {
      const title = event.getTitle(); //コピー元予定のタイトルを取得
      const startDate = event.getAllDayStartDate(); //コピー元予定の開始日を取得
      const endDate = event.getAllDayEndDate(); //コピー元予定の終了日を取得

      // 新しい非公開イベントを作成し各値とタグを付与
      // タイトルにはコピーされた予定とわかるようにCopied:の接頭詞
      const copiedAllDayEvent = calCopyTo.createAllDayEvent(`B予定あり`, startDate, endDate).setTag(key, tag).setVisibility(visibility);
      copiedAllDayEvent.setColor(CalendarApp.EventColor.PALE_GREEN); // イベントのカラーを指定 https://developers.google.com/apps-script/reference/calendar/event-color
      Utilities.sleep(1000);

    } else {
      const title = event.getTitle(); //コピー元予定のタイトルを取得
      const startTime = event.getStartTime(); //コピー元予定の開始時間を取得
      const endTime = event.getEndTime(); //コピー元予定の終了時間を取得

      // 新しい非公開イベントを作成し各値とタグを付与
      // タイトルにはコピーされた予定とわかるようにCopied:の接頭詞
      const copiedEvent = calCopyTo.createEvent(`B予定あり`, startTime, endTime).setTag(key, tag).setVisibility(visibility);
      copiedEvent.setColor(CalendarApp.EventColor.PALE_GREEN); // イベントのカラーを指定 https://developers.google.com/apps-script/reference/calendar/event-color
      Utilities.sleep(1000);
    }
  }
}

コーディングの経験も浅く、ぜひ解決策など思いつく方、教えていただきたいです。

0 likes

1Answer

returnしちゃうとeventsの残りを処理しないで終わっちゃうので、そこはreturnではなくcontinue、という話ではないですか?

0Like

Comments

  1. @hos13

    Questioner

    ありがとうございます!解決いたしました。

Your answer might help someone💌