11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SLOGANAdvent Calendar 2017

Day 3

新卒一年目がGASで日報自動出力アプリケーションを作るまで(1/2)

Last updated at Posted at 2017-12-02

問題

「毎日提出する日報を毎日タイピングするのが面倒」
シンプルな問題ですね。可能な限り記入箇所を自動入力できるようにしたいです。

前提

弊社日報のフォーマットは

  • やったことの名前
  • 予定時間
  • 実績時間
  • 実績時間の合計
    という感じになってます(一応内部情報なんでぼやかします)

そして私はGoogleカレンダーで予定管理を行ってます
タスクをこなす前に予定をGoogleカレンダーに記入し、終わったら超過した時間をカレンダーに反映させ、次の予定の開始時間調整をし最終的にGoogleカレンダーに実績が記録されます

開発要件

つまり…Googleカレンダーと連携して始業時にタスクごとに予定時間を保存終業時に実績時間を保存し最終的に日報のフォーマットで出力されることが出来れば完璧です。

出来上がるイメージ

Webアプリケーションで
始業時に「予定記録」ボタンをクリックし予定時間を記録し
終業時に「実績記録」ボタンをクリックし実績時間を記録し
「日報出力」ボタンで日報を自動出力

技術選定

Googleカレンダー連携が簡単なため、GoogleAppsScriptを使用

開発の流れ

  • GASでWebアプリケーションを公開する
  • Googleカレンダーから今日の予定を吸い上げる
    (今回ここまで)
  • Googleカレンダーの予定をSpreadSheetに保存
  • SpreadSheetの内容を読み取ってWebアプリケーションに出力

GASでWebアプリケーションを公開する

以下2ファイルを新規にスクリプトファイルを作成して生成

nippo.gs
// アクセス時にindex.htmlを読み込む
function doGet(){
  return HtmlService.createHtmlOutputFromFile('index').setTitle('nippo').addMetaTag('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0');
}
index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <!-- とりあえずHello World -->
    Hello World
  </body>
</html>
  • スクリプトエディタの「公開」→「ウェブアプリケーションとして導入」
  • 「プロジェクトバージョンを指定」
  • 次のユーザーとしてアプリケーションを実行「ウェブアプリケーションにアクセスしているユーザー」
  • アプリケーションにアクセスできるユーザー「全員(匿名ユーザーを含む)」
  • 「導入」をクリック
  • 生成されたURLを開いてみる

Googleアカウントでログインすると見れます
スクリーンショット 2017-12-02 19.13.52.png

Googleカレンダーから今日の予定を吸い上げる

GAS上で吸い上げる

GoogleAppsScriptでGoogleカレンダーから予定を吸い上げるためには以下の通りにします。

// アクセス時にindex.htmlを読み込むよー
function getCal(){
  var cal_id = "★カレンダーID"
  //基本的にカレンダーのIDはメールアドレスですが、複数カレンダーを作成して運用している場合は「Googleカレンダー」→「取得したいカレンダーの『設定と共有』」→「カレンダーの統合」→「カレンダーのID」と探します
  var cal = CalendarApp.getCalendarById(cal_id);
  var now = new Date();
  var events = cal.getEventsForDay(new Date(now.getFullYear(), now.getMonth(), now.getDate()));
  
  for(var i=0; i < events.length; i++){
    //終日イベントかどうか判別
    if (events[i].isAllDayEvent()) {
    //終日イベントの場合はなにもしない
    } else {
      Logger.log(events[i]);
    }
  }
}

これではgetCalを実行して、ログを見てもイベントがいくら出力されるだけです
スクリーンショット 2017-12-02 17.46.57.png

それでは、それぞれの「イベント名」「開始時間」「終了時間」「所要時間」「イベントのID」を出力してみましょう

nippo.gs
function getCal(){
  var cal_id = "★カレンダーID"
  //基本的にカレンダーのIDはメールアドレスですが、複数カレンダーを作成して運用している場合は「Googleカレンダー」→「取得したいカレンダーの『設定と共有』」→「カレンダーの統合」→「カレンダーのID」と探します
  var cal = CalendarApp.getCalendarById(cal_id);
  var now = new Date();
  var events = cal.getEventsForDay(new Date(now.getFullYear(), now.getMonth(), now.getDate()));
  
  for(var i=0; i < events.length; i++){
    //終日イベントかどうか判別
    if (events[i].isAllDayEvent()) {
    //終日イベントの場合はなにもしない
    } else {
      Logger.log(events[i].getTitle()) //イベント名
      Logger.log(events[i].getId()) //イベントID
      Logger.log(events[i].getStartTime()) //イベント開始時間
      Logger.log(events[i].getEndTime()) //イベント終了時間
      Logger.log(events[i].getEndTime() - events[i].getStartTime()) //イベント所要時間
    }
  }
}

スクリーンショット 2017-12-02 18.02.45.png

結果をHTMLに書き出し

とりあえずイベント一覧をHTMLに書き出して見ましょう。
HTMLを以下のように変更して

index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
    function getdata(){
      google.script.run.withSuccessHandler(result).getCal();
      function result(data){
        document.getElementById("events").innerHTML = data;
      }
    }
   </script>
  </head>
  <body>
<button onclick="getdata();">今日の予定を出力</button>
<p id="events">ここに今日の予定が出力されます</p>
  </body>
</html>

JavascriptをHTML出力できるよう調整・返り値を設定

nippo.gs
function getCal(){
  var cal_id = "★カレンダーID"
  //基本的にカレンダーのIDはメールアドレスですが、複数カレンダーを作成して運用している場合は「Googleカレンダー」→「取得したいカレンダーの『設定と共有』」→「カレンダーの統合」→「カレンダーのID」と探します
  var cal = CalendarApp.getCalendarById(cal_id);
  var now = new Date();
  var events = cal.getEventsForDay(new Date(now.getFullYear(), now.getMonth(), now.getDate()));
  var event_list_str = "";
  
  for(var i=0; i < events.length; i++){
    //終日イベントかどうか判別
    if (events[i].isAllDayEvent()) {
    //終日イベントの場合はなにもしない
    } else {
      event_list_str = event_list_str + "イベント名:" + events[i].getTitle() + "<br>";
      event_list_str = event_list_str + "イベントID:" + events[i].getId() + "<br>";
      event_list_str = event_list_str + "開始時間:" + events[i].getStartTime() + "<br>";
      event_list_str = event_list_str + "終了時間:" + events[i].getEndTime() + "<br>";
      event_list_str = "<p>" + event_list_str + "所要時間:" + ((events[i].getEndTime() - events[i].getStartTime())/3600000) + "h</p>";
    }
  }
  return event_list_str
}

これでHTMLのボタンクリックすると今日の予定が一覧になって返ってくると思います。
スクリーンショット 2017-12-02 19.00.46.png

次回で予実の計算までできるようにしたいと思います。

スローガン株式会社のAdventCalendar

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?