農林水産DXセミナー2025(2)

2025年10月31日(金)に開催したセミナーの資料です。 10月16日に開催した第1回の続きです。 第1回で作ったスプレッドの「まとめ」の情報をカレンダに転記します。 転記にはGoogleAppsScript(GAS)を利用するため、プログラミングのセミナーとなります。

  1. スプレッドの作業をカレンダの予定として登録
  2. プログラムの説明
  3. カレンダの予定を削除

1.スプレッドの作業をカレンダの予定として登録

「まとめ」のシート情報をカレンダに転記する方法を記載します。 「まとめ」のスプレッドを開き、「拡張機能」、「Apps Script」とクリックします。

Apps Scriptの画面が表示されます。 名前を変更するため「無題のプロジェクト」をクリックします。

名前を入力したら「名前を変更」をクリックします。

プログラムは書き換えるので、不要な行を削除しておきます。

下記のプログラムを全てコピーして、Apps Scriptに貼り付けします。

JavaScript
/**
 * スプレッドシート起動時・メニューを追加
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  
  ui.createMenu('まとめ転記')
    .addItem('転記', 'createSchedule')
    .addItem('削除', 'deleteSchedule')
    .addToUi();
}

/**
* スプレッドシートからカレンダへ書き出し
*/
function createSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // シートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("農薬散布");

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // データが始まる行(一番上が1です)
  const topRow = 2;

  // topRowから1行ずつ、最終行まで処理します
  var lastRow = sheet.getLastRow();   // 最終行
  for (iRow = topRow; iRow <= lastRow; iRow++) {

    // 1行のデータを取得する
    var timeStamp = sheet.getRange(iRow, 1).getValues();  // A列
    var enchi = sheet.getRange(iRow, 2).getValues();      // B列
    var sagyoubi = sheet.getRange(iRow, 3).getValues();   // C列
    var sagyou = sheet.getRange(iRow, 4).getValues();     // D列
    var ryou = sheet.getRange(iRow, 5).getValues();       // E列
    var tani = sheet.getRange(iRow, 6).getValues();       // F列
    var bairitu = sheet.getRange(iRow, 7).getValues();    // G列
    var jyu = sheet.getRange(iRow, 8).getValues();        // H列
    var memo = sheet.getRange(iRow, 9).getValues();       // I列
    var photo = sheet.getRange(iRow, 10).getValues();     // J列
    var stat = sheet.getRange(iRow, 11).getValues();      // K列

    // 既に処理したものは除外します。
    if (stat == "済") {
      continue;
    }
  
    // カレンダーに登録するデータを作成する
    var startTime = new Date(sagyoubi);
    var title = enchi + " " + sagyou.slice(0,10);
    var options = {description:
      sagyou + "\n"
      + ryou + "\n" + tani + "\n" + bairitu + "\n"
      + jyu + "\n"
      + memo + "\n"
      + photo};

    console.log("title: " + title)

    try {
      // Googleカレンダーに書き込み
      calender.createAllDayEvent(title, startTime, options);
  
      // 済みにする
      sheet.getRange(iRow, 11).setValue("済");

      // エラーのとき
    } catch(e) {
      console.log(e);
    }

  }
  // 完了通知
  Browser.msgBox("完了");
}

/**
 * 指定日のカレンダにあるイベントを削除
 *  キーワードがタイトルに含まれるイベントが対象です。
 */
function deleteSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // 削除対象のキーワードを指定
  const keyword = "園地A";  // ここを変更してください
  
  // 検索期間を指定
  const startTime = new Date('2025/10/16');
  const endTime = new Date('2025/10/17');

  // 期間内のすべての予定を取得
  const events = calender.getEvents(startTime, endTime);  // 日付の範囲指定
  //const events = calender.getEventsForDay(startTime);   // 1日のみ指定
  
  // タイトルをチェックして削除
  for (let i = 0; i < events.length; i++) {
    const eventTitle = events[i].getTitle();
    Logger.log('イベントタイトル: ' + eventTitle);
    
    // タイトルにキーワードが含まれているか確認
    if (eventTitle.indexOf(keyword) !== -1) {
      Logger.log('イベント削除: ' + eventTitle);
      events[i].deleteEvent();
    }
  }

}

貼り付けたら、保存ボタンを押します。 GASは保存を実行しないと、前の状態に戻ります。

「実行」をクリックすると、アプリが実行されます。

