見出し画像

④「Vol.5 スプレッドシート:ノンプロ研初心者向けプログラミング講座【GASコース第9期】

ヘッダ画像:ある日の食卓。ほうれん草のおひたしは、レンチンで。熱が通ったら、冷水で締めることが肝要。それをしないと余熱でグダるらしい。サラダにパクチーと砕いたピーナッツが入ると東南アジア風。ピーナッツが無かったので胡桃。シソは合法ハーブ(言い方)。


↓これの続きです。


演習5-09 セル範囲の値を配列で取得

このようなシートで、コードを実行するとこうなる。

画像3

画像3

getDataRange()でA1からC4までの範囲を取り、
getValues();で値を二次元配列で取得している。

イメージ図は講座のスライドが分かりやすい。

画像3

演習5-10 セル範囲の値を配列で入力する

今度は逆に、値をセットしていく。get&Set。
サンプルコード。

const sheet = SpreadsheetApp.getActiveSheet();
 sheet.getRange(row, column, numRows, numColumns).setValues(二次元配列);

ここで注意すべきは、Rangeオブジェクトの範囲と配列のサイズが合わないとエラーになること。lengthプロパティでサイズを決めればズレない、とのこと。

getRange(行番号, 列番号, values.length, values[0].length)

実際にスクリプトを実行してみる。

画像4

実行すると、シートに情報が書き足された。

画像5


まず、このコード

sheet.getRange('A3:C4').setValues(persons);

これによって、A3:C4の範囲に、personsがセットされた。
試しに、この範囲をA3:C3として実行すると、

画像6

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']のようにすると、このようなエラーになる。

画像7

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にコピーするスクリプトを作成してみましょう。

画像8

まず最初のお題を考える。A1からC4のセル範囲をgetして、E3を基点とするセル範囲にsetしたい。

まずは雑に書いてみる。

画像9

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')があかんかった。

これでどうだっ。

画像10

画像11

行と列が逆だった~~~。

画像12

画像13

できた。

もう一個。シート2のA1からC4にコピーするスクリプトを作成する。
シート1のA1からC4のセル範囲を、シート2のA1からC4のセル範囲にコピーてことでいいのかな??

画像14

うーん、これだと、sheet01.getDataRange()で全範囲を取ってしまっているから、A1からC4のセル範囲を指定したほうがいいかな?

画像15

演習5-12 appendRow

シートの最終行に追加できるappendRow、あ~なんか処理したあとに自動で一行足されると嬉しい場面あるかも......。

function myFunction5_12() {
 const sheet = SpreadsheetApp.getActiveSheet();
 sheet.appendRow(['Ivy', 24, 'banana']);
}

画像16

ふむ、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;
}

うーん、こうかなあ。

画像17

む~~~違う~~~~。う~~~んこうかなあ。

画像18

画像19

動作としては、意図したとおりのはず。問題文の日本語の読み取りがまた不安になってきた。

ちょっと整えて、こうかなあ。

画像20

宿題 演習5-14

以下の配列を引数として受け取り、シートの最終行にデータを追加する関数を作りましょう。
[name, age, favorite]

さっきの5-13と何が違うねん...えっと、落ち着いて、えーと、配列?
さっきは値を引数として受け取りだったけど、今度は、配列を引数として受け取り、で、いいの??

うーん、

画像21

画像22

なんじゃこりゃ。

う~~~ん、ちゃんと person 配列になってるよねえ?

画像23

う~~~ん???あ、関数名だ、またやっちった。

画像24

画像25

あってるはずーーー!

宿題 演習5-15

以下の構造のオブジェクトを引数として受け取り、シートの最終行にデータを追加する関数を作りましょう。
{
 name: 'Bob',
 age: 25,
 favorite: 'apple'
}

今度はオブジェクトってことね、OK、わかった、合ってるかなあ??

画像26

ぐぬぬ。そうだ、appendRow(配列)だった。てことは、オブジェクトを配列に変換する作業がどこかで必要なのか???どこで、どうやって???

「GAS オブジェクト 配列 変換」でググったら、ノンプロ研のもりさんのブログがトップヒットだった。ノンプロ研こわい。

Object.entries(obj)
→ オブジェクトの「キーと値のペア」を配列にして返す【二次元配列】

これでいけるか?

画像27

画像28

と思ったら、再び。

console.logしたら、

画像29

こうなってる。あ~~~違うな~~~う~~~ん。

flatしてみたりしつつ、あ~~~う~~~ん、

画像30

あ、Object.valuesにすればいいのか?

Object.values(obj)
→ オブジェクトの「値」を配列にして返す

も~~~よく見て~~~自分~~~~

画像31

いけそうじゃない?

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);
}

画像32

どやあ!!!!

画像33

ありゃ、違った。うーん、どうしよう。


こういうことか?

//これまでの講座を前提にした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(金)  卒業ライトニングトーク大会

残すところあと二回。あっという間だなあ。


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

good-sun(a03)
いただいたサポートで、書籍代や勉強費用にしたり、美味しいもの食べたりします!