LANG SELRCT

コードを書く場所についてはこちら

2017年12月10日日曜日

Googleカレンダーで特定の条件に当てはまるカレンダーの予定を取得する

特定の条件に当てはまるカレンダーの予定を取得して
シートに一覧表示したくて書いたコードです

このコードを書くために関連記事を幾つか新しく書いたようなのものなので
詳細についてはそれぞれの記事に委ねます


コード.gs
function get_specific_schedules(){
  var calenders = get_calenders();
  for(var i = 0; i < calenders.length; i++){
    var id = calenders[i][1];
    get_schedules(id);
  }
  sort();
}

function get_calenders(){
  var calenders = CalendarApp.getAllCalendars();
  var array = [];
  for(var i = 0; i < calenders.length; i++){
    var id = calenders[i].getId();
    if(id.match(/@group.calendar.google.com/)){
    var name = calenders[i].getName();
    array.push([name, id]);
    }
  }
  return array;
}

function get_schedules(id) {
  var target_id = id;
  var calender = CalendarApp.getCalendarById(target_id);
  var start_date = get_date(0);
  var startTime = new Date(start_date);
  var end_date = get_date(1);
  var endTime = new Date(end_date);
  var schedules = calender.getEvents(startTime, endTime);
  var array = [];
  for (var i=0; i < schedules.length; i++) {
    var title = schedules[i].getTitle();
    var start_time = schedules[i].getStartTime();
    var end_time = schedules[i].getEndTime();
    var duration = (end_time - start_time) / (1000 * 60);
    var location = schedules[i].getLocation();
    start_time = Utilities.formatDate(start_time, 'Asia/Tokyo', 'yyyy/MM/dd-HH:mm')
    end_time = Utilities.formatDate(end_time, 'Asia/Tokyo', 'yyyy/MM/dd-HH:mm');
    array.push([start_time, title , end_time, (duration + "min"), location]);
  }
  set_values(array);
}

function get_date(add_day) {
  var now = new Date();
  var year_now = now.getFullYear();
  var month_now = now.getMonth();
  var date_now = now.getDate();
  var new_date = new Date(year_now, month_now, date_now + add_day); 
  var result = Utilities.formatDate(new_date, 'Asia/Tokyo', 'yyyy/MM/dd');
  return result;
}

function set_values(array) {
  var sh = SpreadsheetApp.getActiveSheet();
  var last_row = sh.getLastRow();
  var start_row = last_row + 1;
  var start_col = 1;
  var num_rows = array.length;  
  if (array[0] == null) {
  } else {
    var num_cols = array[0].length;
    var range = sh.getRange(start_row, start_col, num_rows, num_cols);
    range.setValues(array);
  }
}

function sort() {
  var target_col = 1;
  var asc = true;
  var start_row = 2;
  var start_col = 1;
  
  var sh = SpreadsheetApp.getActiveSheet();
  var last_col = sh.getLastColumn();
  var last_row = sh.getLastRow();
  var num_rows = last_row - (start_row - 1);
  var num_cols = last_col - (start_col - 1);
  var range = sh.getRange(start_row, start_col, num_rows, num_cols);
  range.sort([{
    column: target_col,
    ascending: asc
  }]);
}
意訳
この処理は以下を実行する
get_calenders()の結果を取得して
カレンダーの数だけ以下を繰り返す
カレンダーのidを取得して
get_schedulesに渡す

sort()を実行して並べ替える


この処理は以下を実行する
すべてのカレンダーを取得して
取得した結果を入れる入れ物を用意して
取得したカレンダーの数だけ以下を繰り返す
カレンダーのidを取得して
もしidに@group.calendar.google.comが入っていたら
名前を取得して
arrayに追加する
入っていなければ何もせずに次のカレンダーを見る

取得した対象のカレンダーたちを返す


この処理は以下を実行する
target_idに取得したいカレンダーのIDを入れて
対象のカレンダーを取得して
get_dateに0を足した日付を取得して
いつからの予定を見るかstartTimeを取得して
get_dateに1を足した日付を取得して
いつまでの予定を見るかendTimeを取得して
その期間のカレンダーの予定を取得する
取得した予定を入れる入れ物を用意する(例ではarrayという名)
取得した予定の数だけ以下を繰り返す
予定のタイトルを取得して
予定の開始日時を取得して
予定の終了日時を取得して
終了日時から開始日時を引いた時間を分で出して
予定の場所を取得して
開始日時をフォーマットして
終了日時をフォーマットして
arrayに入れる