最初の実行は承認が必要になるので、「権限を確認」をクリックします。

自分のアカウントを選択します。

権限の割り当てが終わりました。 警告が表示されていたら「×」をクリックしてください。

「実行」をクリックすると、作ったコードが実行され、メッセージが表示されます。 このとき実行されるのは「onOpen」と言う部分です。

これが実行されると、スプレッドのメニューに「まとめ転記」が表示されます。 Apps Scriptでプログラムの開発が終わったら、スプレッドの画面だけで実行できるようになります。 「まとめ転記」をクリックすると「農薬散布」シートの情報でカレンダにイベントが追加されます。

「農薬散布」シートは1件の情報があり、日付は10月16日です。 カレンダを確認すると、10月16日は何もイベントがありません。

実行してみます。 「まとめ転記」、「実行」とクリックします。

実行が終わると、完了が表示されるので「OK」をクリックします。

カレンダを確認すると、イベントが追加されています。

イベントをクリックすると詳細が表示できます。

スプレッドには転記済みの印として、K列に「済」が登録されます。

Apps Scriptを利用してスプレッドの情報をカレンダに転記する説明は終わりです。

2.プログラムの説明

スプレッドの情報をカレンダに転記するプログラムを説明します。

JavaScript
/**
 * スプレッドシート起動時・メニューを追加
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  
  ui.createMenu('まとめ転記')
    .addItem('転記', 'createSchedule')
    .addItem('削除', 'deleteSchedule')
    .addToUi();
}

/**
* スプレッドシートからカレンダへ書き出し
*/
function createSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // シートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("農薬散布");

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // データが始まる行(一番上が1です)
  const topRow = 2;

  // topRowから1行ずつ、最終行まで処理します
  var lastRow = sheet.getLastRow();   // 最終行
  for (iRow = topRow; iRow <= lastRow; iRow++) {

    // 1行のデータを取得する
    var timeStamp = sheet.getRange(iRow, 1).getValues();  // A列
    var enchi = sheet.getRange(iRow, 2).getValues();      // B列
    var sagyoubi = sheet.getRange(iRow, 3).getValues();   // C列
    var sagyou = sheet.getRange(iRow, 4).getValues();     // D列
    var ryou = sheet.getRange(iRow, 5).getValues();       // E列
    var tani = sheet.getRange(iRow, 6).getValues();       // F列
    var bairitu = sheet.getRange(iRow, 7).getValues();    // G列
    var jyu = sheet.getRange(iRow, 8).getValues();        // H列
    var memo = sheet.getRange(iRow, 9).getValues();       // I列
    var photo = sheet.getRange(iRow, 10).getValues();     // J列
    var stat = sheet.getRange(iRow, 11).getValues();      // K列

    // 既に処理したものは除外します。
    if (stat == "済") {
      continue;
    }
  
    // カレンダーに登録するデータを作成する
    var startTime = new Date(sagyoubi);
    var title = enchi + " " + sagyou.slice(0,10);
    var options = {description:
      sagyou + "\n"
      + ryou + "\n" + tani + "\n" + bairitu + "\n"
      + jyu + "\n"
      + memo + "\n"
      + photo};

    console.log("title: " + title)

    try {
      // Googleカレンダーに書き込み
      calender.createAllDayEvent(title, startTime, options);
  
      // 済みにする
      sheet.getRange(iRow, 11).setValue("済");

      // エラーのとき
    } catch(e) {
      console.log(e);
    }

  }
  // 完了通知
  Browser.msgBox("完了");
}

/**
 * 指定日のカレンダにあるイベントを削除
 *  キーワードがタイトルに含まれるイベントが対象です。
 */
function deleteSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // 削除対象のキーワードを指定
  const keyword = "園地A";  // ここを変更してください
  
  // 検索期間を指定
  const startTime = new Date('2025/10/16');
  const endTime = new Date('2025/10/17');

  // 期間内のすべての予定を取得
  const events = calender.getEvents(startTime, endTime);  // 日付の範囲指定
  //const events = calender.getEventsForDay(startTime);   // 1日のみ指定
  
  // タイトルをチェックして削除
  for (let i = 0; i < events.length; i++) {
    const eventTitle = events[i].getTitle();
    Logger.log('イベントタイトル: ' + eventTitle);
    
    // タイトルにキーワードが含まれているか確認
    if (eventTitle.indexOf(keyword) !== -1) {
      Logger.log('イベント削除: ' + eventTitle);
      events[i].deleteEvent();
    }
  }

}
/**
 * スプレッドシート起動時・メニューを追加
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  
  ui.createMenu('まとめ転記')
    .addItem('転記', 'createSchedule')
    .addItem('削除', 'deleteSchedule')
    .addToUi();
}

/**
* スプレッドシートからカレンダへ書き出し
*/
function createSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // シートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("農薬散布");

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // データが始まる行(一番上が1です)
  const topRow = 2;

  // topRowから1行ずつ、最終行まで処理します
  var lastRow = sheet.getLastRow();   // 最終行
  for (iRow = topRow; iRow <= lastRow; iRow++) {

    // 1行のデータを取得する
    var timeStamp = sheet.getRange(iRow, 1).getValues();  // A列
    var enchi = sheet.getRange(iRow, 2).getValues();      // B列
    var sagyoubi = sheet.getRange(iRow, 3).getValues();   // C列
    var sagyou = sheet.getRange(iRow, 4).getValues();     // D列
    var ryou = sheet.getRange(iRow, 5).getValues();       // E列
    var tani = sheet.getRange(iRow, 6).getValues();       // F列
    var bairitu = sheet.getRange(iRow, 7).getValues();    // G列
    var jyu = sheet.getRange(iRow, 8).getValues();        // H列
    var memo = sheet.getRange(iRow, 9).getValues();       // I列
    var photo = sheet.getRange(iRow, 10).getValues();     // J列
    var stat = sheet.getRange(iRow, 11).getValues();      // K列

    // 既に処理したものは除外します。
    if (stat == "済") {
      continue;
    }
  
    // カレンダーに登録するデータを作成する
    var startTime = new Date(sagyoubi);
    var title = enchi + " " + sagyou.slice(0,10);
    var options = {description:
      sagyou + "\n"
      + ryou + "\n" + tani + "\n" + bairitu + "\n"
      + jyu + "\n"
      + memo + "\n"
      + photo};

    console.log("title: " + title)

    try {
      // Googleカレンダーに書き込み
      calender.createAllDayEvent(title, startTime, options);
  
      // 済みにする
      sheet.getRange(iRow, 11).setValue("済");

      // エラーのとき
    } catch(e) {
      console.log(e);
    }

  }
  // 完了通知
  Browser.msgBox("完了");
}

/**
 * 指定日のカレンダにあるイベントを削除
 *  キーワードがタイトルに含まれるイベントが対象です。
 */
function deleteSchedule() {
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

  // 削除対象のキーワードを指定
  const keyword = "園地A";  // ここを変更してください
  
  // 検索期間を指定
  const startTime = new Date('2025/10/16');
  const endTime = new Date('2025/10/17');

  // 期間内のすべての予定を取得
  const events = calender.getEvents(startTime, endTime);  // 日付の範囲指定
  //const events = calender.getEventsForDay(startTime);   // 1日のみ指定
  
  // タイトルをチェックして削除
  for (let i = 0; i < events.length; i++) {
    const eventTitle = events[i].getTitle();
    Logger.log('イベントタイトル: ' + eventTitle);
    
    // タイトルにキーワードが含まれているか確認
    if (eventTitle.indexOf(keyword) !== -1) {
      Logger.log('イベント削除: ' + eventTitle);
      events[i].deleteEvent();
    }
  }

}

上記のプログラムは2つの機能を持ちます。 「function」 とカッコ{}で囲われた部分が1つの機能になります。 function は2つあり、onOpen()とcreateSchedule()です。

onOpen()は、スプレッドのメニューに「まとめ転記」を追加する機能です。 「実行」がクリックされたとき、もう1つの機能 createSchedule() を実行する内容です。

JavaScript
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  
  ui.createMenu('まとめ転記')   // メニュー表示名
    .addItem('転記', 'createSchedule')
    .addItem('削除', 'deleteSchedule')
    .addToUi();
}

createSchedule() はスプレッドの情報をカレンダに転記する処理です。

