@morishin_1002

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【初心者:GAS】GoogleスプレッドシートからGoogleカレンダーに自動入力をしたいのですが、うまくいきません。

【初心者:GAS】GoogleスプレッドシートのデータからGoogleカレンダーに自動入力をしたいのですが、GASをデバックするとエラーが出ます。

GAS初心者です。GoogleスプレッドシートのデータからGoogleカレンダーに自動で入力をしたいと思い、Chat-GPTを活用しながらGASを書いてみました(スプシに紐づけたGAS)。アップデートを繰り返し、少しずつ使えるようになったのですが、どうしても分からないエラーが排出されてしまい、実用に至っていません。

ソースコードのどの部分を修正したら直りそうか、ぜひお助けいただきたいです。

発生している問題

スプレッドシートの表示は3列。それぞれ、
「日時(2024/12/01など)、勤務時間(8:00-17:00など)、記載内容(早番など)」という3つのシンプルなデータで構成しています。

対応するデータには7パターンあります。
早番
遅番
通常勤務(9-18時)
出張(勤務)
通し勤務
有給きゅうか
休み

この内、早番(8:00-17:00)と通し勤務(8:00-20:00)でのみ、デバックすると以下のようなエラーが排出されます。

・行 16: イベントを作成しました - 早番 (Invalid Date から Sat Dec 14 2024 17:00:00 GMT+0900 (Japan Standard Time) まで)
・行 30: イベントを作成しました - 通し勤務 (Invalid Date から Sat Dec 28 2024 20:00:00 GMT+0900 (Japan Standard Time) まで)

それぞれに対応する開始時間が「Invalid Date」になってしまいます。
このまま実行をしてみますと、googleカレンダー上にて「1970年 1月 1日 午前9:00~2024年 12月 28日 午後8:00」などといったカレンダーが自動入力されてしまいます。
(そのほかの休みや遅番などは、うまく自動入力されます)

エラーの例.png

ソースコード

function createCalendarEventsForSpecificColumns() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheetName = "カレンダー転記用"; // 処理対象のシート名を指定
  const sheet = spreadsheet.getSheetByName(sheetName);

  if (!sheet) {
    throw new Error(`指定されたシート "${sheetName}" が見つかりません。`);
  }

  const calendar = CalendarApp.getCalendarById("カレンダー入力したいメールアドレス"); // 自分のカレンダーIDを入力
  const rows = sheet.getDataRange().getValues();

  // 処理したい列番号を指定(例えば、1列目(A列)の日付、2列目(B列)の時間、3列目(C列)の内容)
  const targetColumns = [0, 1, 2]; // 0: 日付, 1: 時間, 2: 内容(0から始まるインデックス)

  for (let i = 1; i < rows.length; i++) { // 1行目はヘッダーとしてスキップ
    const row = rows[i];

    // 必須データが不足している場合はスキップ
    if (!row[targetColumns[0]] || !row[targetColumns[1]] || !row[targetColumns[2]]) {
      Logger.log(`行 ${i + 1}: 必須データが不足しているためスキップしました`);
      continue;
    }

    try {
      // 日付の形式が正しいか確認
      const dateOnly = new Date(row[targetColumns[0]]);
      if (isNaN(dateOnly.getTime())) {
        Logger.log(`行 ${i + 1}: 無効な日付形式のためスキップしました - ${row[targetColumns[0]]}`);
        continue; // 無効な日付の場合はスキップ
      }

      const timeRange = row[targetColumns[1]].replace(/\s+/g, '').split('-'); // 空白を除去して分割

      if (timeRange.length !== 2 || !timeRange[0] || !timeRange[1]) {
        throw new Error("時間フォーマットが正しくありません: " + row[targetColumns[1]]);
      }

      const startTime = new Date(`${dateOnly.toISOString().split('T')[0]}T${timeRange[0]}`);
      let endTime = new Date(`${dateOnly.toISOString().split('T')[0]}T${timeRange[1]}`);

      Logger.log(`開始時間: ${startTime}, 終了時間: ${endTime}`); // ログで確認

      const title = row[targetColumns[2]]; // 内容(3列目)

      // イベントを作成
      calendar.createEvent(title, startTime, endTime);
      Logger.log(`行 ${i + 1}: イベントを作成しました - ${title} (${startTime} から ${endTime} まで)`);

    } catch (error) {
      Logger.log(`行 ${i + 1}: エラー - ${error.message}`);
    }
  }
}

自分で試したこと

Chat-GPTを活用して、アップデートを繰り返してみました。
ですが、このエラーの解決方法がわかりません。
GASやコーディングの基礎が甘いというのは大前提にあるのですが、ぜひご助言いただきたいです。よろしくお願いいたします。

0 likes

3Answer

new Date() で日時文字列をパースするとき、時分秒の部分は 08:00 のように0で埋めて各2桁にしなければなりません。 8:00 だとエラーになります。

雑に対応するなら以下のコード(timeRange の各要素について、長さが5文字未満なら5文字になるまで左に "0" を付け足す)で動くようになります。これはシートに記入された時刻の分が必ず2桁で時が1桁か2桁であることを前提としています。分も1桁になりうるならもっとまともな処理が必要です。

const timeRange = row[targetColumns[1]].replace(/\s+/g, '').split('-')
  .map((time) => time.padStart(5, '0'));
1Like

Comments

  1. @morishin_1002

    Questioner

    詳細にありがとうございます。

    元データの関数を調整しまして、以下のようにすることで対応しました!

    時分秒の部分は 08:00 のように0で埋めて各2桁

    実行してみたところ、解決しました!(そのほかにも少し不具合あったのですが、おかげさまで全て解決して、運用のせられそうです。)
    ありがとうございました!

この内、早番(8:00-17:00)と通し勤務(8:00-20:00)でのみ、デバックすると以下のようなエラーが排出されます。

08:00-17:00のように、時:分を2桁で入力すればどうでしょうか。

1Like

Comments

  1. @morishin_1002

    Questioner

    実行してみたところ、解決しました!(そのほかにも少し不具合あったのですが、おかげさまで全て解決して、運用のせられそうです。)
    ありがとうございました!

Your answer might help someone💌