見出し画像

【GAS】Google Apps Script 活用事例 電車料金を算出するスクリプト

従業員から提出された通勤経路や交通費が本当に正しいものかをチェックする作業を簡易化するため作成してみました。

今の勤め先ではIC料金での申請が義務付けられているため、労務担当者に使えねーと言われてしまったのですが、そういうニーズは少なくないのでは?と思ったので書き残しておきます。

シート名を "交通費チェック" にすることは忘れずに
Google Mapの乗り換え案内情報を提供しているのが、ジョルダンのようです。
英語になっていて、やや見にくいですが合っています。

注意点

-  IC料金を算出できない。
-  電車以外の、徒歩や自動車などはスクリプトを一部変更すれば可能
-  新幹線については出来ないかもしれない。
-  合理的な料金を算出するのは難しい。
   -  遠回りでも料金が経済的に合理的 or  通勤時間が一番短く合理的

こちらのコードではライブラリを使用しています。
そのままコピペだと動きません。
上記のエントリーを参考にしてください。

ライブラリへの追加はこんな感じ

スクリプトID

18rg2maFYXNmPmB2R-8s3UuFG850j5OLw4WBvcOrghzRMlfVbQWDgOVvZ

コードサンプル

/**
 * @customfunction
 * 
 * @param  {string} start - 出発駅
 * @param  {string} end - 到着駅
 * @return {Array.<string>} 料金, 経路
 * 
 * Google Mapの情報から経路と電車料金を返す関数
 * 
 */
function JORUDAN() {
  const sheet = SpreadsheetApp.getActiveSheet();
  // シート名を用途に応じて変更してください!! 交通費チェック以外のシート名では動きません
  if(sheet.getName() === '交通費チェック'){
    const activeCell = nepia_infinity.getActiveCell(sheet);
    const column     = getSheetHeader_(sheet);
    const currentRow = sheet.getRange(activeCell.row, 1, 1, sheet.getLastColumn()).getDisplayValues().flat();
    console.log(currentRow);
    console.log(currentRow[column.start]);

    if(currentRow[column.start] && currentRow[column.end]){
      const array = calculateTransitFare_(currentRow[column.start], currentRow[column.end]);
      return [array];

    }else{
      return

    }
  }
}



/**
 * シートヘッダーから列を取得
 * 
 * @param  {SpreadsheetApp.Sheet} sheet - シートオブジェクト
 * @return {Object.<number>}
 * 
 */
function getSheetHeader_(sheet){
  const headers = sheet.getDataRange().getValues()[0];
  const column  = {
    slackId: headers.indexOf('Slack ID'),
    start:   headers.indexOf('出発駅'),
    end:     headers.indexOf('目的駅'),
    fare:    headers.indexOf('料金'),
    route:   headers.indexOf('経路'),
  }

  console.log(column);
  return column
}



/**
 * 出発駅と目的地から料金、経路を算出する
 * 
 * @param {string} start - 出発駅
 * @param {string} end - 到着駅
 * @return {Array.<number, string>} 
 * 
 */
function calculateTransitFare_(start, end){

  // 経路探索を行う
  const finder = Maps.newDirectionFinder();
  finder.setOrigin(start); // 入力された出発地点をセット
  finder.setDestination(end); // 入力された到着地点をセット

  const currentTime = new Date(); // 出発時間をセットするため、現在時刻を取得
  finder.setAlternatives(true); // ベストパスだけではなく、代替経路も出力する
  finder.setLanguage('ja'); // 日本語を指定
  finder.setDepart(currentTime); // 出発時間をセット
  finder.setMode(Maps.DirectionFinder.Mode.TRANSIT) // 移動手段として電車を指定。BYCYCLING / WALKING / DRIVING も選択可
  const directions = finder.getDirections(); // 経路探索を実行
  // console.log(directions);

  let string   = '';
  let newArray = []

  for(const route of directions.routes){

    const fare  = route['fare']['value']; // 交通費(運賃)
    console.log(`料金:${fare}`);
    // console.log(route);

    const steps = route['legs'][0]['steps'];
    console.log(steps);

    for(const step of steps){

      const replaced = step['html_instructions'].replace(/まで歩く|日本、.* /g, '');
      if(replaced.includes('行') || replaced.includes('電車')) continue;
      string += `${replaced}\n↓\n`;
      
    }
    string = string.slice(0, -3);
    newArray.push(fare, string); // ['450', '千葉駅\n↓東京駅']
    console.log(newArray);
    return newArray
  }
}

こんな記事も書いています。


いいなと思ったら応援しよう!