ノンプロ研GAS中級講座 第1回 スコープと関数 その5
前回のnote
ひ~~だいぶ遅れております。
復習がてら動画を観ながら、演習いってみよう。
まとまり切ってないけど、noteに放出しちゃう。
演習1-14
なんだかよくわからんが、5行目がグレーアウトしてるからだめっぽいな、という雰囲気がある。エディタ賢い。
8行目、戻り値がない関数を呼び出しているため
戻り値=undefined となる。
returnと戻り値
・returnされるとその関数の処理は終了
・戻り値がない関数の戻り値はundefined
演習1-15
引数とメモリの関係
値渡し
参照渡し
このへんはまだハラオチしてないです。
サンプルコードみると、そのときはなるほどな?と思うんですが、すぐ忘れる&実戦でどう使うかまだイメージが持ててない。
演習1-16 ★宿題
アクティブなスプレッドシートについて、以下のプロパティまたはメソッドを持つオブジェクトを生成して返す関数を作成してください。なお、シートは1枚のみ存在するものとします。
・Sheetオブジェクトを表すプロパティ
・シートの使用範囲の値の二次元配列を表すプロパティ
・残り使用可能なセル数を整数で返すメソッド
今回の大ボスです。最初、何言ってんのかさっぱりわかりませんでした。日本語なのに意味がわからない。
これまで、とくに初級は、ひとつの演習につき、ひとつの技で対応できたことが多かったですが、今回のこれは「関数」と「オブジェクト」を理解して連携させること、それがキモになるようです。
とにかくこの問題は私にとっては分からなすぎたので、TA回答をみつつ、読み解く方向でこの問題に取り掛かりました。ひとつひとつの用語も、GAS本みつつ。
コードを読み解く
構造としては下記のような形になる。はず。
function myFunction1_16_2() {
//アクティブなスプレッドシート を次の function getSheetInfo2_ に渡す
}
function getSheetInfo2_(仮引数1, 仮引数2) {
//アクティブなスプレッドシートについて、以下のプロパティまたはメソッドを持つオブジェクトを生成して返す関数
// ・Sheetオブジェクトを表すプロパティ
// ・シートの使用範囲の値の二次元配列を表すプロパティ
// ・残り使用可能なセル数を整数で返すメソッド
}
この文字で書いたところを実現するために、いろいろなコードを書いている。
次に、TA回答を見つつ、一行ずつ、何の目的でどういう動きをしているのか、コメントを入れながら見ていった。
// アクティブなスプレッドシートについて、以下のプロパティまたはメソッドを持つオブジェクトを生成して返す関数を作成してください。なお、シートは1枚のみ存在するものとします。
// ・Sheetオブジェクトを表すプロパティ
// ・シートの使用範囲の値の二次元配列を表すプロパティ
// ・残り使用可能なセル数を整数で返すメソッド
function myFunction1_16_2() {
const sp = SpreadsheetApp.getActiveSpreadsheet(); //アクティブなスプレッドシートを定義
const sheetInfo = getSheetInfo2_(sp, 'シート1');//getSheetInfo2_(Private関数)に引数として sp と シート名を渡す。
console.log(sheetInfo.sheet, sheetInfo.values, sheetInfo.getAvailableCellNum());
}//ドット記法でプロパティ(オブジェクトの入れ物の名前)を指定し、オブジェクトから値を取り出す。この場合、sheetInfoオブジェクトの中のsheetやvaluesを取り出している。
/**
* スプレッドシートの情報を格納したオブジェクトを返す(シート名で指定する場合)
* @param {SpreadsheetApp.Spreadsheet} sp
* @return {Object} sheet:シートオブジェクト, values:データ範囲の値, getAvailableCellNum():使用可能なセル数
*/
function getSheetInfo2_(sp, sheetName) {//9行目の引数(sp, 'シート1')が、この20行目の関数に対して仮引数として渡されている。
const sheetInfo = {
// ・Sheetオブジェクト。:の左がプロパティ(入れ物の名前)、右が値。11行目にこれをドット記法で値を取り出し、ログ出力している。
sheet: sp.getSheetByName(sheetName),
// ・シートの使用範囲の値
values: sp.getSheetByName(sheetName).getDataRange().getValues(),
// ・残り使用可能なセル数を整数で返すメソッド(メソッドとは、オブジェクトの要素として関数を持たせた場合は、その要素をプロパティと呼ばずに「メソッド」と呼ぶ)
getAvailableCellNum() {
const sheets = sp.getSheets();
let cellNum = 5000000;
for (const sheet of sheets) {
cellNum -= sheet.getMaxRows() * sheet.getMaxColumns();
}
return cellNum;
}
};
return sheetInfo;
}
で、今回ここで一番よくわからなかったのが
「Sheetオブジェクトを表すプロパティ」だった。
↓コードを実行するとこうなる。
なお、紐づいているスプレッドシートは分かりやすいように1セルのみ使用という状態にしてある。
・Sheetオブジェクトを表すプロパティ→{}
・シートの使用範囲の値の二次元配列を表すプロパティ →[ [ 'ああああ' ] ]
・残り使用可能なセル数を整数で返すメソッド →4999999
という結果になっている。
Sheetオブジェクトを表すプロパティ が 空白の{}とはこれ如何に?
というか、そもそもオブジェクトをうまく理解できていないよな???
何がどうわからないんだ?
そんな状態です。
オブジェクトとは?
const person = {name: 'Bob', gender: 'male', age: 25};
console.log(person.name);
このへんのことを頭にいれたうえで、理解していく必要がある。
・Sheetオブジェクトを表すプロパティ→{}
これは何なのか?
具体的な情報はないけど、オブジェクトだよ、と返している、ということになるようだ。
sheet: sp.getSheetByName(sheetName),は、元をたどれば
const sp = SpreadsheetApp.getActiveSpreadsheet(); なので、
やっていることとしては
sheet: SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName),
となる。ドット記法で、Googleサービス群の中のスプレッドシートだよ、さらにその中のアクティブシートだよ、その中の指定名称のシートだよ、と指定している。
sheet: SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName).getName()
とすれば、{} でなくて、シート名が返ってくるので、まだ分かりやすいかもしれない。
sheet: SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName),
↑sheet=プロパティ、箱のラベル。
↑SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName),=箱の中身。値。
.getName() のように、getSheetByName(sheetName)の中に含まれているオブジェクトと具体的な情報を指定すればそれを返してくれるが、getSheetByName(sheetName)だけだと、これはオブジェクトですよという塩対応的な返事が返ってくる、というざっくりとした理解に留まっている。
なにかこう、抽象的な感じ。
この演習1-16についてslackであれこれ訊いてたところ、なんと補講をしていただける機会を得た。貴重な休日に、本当にありがたい。
当日は、絵文字をログ出力できたりという、ちょっと脇道に逸れたけど面白い発見もあって楽しかった。
配列とオブジェクトの違い、その説明や使い分けはまだまだだが、理解が一歩進めたかなと思う。しかし、うまく言語化できないので、やっぱまだかな、とも思う。実務でこのへんを使い倒すのが一番いいんだろうな~。
/*****/
ふう、やっと第1回の分について、宿題の提出とnoteの更新ができたかな。
遅れてますが、ちみちみやってます。
研修日程
09/21火 スコープと関数
10/05火 クラス・ライブラリ
10/19火 組み込みオブジェクト
11/02火 Script Services 1 ←リアルタイム受講できんかったのでビデオ観ないと
11/16火 Script Services 2 ←次ここ
11/30火 HTTP通信・API
12/14火 卒業LT大会
クラス・ライブラリ、 組み込みオブジェクトの宿題もまだあるんだよ~ひ~~~