『GAS』はじめました ~第2回~

目次

1.   スプレッドシートの処理

お久しぶりです!
前回から長時間空いてしまいましたが、しれっと再開させていただきますね!

今回はスプレッドシートの処理を実施したいと思います。
2回目にしていきなり本丸に攻め込んでしまいますよ!

材料は以下の通り、
 ・ 処理したいデータが記載されているスプレッドシート
以上です。
あれま簡単!なんと、これだけでオッケーなのです!

用意していただくスプレッドシートは数値が記載されていて、それをもとに算出した結果をセットできるセルがあればお好きな内容で結構です。
私はこんなスプレッドシートを準備してみました。

商品の在庫を管理している表で、総額欄を空けています。
ということで、お気づきかと思います。
そうです、ここに計算した結果を入れる処理をGASで作ってしまおうというもくろみなのです。
自分のデータを自分で計算する、そんな自己完結しているスプレッドシートを作成します。

データが入っているスプレッドシートと、GASのコーディングが含まれている(コンテナバインドされている) スプレッドシートを別々にすることもできます。
でも、データとGASのコーディング、両方を含んだスプレッドシートにすることには以下のメリットがあるのです。

・プログラムがシンプルになる

同じスプレッドシート環境内であれば、GASで「このスプレッドシートを開いて!」と指示する命令が1行ですむ。

・行方不明にならない

『集計する表』と『それを動かすプログラム』がセットになっているので、コピーしたり、移動したりしても、お互いを見失わない。

・権限の設定がわかりやすい

そのスプレッドシートを編集できる人であれば誰でも、そこに記述されたGASが使用できる。

という具合に我々初心者にも取り扱いがしやすいので、これで実施しますね。

2.   GAS再

それでは、用意したスプレッドシートにGASを記述していきます。
前回の『スプレッドシートから作成する』のコンテナバインド型ですね。
ってもうだいぶ前のことになってしまっているので、改めて
用意したスプレッドシートの『拡張機能』→『Apps Script』からGASの画面を開きましょう。

『Apps Script』をポチっとします。


久しぶりのGASの画面です。

3.   プロジェクト名をつけてみましょう

前回はしませんでしたが、今回はきちんと名前をつけますね。
『無題のプロジェクト』ではなんか寂しいですもんね。
ところで、『プロジェクト』ってなんでしょう?ちょっとGemini に聞いてみます。

 Gemini君、曰く

「GASの『プロジェクト』というのは、マクロやプログラムを書き込むための
 『1冊のノート(ファイル)』のことだよ。
 ノートの中に『スプレッドシートを自動化するプログラム』とか
『メールを自動送信するプログラム』といったページ(コード)を書き込んでいくイメージ。
Googleドライブに保存されるファイルそのもの、と思ってもらえばOKです!」

だそうです。「のことだよ」とか最近のAIはフランクというか慣れ慣れしいですな。
まあ、そういうふうに接すると喜ばれると教え込まれているのでしょう。
わかりやすく説明してくれているので、これを採用いたします。
そのノートの名前が『無題の・・・』になっているので、後で見てわかりやすいように変えますね。

『無題のプロジェクト』の上にカーソルを
 持っていくと
『名前を変更』と出てきますのでクリックすると


こんなポップアップが出現します。
これを上書きしましょう。
お好きな名前で結構です。
私は、とりあえず『GAS演習1』にしておきます。


で、『名前を変更』をクリックします。

すると名前が変わりました。


なあに、付けた名前が気に入らなかったら、
また変えてしまえばよいのです。
これで、攻略開始を宣言したような気になって
きました。
(私だけですか?)。
いよいよ、本丸へ攻め込みましょう。

4.   スプレッドシートを指定します

まず、作った商品在庫管理表(GAS講義用サンプル)をGASに認識させます。
それが、以下のコードです。

function myFunction() {
 // 1, スプレッドシートを指定する
 const ss = SpreadsheetApp.getActiveSpreadsheet();
}

この命令を分解して一つずつ確認していきます。

・const ss とは?

