見出し画像

【GAS】中級の復習 その1(関数)

中級の復習もなんとか時間をやりくりして頑張っております。動画を見返して、自分用のノートにまとめながら、演習を解いて理解を深めていくスタイル。先生、中級に入ってから宿題が難しすぎませんか・・。(後述)

中級の1日目はスコープと関数。スコープについては特に新発見はなかったので割愛。強いていうならvarconst・letのまだ使い分けが分かっていないけど、そもそもGASでvar宣言を使うことはほとんどないという先生の言葉を信じてスルーする。(コラ)

関数については、基本の理解があやふやなまま中級に突入していたので、概念からしっかり理解し直す。

引数と仮引数

引数と仮引数は数が合わなくても動く。引数 > 仮引数の場合、余った引数は捨てられる。逆に引数 < 仮引数の場合、余った仮引数にはundefinedが入る。なんとなく分かるけど、「引数と仮引数の数が合ってません」的なエラーが出そうな感覚もある。引数と仮引数の数が合っていなくても動いてしまう、ということを認識して先に進む。

function myFunction1_10() {
 const coFunction = (x, y) => `x:${x},y:${y}`;

 console.log(coFunction(1, 2, 3)); //x:1,y:2
 console.log(coFunction(1)); //x:1,y:undefined
}


デフォルト引数

引数がない場合に仮引数の規定値を設定できる。どんな場面で使うのかな〜。いまいち実務のイメージがわかない。

function 関数名(, ...仮引数[ = 値]) {
//処理
return 戻り値;
}
function myFunction1_11() {
 const coFunction = (x = `hoge`, y = `fuga`) => {
   console.log(`x:${x},y:${y}`);
 }
 coFunction(); //x:hoge,y:fuga
 coFunction(1); //x:1,y:fuga
 coFunction(1, 2); //x:1,y:2
}


残余引数

余った引数を配列として受け取る。スプレッド構文と全く同じ書き方。むぅ、ちょっとだけ混乱する。

function 関数名(..., ...仮引数x) {
//処理
return 戻り値;
}
function myFunction1_12() {
 const coFunction = (...args) => {
   for (let i = 0; i < args.length; i++) {
     console.log(`引数${i}:${args[i]}`);
   }
 }
 coFunction(1, 2, 3, 5);
}
//引数0:1
//引数1:2
//引数2:3
//引数3:5


難しかった宿題1

中級になって宿題の難易度が高い。

Spreadsheetオブジェクトを渡すと、残り使用可能なセル数を返す関数を作成しましょう。(スプレッドシートの使用可能なセル数は500万セル)
function myFunction1_08() {
 const ss = SpreadsheetApp.getActiveSpreadsheet();
 console.log(availableCells(ss));
}

function availableCells(ss) {
 /**
  * スプレッドシートオブジェクトを渡すと残り使用可能なセル数を返す関数
  * @param {object} ss スプレッドシートオブジェクト
  * @return {number} 残り使用可能なセル数
  */
 const maxCells = 5000000;
 let usingCell = 0;
 const sheets = ss.getSheets();

 for (let i = 0; i < sheets.length; i++) {
   const values = sheets[i].getDataRange().getValues().flat();
   for (const value of values) {
     if (value !== ``) {
       usingCell += 1;
     }
   }
 }
 return maxCells - usingCell;
}

1回解いたはずなのに30分くらいかかったぜよ。。for文の中は以下のような処理をしている。

for (let i = 0; i < sheets.length; i++) //全てのシートの処理が終わるまで
  const values = sheets[i].getDataRange().getValues().flat(); //シートのデータを全て取得し、一次元配列に変換
   for (const value of values) {
     if (value !== ``) {
       usingCell += 1;
     }
   } //一次元配列の要素を順に取り出し、空っぽでなければ1をusingCellのカウントに足す

難しいよ〜( ;  ; )


難しかった宿題2

問題文の意図を読み取るのがまず難しい。小学校の国語からやり直してこようかな。

アクティブなスプレッドシートについて、以下のプロパティまたはメソッドを持つオブジェクトを生成して返す関数を作成してください。なお、シートは1枚のみ存在するものとします。
・Sheetオブジェクトを表すプロパティ
・シートの使用範囲の値の二次元配列を表すプロパティ
・残り使用可能なセル数を整数で返すメソッド
function myFunction1_16() {
 const ss = SpreadsheetApp.getActiveSpreadsheet();
 console.log(ssObj(ss));
}

/**
* アクティブなスプレッドシートについて以下のプロパティまたはメソッドを持つオブジェクトを生成して返す関数
* - Sheetオブジェクトを表すプロパティ
* - シートの使用範囲の値の二次元配列
* - 残り使用可能なセル数を整数で返すメソッド
* 
* @param {object} ss -アクティブなスプレッドシート
* @return {object} ssObj -上記3つの戻り値をプロパティまたはメソッドとして持つオブジェクト
*/
function ssObj(ss) {
 const activeSheet = ss.getActiveSheet();
 const usingRangeValues = activeSheet.getDataRange().getValues();
 let i = 0;
 let availableCellNum;
 for (const value of usingRangeValues.flat()) {
   if (value !== ``) {
     i += 1;
     availableCellNum = activeSheet.getMaxRows() * activeSheet.getMaxColumns() - i;
   }
   let ssObj = {};
   ssObj.sheet = activeSheet;
   ssObj.usingRangeValues = usingRangeValues;
   ssObj.availableCellNum = availableCellNum;
   return ssObj;
 }
}

ふぇー、こっちも難しかった( ;  ; ) オブジェクトのプロパティの追加など、初級で習ったこともフル活用してどうにか完成。たぶん合っているハズ・・。

次回はいよいよclass!元を辿ると、中級講座でclassの概念が全く理解できている感覚がなくて初級から復習し始めたんだよなー。引き続き頑張ります。

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