LoginSignup
1
8

More than 5 years have passed since last update.

スプレッドシートの私的Utilクラス

Last updated at Posted at 2018-01-07

環境

2018/1/7 時点のGoogleAppsScript

はじめに

スプレッドシートでツールを作る時に、使っている汎用クラスのまとめです。
ライブラリ化してしまったほうが良いのかも...。

先にまとめ

//////////////////////////////////////////////////////////////////////////////////
// 配列とhashに関する便利クラス
//////////////////////////////////////////////////////////////////////////////////

/**
* シートから連想配列を作成する
*
* @param {sheet} sh sheetクラス
* @param {int} lastRowNum shの最終行番号
* @param {int} lastColumNum shの最終列番号
* @param {int} keyColumNum keyにする列の番号
* @return {array} 連想配列 key:id value:id以外の列
*/
function sheetToHash(sh, lastRowNum, lastColumnNum, keyColumNum) {
  var idArray = sh.getRange(2, keyColumNum, lastRowNum, 1).getValues();
  var allArray = sh.getRange(2, 1, lastRowNum, lastColumnNum - 1).getValues();
  var hash = {};
  allArray.forEach(function(value, i) {
    hash[idArray[i]] = value;
  })
  return hash;
}

/**
* カラムのid名から列番号を取得する
*
* @param {array} hash 連想配列
* @param {int} columnNum カラム数
* @param {string} name カラムのid名
* @param {string} keyName hashのkey名
* @return {int} targetColumn 列番号
*/
function getTargetColumn(hash, columnNum, name, keyName){
  var targetColumn = -1;
  var headerRow = hash[keyName];
  for(var i = 0; i < columnNum; i++){
    if(headerRow[i] === name){
      targetColumn = i;
    }
  }
  return targetColumn;
}

/**
* 連想配列を2次元配列へ変換する
*
* @param {array} hash 連想配列
* @param {int} columnNum 列数
* @return {array} ms2DimensionArray 2次元配列
*/
function hashTo2DimensionArray(hash, columnNum){
  var ms2DimensionArray = new Array();
  var count = 0;
  for(var key in hash){
    ms2DimensionArray[count] = new Array();
    for(var i = 0; i < columnNum - 1; i++){
      ms2DimensionArray[count][i] = hash[key][i];
    }
    count++;
  }
  return ms2DimensionArray
}

解説

シートから連想配列を作成する

シートからgetRangeで取得したデータは2次元配列になっています。
そのままループして目的のデータを検索・加工しようとすると時間がかかり、データが多いとタイムアウトしてしまいます。
そこで2次元配列を特定の列をキーとした連想配列に変換します。

/**
* シートから連想配列を作成する
*
* @param {sheet} sh sheetクラス
* @param {int} lastRowNum shの最終行番号
* @param {int} lastColumNum shの最終列番号
* @param {int} keyColumNum keyにする列の番号
* @return {array} 連想配列 key:id value:id以外の列
*/
function sheetToHash(sh, lastRowNum, lastColumnNum, keyColumNum) {
  var idArray = sh.getRange(2, keyColumNum, lastRowNum, 1).getValues();
  var allArray = sh.getRange(2, 1, lastRowNum, lastColumnNum - 1).getValues();
  var hash = {};
  allArray.forEach(function(value, i) {
    hash[idArray[i]] = value;
  })
  return hash;
}

注)getRange(2,×,×,×) と2行目から取得しています。
  今のチームは1行目をシートのタイトル記載部分として確保しているためです。
  適宜変更してください。

カラムのid名から列番号を取得する

特定の列名が何番目にあるかを取得します。
シートの列数が変わっても対応できるようにするためです。

/**
* カラムのid名から列番号を取得する
*
* @param {array} hash 連想配列
* @param {int} columnNum カラム数
* @param {string} name カラムのid名
* @param {string} keyName hashのkey名
* @return {int} targetColumn 列番号
*/
function getTargetColumn(hash, columnNum, name, keyName){
  var targetColumn = -1;
  var headerRow = hash[keyName];
  for(var i = 0; i < columnNum; i++){
    if(headerRow[i] === name){
      targetColumn = i;
    }
  }
  return targetColumn;
}

連想配列を2次元配列へ変換する

シートに貼り付けたい時に使用します。
連想配列のままだとsetValues(配列)を使うことができないので2次元配列に戻します。

/**
* 連想配列を2次元配列へ変換する
*
* @param {array} hash 連想配列
* @param {int} columnNum 列数
* @return {array} ms2DimensionArray 2次元配列
*/
function hashTo2DimensionArray(hash, columnNum){
  var ms2DimensionArray = new Array();
  var count = 0;
  for(var key in hash){
    ms2DimensionArray[count] = new Array();
    for(var i = 0; i < columnNum - 1; i++){
      ms2DimensionArray[count][i] = hash[key][i];
    }
    count++;
  }
  return ms2DimensionArray
}

(ms2DimensionArrayって何でこんな名前にしたんだっけ...)

使用例

/**
* 対象のシートの加工後の2次元配列を取得する
*
* @param {string} spreadsheetId スプレッドシートのid
* @param {string} sheetName シート名
* @return {array} processedArray 加工後の2次元配列
*/
function getProcessedArray(spreadsheetId, sheetName){
  // シート取得
  var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
  if(sheet == null){
    Browser.msgBox(sheetName + "のシートが見つかりませんでした。");
  }
  // シートのhash取得
  var lastRowNum = sheet.getLastRow();
  var lastColumnNum = sheet.getLastColumn();
  var keyColumnNum = 2;
  var sheetHash = sheetToHash(sheet, lastRowNum, lastColumnNum, keyColumnNum);

  // 検索する列番号取得
  var nameRowNum = getTargetColumn(sheetHash, lastColumnNum, "name", "id");
  var dateRowNum = getTargetColumn(sheetHash, lastColumnNum, "date", "id");
  var flagRowNum = getTargetColumn(sheetHash, lastColumnNum, "flag", "id");

  // ここでsheetHashを加工する
  // sheetHashをループ for(var id in sheetHash) しながら、
  // sheetHash[id][nameRowNum] このように特定列にアクセスします

  //2次元配列に変換する
  var processedArray = hashTo2DimensionArray(sheetHash, lastColumnNum);
  return processedArray;
}

さいごに

gasはブラウザ上で完結して開発できて楽しいです!

1
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
1
8