見出し画像

【GAS】Google Apps Script 活用事例 シューカツでもGoogleを使い倒そう!!SpreadsheetからGoogleカレンダーへお手軽登録

今回は、スプレッドシートからGoogleカレンダーに登録するスクリプトを紹介します。2020年の2月に、V8ランタイムへのアップデートがあり、それに合わせて、リライトしました。

登録イメージはこんな感じ

ちょうど、この記事を書いていた当初、大企業向け勤怠管理ソフトを提供するチームスピリットの株を買っていたので、株価が上がって欲しいという意味合いがあったんだと思います。ちなみにチームスピリットは受けた事すらありません。

スクリーンショット 2020-03-21 13.33.04

売上だけではなく、営業利益もチェックしよう。

売上規模は、会社の規模を知る上で、重要な指標です。ただし、売上というのは原価や販管費、経費、税金を引く前の総額です。それらを引いたときに手元に、どのくらいのお金が残るのかを知るのは大切だと、今の会社に入社してから、嫌というほど痛感しました。売上が大きくても99%使っていたら、残るのは、たった1%でしかありません。

企業のHPには売上は書いてあっても、利益率まで記載されている会社は少ないような気がします。

営業利益率は、本業で稼ぐ力を見る指標です。営業利益率と給与額は、ほぼ比例します。スタートアップでは、法人税の節税のために、投資加速フェーズとして、赤字上場するケースがありますが、そうではない会社の場合は、必ず営業利益を見るべきです。

僕のいる会社は、いわゆる労働集約産業です。こういった業種は、お金を社員やスタッフなど、より多くの人に分配してしまうため、取り分が少ない、つまり給与が低いという事を身を持って痛感しました。

一方で、Uberのように旧態依然の業界に、ITを武器に進出してくる会社もありますが、そこはゲームチェンジャーになり得る要素を持っているのかどうか慎重に判断する必要があるでしょう。

営業利益の高さと生産性の高さは比例する。

より少ない工数や手間暇で、より多くのお客様に商品やサービスを提供する手段を持っていれば、必然的に生産性は高く、営業利益率も高くなります。朝礼が1時間もあったり、紙に溢れた職場よりも、そういう生産性の高い職場で働きたい。

後述、2020年8月に転職出来ました。

Yahoo!ファイナンスが、結構分かりやすい。

最近、転職活動、自分の時間と労働力を提供する会社を選ぶためには、投資家目線が重要なんじゃないかと考えています。そういった投資家目線で会社を見る際に、情報がよく纏まっているサイトがYahoo!ファイナンスです。

そうため、Yahoo!ファイナンスのリンクを加えたり、求人ページや備考(その会社に関連する新聞記事などは見ておいた方がいいかもしれません。)など、あった方がいい項目を再考し、追加しました。

結果、こうなりました。(横に長くなっちゃう.....笑)

スクリーンショット 2020-03-20 22.27.02

ID
企業名
面接ステップ
会社所在地
企業HP
面接日
時刻
登録ステータス
応募媒体
求人ページ
Yahoo!ファイナンス
備考

を網羅しました。

IDは証券コード

Yahoo!ファイナンスは証券コードで検索できるので、証券コードをスプレッドシートに書いておくと便利です。証券コードは、東証のページでEXCELデータで配布されているようなので、そこから取得しました。

'https://stocks.finance.yahoo.co.jp/stocks/detail/?code=' + values[i][0];

こんな感じで書けば、出来そうな気がします。アクティブなセルを検知して、自動的にURLを付与するみたいな処理を書いたら便利そうなので、後で書いてみようと思います。

このブログは自分の備忘録も兼ねているので、とりあえず公開し、完成次第追記していく事にします。結構書いているうちにアイデアが浮かぶ事も多いです。

カレンダー登録 メインのスクリプト