JavaScript
function createSchedule() {

以下はご自分のGoogleのアカウント(メールアドレス)を登録してください。

JavaScript
// 自分のGoogleアカウント
const gAccount = "********@gmail.com";

以下は転記する対象のシートを指定する部分です。 「農薬散布」のシートを指定しています。

JavaScript
// シートを取得
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("農薬散布");

以下の命令は、2行目(topRow)から1行ずつ、最後の行(lastRow)まで繰り返します。

JavaScript
for (iRow = topRow; iRow <= lastRow; iRow++) {

1行ずつセルの情報を読み出します。 GASではA列と表示せず「1」と表示します。 同様にB列は「2」です。 B列の情報は「enchi」に保存されます。

JavaScript
// 1行のデータを取得する
var timeStamp = sheet.getRange(iRow, 1).getValues();  // A列
var enchi = sheet.getRange(iRow, 2).getValues();      // B列
var sagyoubi = sheet.getRange(iRow, 3).getValues();   // C列
var sagyou = sheet.getRange(iRow, 4).getValues();     // D列
var ryou = sheet.getRange(iRow, 5).getValues();       // E列
var tani = sheet.getRange(iRow, 6).getValues();       // F列
var bairitu = sheet.getRange(iRow, 7).getValues();    // G列
var jyu = sheet.getRange(iRow, 8).getValues();        // H列
var memo = sheet.getRange(iRow, 9).getValues();       // I列
var photo = sheet.getRange(iRow, 10).getValues();     // J列
var stat = sheet.getRange(iRow, 11).getValues();      // K列

既に処理済みの情報をカレンダに登録しないよう、「済」とK列に書かれた行は、スキップします。

JavaScript
// 既に処理したものは除外します。
if (stat == "済") {
  continue;
}

これ以降がカレンダに登録する処理になります。 まずC列の作業日を、カレンダのイベントの日とします。

JavaScript
var startTime = new Date(sagyoubi);

カレンダのタイトルを決めます。 B列の園地とD列の作業(10文字だけ)をつなぎます。

JavaScript
var title = enchi + " " + sagyou.slice(0,10);

イベントの詳細に表示する内容を決めます。 メモや写真も登録しています。

JavaScript
var options = {description:
  sagyou + "\n"
  + ryou + "\n" + tani + "\n" + bairitu + "\n"
  + jyu + "\n"
  + memo + "\n"
  + photo};

カレンダに登録します。 tryで囲われているのは、エラーが発生したときの処理のためです。

JavaScript
try {
  // Googleカレンダーに書き込み
  calender.createAllDayEvent(title, startTime, options);
  
  // 済みにする
  sheet.getRange(iRow, 11).setValue("済");

  // エラーのとき
  } catch(e) {
    console.log(e);
  }
}

3.カレンダの予定を削除

上記2のプログラムに含まれています。 194行目以降の「deleteSchedule」が削除の機能になります。 指定日のイベントのタイトルに、キーワードと一致する文字があるとき、そのイベントを削除します。

以下の命令は定型で、毎回設定が必要になります。

JavaScript
  // 自分のGoogleアカウント
  const gAccount = "kawano.g13@gmail.com";

  // googleカレンダーの取得
  var calender = CalendarApp.getCalendarById(gAccount);

タイトルから削除対象を決めるキーワードを登録します。

JavaScript
  // 削除対象のキーワードを指定
  const keyword = "園地A";  // ここを変更してください

削除対象となるカレンダの日付を指定します。 以下のサンプルは日付の範囲指定です。 1日のみを対象とするときは、getEventsForDayの行を有効にしてください。

JavaScript
  // 検索期間を指定
  const startTime = new Date('2025/10/16');
  const endTime = new Date('2025/10/17');
  
  // 期間内のすべての予定を取得
  const events = calender.getEvents(startTime, endTime);  // 日付の範囲指定
  //const events = calender.getEventsForDay(startTime);   // 1日のみ指定

キーワードと一致するか調べて、削除するプログラムです。

JavaScript
  // タイトルをチェックして削除
  for (let i = 0; i < events.length; i++) {
    const eventTitle = events[i].getTitle();
    Logger.log('イベントタイトル: ' + eventTitle);
    
    // タイトルにキーワードが含まれているか確認
    if (eventTitle.indexOf(keyword) !== -1) {
      Logger.log('イベント削除: ' + eventTitle);
      events[i].deleteEvent();
    }
  }

株式会社ルークシステムの代表です。 社会人になってからずーっと、コンピュータの技術者です。 年齢が上がるとプログラムが作れなくなる、と聞いていましたが、今も必要になれば、あれこれ作っています。 私はプログラムを作る(設計すること)が楽しいので、これからも作り続けたいと思っています。