
④「Vol.5 スプレッドシート:ノンプロ研初心者向けプログラミング講座【GASコース第9期】
ヘッダ画像:ある日の食卓。ほうれん草のおひたしは、レンチンで。熱が通ったら、冷水で締めることが肝要。それをしないと余熱でグダるらしい。サラダにパクチーと砕いたピーナッツが入ると東南アジア風。ピーナッツが無かったので胡桃。シソは合法ハーブ(言い方)。
↓これの続きです。
演習5-09 セル範囲の値を配列で取得
このようなシートで、コードを実行するとこうなる。
getDataRange()でA1からC4までの範囲を取り、
getValues();で値を二次元配列で取得している。
イメージ図は講座のスライドが分かりやすい。
演習5-10 セル範囲の値を配列で入力する
今度は逆に、値をセットしていく。get&Set。
サンプルコード。
const sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(row, column, numRows, numColumns).setValues(二次元配列);
ここで注意すべきは、Rangeオブジェクトの範囲と配列のサイズが合わないとエラーになること。lengthプロパティでサイズを決めればズレない、とのこと。
getRange(行番号, 列番号, values.length, values[0].length)
実際にスクリプトを実行してみる。
実行すると、シートに情報が書き足された。
まず、このコード
sheet.getRange('A3:C4').setValues(persons);
これによって、A3:C4の範囲に、personsがセットされた。
試しに、この範囲をA3:C3として実行すると、
Exception: The number of rows in the data does not match the number of rows in the range. The data has 2 but the range has 1.
例外: データの行数が範囲内の行数と一致しません。 データは 2 ですが、範囲は 1 です。(自動翻訳)
personsのデータが2行分なのに、範囲が1行やぞ、と、怒られる。
次のコード
sheet.getRange(6, 1, persons.length, persons[0].length).
getRange(行番号, 列番号[, 行数, 列数])であるから、
6行目、1列目を基点として、persons.length(今回は2)、persons[0].length(今回は3)という範囲で、personsの値がセットされた。
最後の列数はpersons[0].lengthとしているから、例えば、Tomの年齢がわからんような場合は、空データとして“”を入れておかないとズレる。
試しに、const persons = [['Tom', 'orage']のようにすると、このようなエラーになる。
Exception: The number of columns in the data does not match the number of columns in the range. The data has 2 but the range has 3.
例外: データの列数が範囲内の列数と一致しません。 データは 2 ですが、範囲は 3 です。
として、怒られる。
宿題 演習5-11
以下のA1からC4のセル範囲をE3を基点とするセル範囲にコピーするスクリプトを作りましょう。
また、シート2のA1からC4にコピーするスクリプトを作成してみましょう。
まず最初のお題を考える。A1からC4のセル範囲をgetして、E3を基点とするセル範囲にsetしたい。
まずは雑に書いてみる。
Exception: The number of rows in the data does not match the number of rows in the range. The data has 4 but the range has 1.
例外: データの行数が範囲内の行数と一致しません。 データは 4 ですが、範囲は 1 です。
として怒られた。getRange('E3')があかんかった。
これでどうだっ。
行と列が逆だった~~~。
できた。
もう一個。シート2のA1からC4にコピーするスクリプトを作成する。
シート1のA1からC4のセル範囲を、シート2のA1からC4のセル範囲にコピーてことでいいのかな??
うーん、これだと、sheet01.getDataRange()で全範囲を取ってしまっているから、A1からC4のセル範囲を指定したほうがいいかな?
演習5-12 appendRow
シートの最終行に追加できるappendRow、あ~なんか処理したあとに自動で一行足されると嬉しい場面あるかも......。
function myFunction5_12() {
const sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow(['Ivy', 24, 'banana']);
}
ふむ、6行目、A~D列は空白だけど、E列以降にデータがあるから、6行目が最後と判断されて7行目に追加されたんだな、なるほ。
appendRowしつつ、上の行の書式を引き継ぐ形ができたら、実戦で使いたいかも。
宿題 演習5-13
以下の3つの値を引数として受け取り、シートの最終行にデータを追加する関数を作りましょう。
・name
・age
・favorite
関数好きやな!
関数作るときは、いつもこのサンプルコードを見てから組み立てています。
function myFunction3_02Review() {
console.log(calcArea(3, 4));
}
function calcArea(x, y) {
return x * y;
}
うーん、こうかなあ。
む~~~違う~~~~。う~~~んこうかなあ。
動作としては、意図したとおりのはず。問題文の日本語の読み取りがまた不安になってきた。
ちょっと整えて、こうかなあ。
宿題 演習5-14
以下の配列を引数として受け取り、シートの最終行にデータを追加する関数を作りましょう。
[name, age, favorite]
さっきの5-13と何が違うねん...えっと、落ち着いて、えーと、配列?
さっきは値を引数として受け取りだったけど、今度は、配列を引数として受け取り、で、いいの??
うーん、
なんじゃこりゃ。
う~~~ん、ちゃんと person 配列になってるよねえ?
う~~~ん???あ、関数名だ、またやっちった。
あってるはずーーー!
宿題 演習5-15
以下の構造のオブジェクトを引数として受け取り、シートの最終行にデータを追加する関数を作りましょう。
{
name: 'Bob',
age: 25,
favorite: 'apple'
}
今度はオブジェクトってことね、OK、わかった、合ってるかなあ??
ぐぬぬ。そうだ、appendRow(配列)だった。てことは、オブジェクトを配列に変換する作業がどこかで必要なのか???どこで、どうやって???
「GAS オブジェクト 配列 変換」でググったら、ノンプロ研のもりさんのブログがトップヒットだった。ノンプロ研こわい。
Object.entries(obj)
→ オブジェクトの「キーと値のペア」を配列にして返す【二次元配列】
これでいけるか?
と思ったら、再び。
console.logしたら、
こうなってる。あ~~~違うな~~~う~~~ん。
flatしてみたりしつつ、あ~~~う~~~ん、
あ、Object.valuesにすればいいのか?
Object.values(obj)
→ オブジェクトの「値」を配列にして返す
も~~~よく見て~~~自分~~~~
いけそうじゃない?
function myFunction5_15() {
const person = {
name: 'Bob',
age: 25,
favorite: 'apple',
};
const personArray = Object.values(person);
lastRowByObject(personArray);
}
function lastRowByObject(p) {
const sheet = SpreadsheetApp.getActiveSheet();
return sheet.appendRow(p);
}
どやあ!!!!
ありゃ、違った。うーん、どうしよう。
こういうことか?
//これまでの講座を前提にしたversion
function myFunction5_15_02() {
const person = {
name: 'Bob',
age: 25,
favorite: 'apple',
};
lastRowByObject(person);//オブジェクトをpersonとして渡す
}
function lastRowByObject(person) {//仮引数としてpersonを受け取る。
const sheet = SpreadsheetApp.getActiveSheet();
return sheet.appendRow([person.name, person.age, person.favorite]);//配列にする。ドット記法
}
//これまでの講座を前提にしたversion+アロー
function myFunction5_15_03() {
const sheet = SpreadsheetApp.getActiveSheet();
const person = {
name: 'Bob',
age: 25,
favorite: 'apple',
};
const lastRowByObjectArrow = person => sheet.appendRow([person.name, person.age, person.favorite]);
lastRowByObjectArrow(person);
}
//Object.valuesを使ったversion
function myFunction5_15_04() {
const person = {
name: 'Bob',
age: 25,
favorite: 'apple',
};
lastRowByObjectValues(person);//オブジェクトをpersonとして渡す
}
function lastRowByObjectValues(person) {//仮引数としてpersonを受け取る。
const sheet = SpreadsheetApp.getActiveSheet();
return sheet.appendRow(Object.values(person));//配列にする。
}
講座日程
05/07(金) はじめてのGAS、変数、演算、データ型
05/14(金) 制御構文
05/21 (金) 関数、配列
05/28 (金) オブジェクト
06/04 (金) スプレッドシート・シート・セルの操作
06/11 (金) スプレッドシートの操作(実践編)
06/25(金) 卒業ライトニングトーク大会
残すところあと二回。あっという間だなあ。
いいなと思ったら応援しよう!