function registarCal() {
 const calendar    = CalendarApp.getDefaultCalendar();
 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
 const sheet       = spreadsheet.getSheetByName('スケジュール登録');
 const values      = sheet.getDataRange().getValues();
 
 for(let i = 1; i < values.length; i++){
   if(values[i][0] !== '' && values[i][7] === '未登録'){
     
     const calTitle  = values[i][1] +' '+ values[i][2];
     const startTime = new Date(values[i][5]);
     startTime.setHours(values[i][6].getHours());
     startTime.setMinutes(values[i][6].getMinutes());
     
     
     const endTime = new Date(startTime);
     endTime.setHours(values[i][6].getHours()+1);//1時間後にイベントの終わりを設定する。
     endTime.setMinutes(values[i][6].getMinutes());
     
     /*移動距離と所要時間の算出*/
     const origin      = '神奈川県*********';//自宅
     const destination = values[i][3];//目的地
     
     const directions = Maps.newDirectionFinder()
     .setLanguage('ja')
     .setRegion('ja')
     .setOptimizeWaypoints(true)
     .setOrigin(origin)
     .setDestination(destination)
     .setMode(Maps.DirectionFinder.Mode.TRANSIT)
     .setDepart(new Date())
     .getDirections();
     
     console.log(directions);

     const route = directions.routes[0];
     const duration = route.legs[0].duration.text;//所要時間
     const distance  = route.legs[0].distance.text;//距離
     const instructions  = route.legs[0].steps;//ルート
     
     console.log(duration);
     console.log(distance);
     
    /*現状、最適とは言えないルートが表示されるため、時間はあまり当てになりません。注意が必要です。
      余裕を持った行動が大切なので、一応書いています。
    */
     let words = 
       '【所要時間】 ' + duration + '\n' + 
       '【移動距離】 ' + distance;
     
     
     /*カレンダーの詳細*/
     const eventDetail =  '【' + values[0][4] + '】 ' + '\n' + values[i][4] + '\n\n' +
                          '【' + values[0][10] + '】 ' + '\n' + values[i][10] + '\n\n' + 
                          '【' + values[0][8] + '】 ' + values[i][8] + '\n' + values[i][9] + '\n\n' + 
                          words + '\n\n' + values[i][11];
                          
     
     const options = {
       description: eventDetail,
       location:    values[i][3],
       sendInvites: true
     }
     
     console.log('catTitle %s startTime %s endTime %s',calTitle,startTime,endTime);
     console.log('options %s', options.description);
     calendar.createEvent(calTitle, startTime, endTime, options);
     
   }//if
 }//for 
}//end
const endTime = new Date(startTime);
endTime.setHours(values[i][6].getHours()+1);
endTime.setMinutes(values[i][6].getMinutes());

大体、面接は1時間前後が多いので、スクリプト側でデフォルトで1時間で設定しておきます。変わるようだったら、手動で変更します。ARRAYFORMULA関数は、GASと相性が良くないのでなるべく使わずに済むようにしています。

Maps Serviceを使えば、所要時間なども把握出来ます。

Maps serviceを使えば、出発地点から目的地までの大体の距離や移動に掛かる時間を算出する事が出来ます。ちょっと、まだ日本での精度はあまり良くないようです。徒歩に関してはベータ版になっていました。(海の上や国道がないルートを徒歩としている事もあります。)

.......最適なルートの表示は難しい。

.setOptimizeWaypoints(true)

最適なルートとは、駅から歩く距離を出来るだけ少なくするのが良いのか、少し歩いたとしても乗り換え無しで目的地まで向かう事を指すのか、金額が最安値である事を指すのか、時間が最短なルートが良いのか、雨だったら、なるべく濡れない方がいいとか。そういったメソッドが今の所、まだ無いようなので難しいのかもしれません。

optimaizeって、最適化みたいな感じだと思うのですが、上述したような理由からかイマイチでした。自分の望むルートになりませんでしたが、大体自宅から何分くらい掛かるかを把握する事が出来ます。

理系が恋に落ちたので証明してみたのアニメを見て、単語を知りましたが、循環セールスマンっぽい要素があって、僕が考えているよりもずっと難しいのかもしれません。

.setOrigin('Times Square, New York, NY')//出発地点
.addWaypoint('Lincoln Center, New York, NY')//経由地点
.setDestination('Central Park, New York, NY')//終着地点

確か、アニメでは、デートで、いかに効率的に遊園地を全てのアトラクションを周る事が出来るかみたいな感じだったと思います。

.addWaypoint('Lincoln Center, New York, NY')

が増えれば、増えるほど難しくなるんじゃないかと思います。数学かプログラミングに強い人、中学生にも分かるような感じで、僕に難しさの理由を教えて下さい。

登録したカレンダーに、情報追記するスクリプト


この記事が気に入ったらサポートをしてみませんか?