const はデータ定義の宣言で、一度定義した内容の変更は基本的にできないようになっています。
(例外もありますが、今はスルーさせてください) ss という名称にしたのは spreadsheet だから
単純に ss としただけで、お好きなお名前で結構です。

・SpreadsheetApp.getActiveSpreadsheet(); とは?

『SpreadsheetApp』はスプレッドシートを処理するための技の一覧です。
で、『getActiveSpreadsheet』はアクティブなスプレッドシートをゲットするという、
今まさに開いているスプレッドシートを処理対象とするという命令です。

なので、『const ss = SpreadsheetApp.getActiveSpreadsheet();』は
それをいちいち指定せずに『ss』という領域を定義して、そこに
『SpreadsheetApp.getActiveSpreadsheet()』という命令を封じ込めてしまうということに
なります。

命令の後ろの ’()’ ですが、たとえ中が空っぽでも、これは必須です。
GASはこれを見つけてからコードを動かすという仕組みになっていて、これがないと動きません。
この ’()’ の中には『引数』というデータが入ることもありますが、空っぽであっても、これを確認してから命令を実行する ’きっかけ’ になるものです。

そして最後の ‘;’ (セミコロン) です。
実はこれ、なくても命令的に終わっていると判断してくれるのですが、普通の文章の’ 。’ (句点) と同じで、ここで終わりという区切りを明確に入れておいた方が良いという文法上の決まりとして記述しています。
「入れるクセをつけておきましょう」と先輩に教えてもらいました。
(まあ、最近はメール文とかでも、句点があると高圧的に見えるから書かないようにしましょうとかいう新しい常識が広がってきて、句点も肩身の狭い思いをしていますが)
例えば、2つの命令を1行に入れてしまっても、セミコロンがあればそれぞれの命令の終わりがわかりますからね。

セミコロンを入れて終わるクセをつけておけば、他の人にもわかりやすいコーディングができますし、必ず入れるようにしたいですね。
* YouTube 等で、GASを教えている動画を見ると、先生がセミコロンを打ってなかったりしていますけれど。

ということで最初の命令は、

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
}

となります。
これをそのままコピペしていただいても良いです。
で、スプレッドシート商品在庫管理表(GAS講義用サンプル)への最初のコードが
入りました(もちろんここではご自分の作成されたスプレッドシートが指定されます)。

さっそく、実行してみたいと思います。

『ドライブにプロジェクトを保存』というポップアップが表示されています。

このフロッピーディスクのボタンを押して保存します。

そして、実行してみましょう。


この実行ボタンを押します。
すると、


こんなポップアップが出てきたではありませんか!
承認が必要ですと!
私は人畜無害な小市民ですぞ!
何も咎めを受けるようなことはしておりません!

と、ここで、慌ててはいけません。
これは、『あなたが生み出そうとしているアプリが、スプレッドシートを見たり、
修正したりする権限を与えちゃってもいいですかね?』と聞かれているのです。
ここは自信を持って、「これから生み出す私のGASに、権限を与えることを許可する!」
ということで『権限を確認』ボタンを押します。
すると、今度は以下のようなポップアップが出てくるかもしれません。

ここでも、これから作成する『GAS演習1』 は
「大丈夫、悪いことする心配ないからね」
ってことで、











『続行』をクリックしましょう。
これで、私の『GAS演習1』は晴れてプログラムとして世に出ることになるのです。
おめでとう!

その結果が、

無事実行されたということで、このような表示が出てきます。
しかし、まだ、ひとつめの命令を実行したにすぎません。これからですね。

★ コピペできるコードは『6. 一つめの商品の単価を取得しましょう』と
最後に全部を入れておきますね。コピペされる方は使用してください。

5. スプレッドシート中の特定のシートを指定します

スプレッドシートの中で、データが入っている目的のシートをGASに教える必要があります。
その命令は、

  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName(‘シート1’);

です。

今度の const では ‘sheet’ という領域を定義しました。
‘ss’ がスプレッドシート全体で、’sheet’ はその中の一枚のシートということです。

