いよいよ近所の公園でもセミの声が聞こえてきましたが、みなさんの周りはいかがでしょうか?
通勤ルートに小学校があるのですが、彼らは夏休みを満喫中なんですよね。なんとも羨ましい…。
さて、今回は前回予告していた通り、Googleカレンダーを元にして、作業実績を作成します。
イメージ図(前回のものを再掲)
Googleのサービスの関係は下記の図のようになります。
では、実現したコードを見てみましょう。
HOUR_MILLISECOND = 60 * 60 * 1000;
DATE_MILLISECOND = 24 * HOUR_MILLISECOND;
function run() {
// 出力先スプレッドシートとシートの設定
var SSHEET_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var SHEET_NAME = "YYYYY"
// 出力先スプレッドシートのシートを取得
var sheet = SpreadsheetApp.openById(SSHEET_ID).getSheetByName(SHEET_NAME);
// 日付範囲の設定
var DATE_TERM = 5;
var startDate = new Date("2015/7/20");
var endDate = new Date(startDate.getTime() + DATE_TERM * DATE_MILLISECOND);
// デフォルト(初期表示)されるカレンダーを選択
var cal = CalendarApp.getDefaultCalendar();
// カレンダーのイベントを取得
var events = cal.getEvents(startDate, endDate);
var row = 0;
var column = 0;
var works = [""];
var result = [[""]];
for(var index in events) {
// イベントの名前、作業時間、実施日を取得
var title = events[index].getTitle();
var workTime = getWorkTime(events[index]);
var targetDate = getTargetDate(events[index]);
// イベントの名前がループ中に出てきたかを確認
row = works.indexOf(title);
// イベントの名前がループ中初めて出てきた場合
if(row == -1){
row = works.length;
result[row] = [];
result[row][0] = title;
works.push(title);
}
// イベントの実施日がループ中初めて出てきた場合
if(index == 0 || targetDate != getTargetDate(events[index - 1])){
column++;
result[0][column] = targetDate;
}
result[row][column] = result[row][column] == null ? workTime : workTime + result[row][column];
}
sheet.clear();
// 1行目(日付表示の行)の取得・書き込み
var header = getDateRow(result[0]);
sheet.getRange(1, 1, 1, header.length).setValues(new Array(header));
// 2行目以降の取得・書き込み
for(var sRow = 1; sRow < result.length; sRow++) {
var writeRow = getWriteRow(result[sRow]);
sheet.getRange(sRow + 1, 1, 1, writeRow.length).setValues(new Array(writeRow));
}
}
function getDateRow(arrray){
var dateRow = arrray;
dateRow.splice(1, 0, "合計");
return dateRow;
}
function getWriteRow(arrray){
var writeRow = replaceArrayNull(arrray);
var totalWorkTime = getTotalWorkTime(arrray);
writeRow.splice(1, 0, totalWorkTime);
return writeRow;
}
function replaceArrayNull(arrray){
for(var index = 0; index < arrray.length; index++){
if(arrray[index] == null){
arrray[index] = "";
}
}
return arrray;
}
function getTotalWorkTime(arrray){
var total = 0;
for(var index = 0; index < arrray.length; index++){
if(isFinite(arrray[index]) && arrray[index] != ""){
total += arrray[index];
}
}
return total;
}
function getWorkTime(event){
return (event.getEndTime() - event.getStartTime()) / HOUR_MILLISECOND;
}
function getTargetDate(event){
var sourceDate = event.getStartTime();
return (sourceDate.getMonth() + 1) + "/" + sourceDate.getDate();
}
DATE_MILLISECOND = 24 * HOUR_MILLISECOND;
function run() {
// 出力先スプレッドシートとシートの設定
var SSHEET_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var SHEET_NAME = "YYYYY"
// 出力先スプレッドシートのシートを取得
var sheet = SpreadsheetApp.openById(SSHEET_ID).getSheetByName(SHEET_NAME);
// 日付範囲の設定
var DATE_TERM = 5;
var startDate = new Date("2015/7/20");
var endDate = new Date(startDate.getTime() + DATE_TERM * DATE_MILLISECOND);
// デフォルト(初期表示)されるカレンダーを選択
var cal = CalendarApp.getDefaultCalendar();
// カレンダーのイベントを取得
var events = cal.getEvents(startDate, endDate);
var row = 0;
var column = 0;
var works = [""];
var result = [[""]];
for(var index in events) {
// イベントの名前、作業時間、実施日を取得
var title = events[index].getTitle();
var workTime = getWorkTime(events[index]);
var targetDate = getTargetDate(events[index]);
// イベントの名前がループ中に出てきたかを確認
row = works.indexOf(title);
// イベントの名前がループ中初めて出てきた場合
if(row == -1){
row = works.length;
result[row] = [];
result[row][0] = title;
works.push(title);
}
// イベントの実施日がループ中初めて出てきた場合
if(index == 0 || targetDate != getTargetDate(events[index - 1])){
column++;
result[0][column] = targetDate;
}
result[row][column] = result[row][column] == null ? workTime : workTime + result[row][column];
}
sheet.clear();
// 1行目(日付表示の行)の取得・書き込み
var header = getDateRow(result[0]);
sheet.getRange(1, 1, 1, header.length).setValues(new Array(header));
// 2行目以降の取得・書き込み
for(var sRow = 1; sRow < result.length; sRow++) {
var writeRow = getWriteRow(result[sRow]);
sheet.getRange(sRow + 1, 1, 1, writeRow.length).setValues(new Array(writeRow));
}
}
function getDateRow(arrray){
var dateRow = arrray;
dateRow.splice(1, 0, "合計");
return dateRow;
}
function getWriteRow(arrray){
var writeRow = replaceArrayNull(arrray);
var totalWorkTime = getTotalWorkTime(arrray);
writeRow.splice(1, 0, totalWorkTime);
return writeRow;
}
function replaceArrayNull(arrray){
for(var index = 0; index < arrray.length; index++){
if(arrray[index] == null){
arrray[index] = "";
}
}
return arrray;
}
function getTotalWorkTime(arrray){
var total = 0;
for(var index = 0; index < arrray.length; index++){
if(isFinite(arrray[index]) && arrray[index] != ""){
total += arrray[index];
}
}
return total;
}
function getWorkTime(event){
return (event.getEndTime() - event.getStartTime()) / HOUR_MILLISECOND;
}
function getTargetDate(event){
var sourceDate = event.getStartTime();
return (sourceDate.getMonth() + 1) + "/" + sourceDate.getDate();
}
赤字部分は実行環境に応じて必ず書き換えてください。
なお、"SSHEET_ID"には出力先として指定するスプレッドシートのIDを指定し、そのスプレッドシートのどのシートに出力するかを、"SHEET_NAME"(こちらはシート名)に指定します。
青字部分は実行時の都合に応じて書き換えてください。
カレンダーから抜き出す情報の開始日を"startDate"に指定し、開始日から何日分を取得するかを"DATE_TERM"に指定します。
実際に次のようなカレンダーに対して実行すると…
こんな感じに出力されました。
カレンダーの画像が小さくて分かりづらいですが、同じ作業が別の日にあった場合、行は1つに統一するようになっています。(具体的には"打ち合わせ"が7/21と7/24にあるところと、"開発"が7/22と7/24にあるところです)
なお、イベントが1つもない日(上記の図で言えば7/23)は、列が作成されない仕様なので、その点は注意してください。
他に注意するべき仕様として、終日の予定は24時間としてカウントします。
全ての予定と実績をGoogleカレンダーに書き込んでいる方は稀だと思いますが、日常的にGoogleカレンダーを業務で利用している方は、本当の作業実績を作成するための一助としてご利用ください。
0 件のコメント:
コメントを投稿