すべての予定を取得したarrayをset_valuesに渡す


この処理は以下を実行する
現在日時を取得して
西暦を取得して
月を取得して
日付を取得して
日付にadd_dayの日数を足して
フォーマットして
返す


この処理は以下を実行する
開いているシートを取得して
データの入っている最終行を取得して
その次の行を入力を開始する行に設定して
入力を開始する列を設定する(例では1列目を指定)
入力する行数はarrayの長さから取得して
もしarrayの0番目のデータがnullならなにもしない
nullでなければ
入力する列数はarrayの中の1行内のデータ数を取得して
入力を開始する行, 入力を開始する列, 入力する行数, 入力する列数で範囲を指定して
arrayのデータを入力する



この処理は以下を実行する
ソートする基準の列を指定して
昇順にしたければtrue, 降順にしたければfalseにして
ソートしたい範囲の先頭行を指定し(例では2行目)
ソートしたい範囲の先頭列を指定し(例では1列目(A列))

対象のシートを指定して(例では今開いているシート)
データが入っている最終列を取得し
データが入っている最終行を取得し
対象の行の数を取得し
対象の列の数を取得し
2行目の、1列目から、対象の行数、対象の列数を範囲に指定して
ソートする
基準にする列はtarget_colで指定した列
昇順はascで指定したとおり





おまけ


上のコードではカレンダー毎に予定を取得してシートに書き出していますが


  • すべてのデータを一気に書き出したい
  • 配列の状態でソートしてしまいたい


と思ってそれを実現するコードも書きました


var arrays = [];

というすべてのデータを入れる配列を用意して
カレンダー毎に取得した予定を順番にarraysの中に入れてゆく
最後のカレンダーまで取得したらarrays.sort()で並び替えてから
シートに一気に書き出す
ように書き換えたのが以下のコードです


コード.gs
var arrays = [];

function get_specific_schedules() {
  var calenders = get_calenders();
  for (var i = 0; i < calenders.length; i++) {
    var id = calenders[i][1];
    get_schedules(id);
  }
  Logger.log(arrays);
  var data = arrays.sort();
  set_values(data);
}

function get_calenders() {
  var calenders = CalendarApp.getAllCalendars();
  var array = [];
  for (var i = 0; i < calenders.length; i++) {
    var id = calenders[i].getId();
    if (id.match(/@group.calendar.google.com/)) {
      var name = calenders[i].getName();
      array.push([name, id]);
    }
  }
  return array;
}

function get_schedules(id) {
  var target_id = id;
  var calender = CalendarApp.getCalendarById(target_id);
  var start_date = get_date(0);
  var startTime = new Date(start_date);
  var end_date = get_date(1);
  var endTime = new Date(end_date);
  var schedules = calender.getEvents(startTime, endTime);
  for (var i = 0; i < schedules.length; i++) {
    var title = schedules[i].getTitle();
    var start_time = schedules[i].getStartTime();
    var end_time = schedules[i].getEndTime();
    var duration = (end_time - start_time) / (1000 * 60);
    var location = schedules[i].getLocation();
    start_time = Utilities.formatDate(start_time, 'Asia/Tokyo', 'yyyy/MM/dd-HH:mm')
    end_time = Utilities.formatDate(end_time, 'Asia/Tokyo', 'yyyy/MM/dd-HH:mm');
    arrays.push([start_time, title, end_time, (duration + "min"), location]);
  }
}

function get_date(add_day) {
  var now = new Date();
  var year_now = now.getFullYear();
  var month_now = now.getMonth();
  var date_now = now.getDate();
  var new_date = new Date(year_now, month_now, date_now + add_day);
  var result = Utilities.formatDate(new_date, 'Asia/Tokyo', 'yyyy/MM/dd');
  return result;
}

function set_values(array) {
  var sh = SpreadsheetApp.getActiveSheet();
  var last_row = sh.getLastRow();
  var start_row = last_row + 1;
  var start_col = 1;
  var num_rows = array.length;  
  if (array[0] == null) {
  } else {
    var num_cols = array[0].length;
    var range = sh.getRange(start_row, start_col, num_rows, num_cols);
    range.setValues(array);
  }
}