で、’ ss.getSheetByName(‘シート1’); ‘ は
『ss というスプレッドシートの中から、’シート1’ という名前のシートをゲットしてきて』
という命令になるわけです。

命令は自分で探すのは大変なので、Gemini とかに探してもらうと早いです。
探してきた命令をそのままコピペすると楽ですね。
参考書とかを見ながら自分で打ち込むと、綴りをミスったりすることがあるかもしれませんし。

この ‘getSheetByName ‘ をよく見ると、小文字と大文字が混じっています。
単語の切れ目の頭のSとBとNが大文字です。
これはキャメルケースというプログラム記述の技法で、キャメル=ラクダのコブのように
単語の頭の一文字を大文字で表記します。
こうすると、違う単語を繋げる時にスペースやバーやアンダーバーで繋げなくても見やすくなるので、
誤りを防ぐことができます。
GAS の命令では、この表記法が使用されます。
なので、全部小文字にしたり、全部大文字にするとエラーになってしまい、命令を実行してくれないので
注意が必要です。

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName(‘シート1’);
}

これも実行してみましょう。



と表示されました。
うまく実行できたようです。

6. 一つめの商品の単価を取得しましょう

次に一つ目の商品の単価を取得しましょう。
例では、シート1の表のセル D2 に入っている ’¥120,000’ をGASに取ってきてもらいます。

そのコードは、

  // 3, セルD2から単価を取得する
  const price = sheet.getRange(‘D2’).getValue();

となります。
今回の const で定義したのは 単価なので ‘ price ‘という名前にしました。
皆さんは、お好きな名前でよいですので。
で、今度の命令は ‘ sheet.getRange(‘D2’).getValue(); ‘ です。
sheet からgetRange(‘D2’) = D2というエリアをロックオンして、そこから
getValue = 中身を取ってこい 、そして const price = price に書き写しなさい 
という命令です。

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName(‘シート1’);
  // 3, セルD2から単価を取得する
  const price = sheet.getRange(‘D2’).getValue();
}

これも実行してみましょう。

いや、順調。まあAIに聞いた内容を実行しているのだから当然と言えば当然ですが。

ここで、ちょっと気になったのが・・・
『実行完了』と、明るく知らせてくれてはいるけれど、本当にできてるの? という点です。
いや、GAS のことは信頼しているけれど、疑っているわけではないけれど、
まだ知り合ってから日が浅いし、証拠が欲しいかなと。

つまり、『実行完了』しているのを形として確認したいんですよね。
それは皆さんも感じていらっしゃるでしょう。
そこで、朗報です!
確認する方法があるのです。
それが 今回ご紹介する’ console.log() ‘ なのです。
この ’ () ’ の中に確認したい、定義した項目を入れます。
ここでは ‘ price ’ ですね。

  // 3.1, セルD2の値が price に入ったか確認する
  console.log(price);

これを一番下に入れます。

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName(‘シート1’);
  // 3, セルD2から単価を取得する
  const price = sheet.getRange(‘D2’).getValue();
  // 3.1, セルD2の値が price に入ったか確認する
  console.log(price);
}

で、実行すると、

『情報』 という言葉の後に price に書き込まれた金額の ‘120000’ が表示されました!
なんかそっけない表示の仕方ですが、これで、確かに ‘price ‘ にD2セルの内容が書き込まれたことが確認できました!
GAS よ、君をチラとでも疑ってごめんなさい。ちゃんとやってくれてるんだね。
ということです。

でも、GASで長いコーディングをして、エラーがなくても、実行結果が期待したものと違っていたら、
どの時点でおかしくなったのかわからなくなってしまいますからね。
私ら初心者ですから、最初のうちは慎重に経過がわかる要所要所で、
この console.log を入れて確認しながら作っていくのが良いかなと思います。
* console.log 以外に Logger.log() という命令で確認する方法もあるのですが、
今は console.log で確認するのが主流のようです。

★ ここまでのコードをまとめておきます。
 コピペされる方は下のコードを使用してください。
ご自分の作成されたスプレッドシートのコンテナバインドしたGASのコード部分を上書きしてください。
‘ const ‘ の名称はご自分で定義した名前を使用されてください。
(ここでは  ‘ss’ と’sheet’ と ‘price’ ですね。
また、シート名の ‘シート1’ と セルの ‘D2’ も、ご自分のスプレッドシートで定義した名前に合わせて変えてください)。

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName('シート1');
  // 3, セルD2から単価を取得する
  const price = sheet.getRange('D2').getValue();
  // 3.1, セルD2の値が price に入ったか確認する
  console.log(price);
}

7.   金額に消費税をのせてみましょう

単価は無事に取得できました。そこでちょっと欲を出して、消費税分も入れてみたいと思います。
早速、消費税の定義をします。

  console.log(price);
  // 4, 消費税率を設定(今回は10%固定)
  const taxRate = 0.1;

税金なので、taxRate にしてみました。これも const で定義します。で10%だから ‘ 0.1 ‘ を
セットしました。
これを先ほどの単価に加えます。

  // 5, 単価に消費税をのせた金額を求める
  const taxIncluded = Math.floor(price * (1 + taxRate));

ネットで調べた税込み = taxIncluded をそのまま使ってみました。
で、’ Math.floor ‘ という命令ですが、これは ’ Math’ = 数学的命令、
’ floor ‘ = 直訳すると床ですが、小数点以下を切り捨てるということです。
‘ price * (1 + taxRate) ‘ price’ に 1 + 0.1 つまり 1.1をかけて消費税を入れた金額を
計算するということです。
で、うまく計算できたか確認してみましょう。

  // 5.1, 消費税分が入って金額になっているか確認
  console.log(taxInclude);

実行します。

あれまっ!エラーになってしまったではありませんか!
ここで、あわてない。一呼吸おいて エラーの内容を見てみると、
taxInclude is not defined ‘ ですと。
このレベルの英語なら私でもわかりますよ。
「taxInclude なんか定義されてないよ!」 と言っているわけです。
そう、定義したのは ’ taxInclude ‘ じゃなくて ’ taxIncluded ‘ でした。
名前の間違いですね。
でも、定義した時点では、なんもエラー出てなかったのに・・・
今まで経験してきた他のプログラミング言語だと、未定義の名前を使ったら、
即アウトになってたんですよ。

調べると、どうやらGASは実行するまでは定義されていなくても保留にしてくれる
ようなのです。
この詳細についてはまた次回とさせていただきます。
定義されているかどうかを確認するには、調べたい領域の名前の上にカーソルを位置づけて
クリックすると、その名前を使用している所の色が変わります。

例えば、定義した ’ price ‘ を調べてみましょう。
※ここでは定義している色の濃淡の状態で確認するためにここはスクショで載せています。

7番目の行の ’ price ‘ の上にカーソルを位置付けて、クリックしてみると

‘const price ‘ の ‘ price ‘ の背面が薄青になりました。
そして、’ console.log(price); ‘ の ‘price ‘ の背面が薄灰色になりました。
これは、初めて ‘ price ‘ が定義された所は薄青、それが使用されている所は薄灰色の背景色にすることでわかりやすくしてくれているのです。

というわけで 13行目の taxIncluded をクリックすると

なんか12行目にが浮かんでるんですけど? 
これは「ひらめいた!」の電球マークだということです。懐かしい昭和の漫画の表現みたいですね。
これを押してみると

こんなポップアップが表示されました。



これはGASが「こうした方がよくない?」と提案してくれているということです。

・『Remove unused declaration for ‘taxIncluded’ 』は

「‘taxIncluded’って使われてないけど、削除する?」という提案をしている。

・『Ignore this erro messege』は

「この警告は無視するよ」

・『Disable chacking this file』は

「このファイルでは、このようなチェックはしません」つまり「ほっておいてくれ」という意味。

と、親切に提案してくれています。
ですが、この場合は 定義された‘ taxIncluded ‘ を使用すべき箇所で‘ taxInclude ‘ と
誤入力してしるのが原因です。

よーく見ると、13行目の‘ taxIncluded ‘ は、色が薄くなっていました。
これは、いざ const で定義されて誕生してみたものの、どこでも使用してくれていない
という肩身の狭い思いを薄い色で表しているのです。

そこで、15行目の ‘ taxInclude ‘ を ‘ taxIncluded ‘ と修正すると、

ということで、陰になり日向になって私達のGASのコーディングを助けてくれているこの機能は
『エディタ』と呼ばれています。
これからも助けてもらうことになりますね。
エラー対応したので、再度実行してみます。







というわけで、無事に消費税分がのっかった金額が
でました。

8.   金額に個数を掛けましょう

次はこの金額に個数を掛けて総額を求めます。
私の表では在庫数はE2 のセルに入っています。

これをさっき求めた消費税込みの金額に掛ければ求められるわけです。
E2セルの在庫数を取得します。

// 6. セルE2の在庫数を取得する
  const number = sheet.getRange(‘E2’).getValue();

個数を単純に ‘ number ‘ という名前で定義しました。
皆さんはお好きな名称でかまいません。
そして、先ほどの税込み金額にこの個数を掛けて総額を求めてみます。

  // 7. 消費税が入った金額に個数を掛けて総額を求める
  const total_amount = Math.floor(taxIncluded * number);

これで実行しても、結果がどうなっているのかはわかりませんので、
console.log で確認します。

  // 7.1 総額が求められているか確認する
  console.log(total_amount);

実行してみます。






計算してみましたが、結果の金額はあっています!

9.   算出された総額を表のセルにセットしましょう

この結果を『総額』のセルにセットすれば一連の処理はコンプリートですね!
そのコーディングは、

  // 8. 総額をF2セルに設定する
  sheet.getRange(‘F2’).setValue(total_amount);

これをまた分解してみます。

・sheet

指定した今開いているシート。

・getRange(‘F2’) 

そのF2のRsnge(領域) を get(ロックオン) せよ。

・setValue(total_amount)

total_amount の Value(内容) を set(設定) せよ。

ということで実行してみましょう。

今回の実行結果は console.log で確認する必要はなくて
直接、スプレッドシートの表に出てきています。

というわけでこれでセルの中のデータを計算に使用して、その結果を指定のセルに設定するところまでできました!
で、当然、「まだ1行分しかできてないじゃないの?」と思われることでしょう。

ということで、次回は、F6 まで同様の処理を繰り返す、『ループ』 という技を実施しましょう。

★ 今回のコード全部を、コピペ用にまとめました。
 よろしければ使用してください。
 その際、ご自分で定義したエリア名やシート名に変えてくださいね。
 全く同じ名称で作成していただいた方はそのまま使用できますので。

function myFunction() {
  // 1, スプレッドシートを指定する
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 2,『シート1』を指定する
  const sheet = ss.getSheetByName('シート1');
  // 3, セルD2から単価を取得する
  const price = sheet.getRange('D2').getValue();
  // 3.1, セルD2の値が price に入ったか確認する
  console.log(price);
  // 4, 消費税率を設定(今回は10%固定)
  const taxRate = 0.1;
  // 5, 単価に消費税をのせた金額を求める
  const taxIncluded = Math.floor(price * (1 + taxRate));
  // 5.1, 消費税分が入った金額になっているか確認
  console.log(taxIncluded);
  // 6. セルE2の在庫数を取得する
  const number = sheet.getRange('E2').getValue();
  // 7. 消費税が入った金額に個数を掛けて総額を求める
  const total_amount = Math.floor(taxIncluded * number);
  // 7.1 総額が求められているか確認する
  console.log(total_amount);
  // 8. 総額をF2セルに設定する
  sheet.getRange('F2').setValue(total_amount);
}


今回はここまでです。
最後までおつきあいいただき、ありがとうございます!
次回もよろしくお願いいたします!

『GAS』はじめました ~第3~ Coming soon



目次