見出し画像

【GAS】2.プログラミング基礎

 この記事は全文が無料である。読み終わった後に幸せな気持ちになっていたら、ぜひお金を落としていってほしい。


 これからGASを扱うにあたって、やはりプログラミング脱初心者をしていきたいところである。というか、やっているうちに覚えるものであるが、さすがに何も知らない状態からは何も吸収することができない。GASの基礎というか、JavaScriptの基礎を押さえたものである。


2. プログラミングの基礎を学ぼう

 プログラミングとは果てしないものであるという認識の方もいらっしゃるかもしれないが、実は非常に簡単な概念で構築されている。

  1. 逐次処理

  2. 反復処理

  3. 条件分岐処理

  4. モジュール

 逐次処理とは、最初から1文字ずつ読んでいき、文字を言葉として認識していくプロセスである。これは実は人間がやっていることと類似している。
 反復処理は、いわゆるfor文while文で、「同じことを何回もやる」という処理である。ここは、やはり人間と機械の一番差がつく部分である。人間がやったら途方もない作業も、機械がやれば1秒もかからない、というのがプログラミングの価値を高めている。
 そして条件分岐処理だが、これはいわゆるif文である。「これがこうだったらこうして、ああだったらああして…」というものだ。これは反復処理に比べたら人間でもできそうだが、機械は非常に複雑なものを、正確に処理することができる。クオリティという意味で、やはり人間を超越している部分である。
 最後に、モジュール化という考え方を紹介する。本質的には変数宣言(これをこう略します!)と同じである。これを極限まで行えば、綺麗で読みやすい、扱いやすいプログラミングが実現できる。

 実はこれだけである。私含め、学校でプログラミングを習う世代だが、「習うのってこれだけでよいのかしら」「もっと複雑なこともあるのではないかしら」と思った経験があるだろう。否、本当にこれだけである。しかも1番の逐次処理に関しては勉強をすることではないので、大事なのはfor文とif文のみである。

2-1. for文を用いた例

 Logger.logを用いて、簡単にfor文の使い方を学ぼう。

function myFunction() {
  for (i=0;i<10;i++) { //0から始めて、i<10を満たすうちは、iを1ずつ増やしながら
    Logger.log(i + "周目だよ"); //iは今何周目かを表す変数として使える。
  }
}

 これをコピペしよう。そして実行すると…?

2-1 実行例

 for文は、まず()の中身に、3つのことを記述する必要がある。(JavaScriptの場合)それぞれをセミコロンによって分割する。( ; )
 一つ目は変数 i を「いくつから始めるか」
 二つ目は変数 i が「実行中に満たすべき条件」
 三つ目は変数 i を「どのように変化させるか」
 という構成である。今回の場合は、i を 0 からスタートして、「 i < 10を満たすうちはループ」、すなわち i が10になったら終了、そしてその間は「 i を1ずつ増やしていく」( i++という特殊な記法)という意味である。ログを見れば、確かに0から始まり、10になったら実行されずに終わるから、ログは i が9のときで終了しているのが分かる。

function myFunction() {
  for(i=9;i>=0;i=i-1) {
    Logger.log(i + "周目だよ");
  }
}

 こういう書き方もできる。少しずつ自分で変えてみると楽しいだろう。もちろん i++のように i--とも書ける。

2-2. if文を用いた例

 今度は、時間を用いてif文を勉強しよう。

function myFunction() {
  var time = Date.now(); // 現在時刻をミリ秒単位で取得
  Logger.log("現在時刻は、1970年1月1日から数えて" + time + "ミリ秒です。");
  if(time % 2 === 1) { // %は剰余演算
    Logger.log("奇数だね!");
  } else { // 奇数ではない、ということは、偶数。
    Logger.log("偶数だね!");
  }
}

 せっかくなのでちょっとずつ新しいことを学んでいこう。GASでは非常に重要な概念「Date型」というのが存在する。これは、日付を1970年1月1日からミリ秒単位でずっと数えていくものである。
 var time = Date.now();
 これは、これを実行した瞬間のミリ秒単位の時刻をtimeという変数に保存している。これの中身はバカでかい数字である。

2-2 if文の例

 意外と54年間を秒単位で表すとこんなもんなんだ、と思う。光陰矢の如しである。何回も実行すると、確率1/2の二項分布を感じられて良い。

 さて一番重要な条件分岐の部分である。まず、非常に重要な概念である「真偽値」について書く。
 真偽値とは、「正しい(true)」か「正しくない(false)」かの二つのみの概念である。Bool値、Booleanとも呼ばれる。コンピュータは本質的にはこの真偽値(1か0)のみで動いており、計算機科学ではBool代数という学問分野があるほどだ。if文は、
 if ( 真偽判定文 ) {}→ この真偽判定文が、trueならば{}の中身を実行する。falseならば{}の中身は実行しない(飛ばす)。

 この場合は、「time % 2 === 1」というのが真偽判定文で、正しいか正しくないかのどちらかである。

A % B → AをBで割った余り。5 % 2 → 1。8 % 4 → 0。
=== → 左と右が「型まで含めて合致しているか」を判定する真偽判定要素。ちょっとラフでいいなら == という演算子を使う。trueかfalseのどちらかを返す。
演算子 → 演算に使う記号。+ とか = とかいろいろある
else → if文の判定文に対して、その判定文がfalseのときに実行される部分。trueのところとfalseのところは対になっていて、どちらかしか実行されない。

2-3. for文とif文の合わせ技

function myFunction() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  for(i=1;i<101;i++) { // 1から100
    if(i % 2 === 0){
      if(i % 3 === 0){
        sheet.getRange(i,1).setValue("6の倍数だ!");
      } else {
        sheet.getRange(i,1).setValue("2の倍数だ!");
      }
    } else {
      if(i % 3 === 0) {
        sheet.getRange(i,1).setValue("3の倍数だ!");
      } else {
        sheet.getRange(i,1).setValue("2の倍数でも3の倍数でもないよ!");
      }
    }
  }
}

 簡素かつ無粋なものだが、for文とif文を合わせたものだ。機能としては、A1からA100のセルに、2の倍数か3の倍数か6の倍数かどれでもないかを書き込むものとなる。ループをするにつれて、iが1から100まで変化していく。そのiについて、毎回判定をしていく。このくらいのif文の入れ子は見られるようになってほしい。これを実行すると、

倍数判定

 このようになるはずだ。機械の強みは、100でも1000でもすぐに実行できるところにあるだろう。

const → 今回はvarではなくてconstというのを使ってみた。役割はvar(let)と大きく変わらないが、constとすると、それ以降その変数の中身を変更することができない

2-4. モジュール化

 例えば、約数を数える関数を用意してみよう。

function myFunction() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  for(i=1;i<101;i++) { // 1から100
    //iの約数の個数を数える
    var count = 0;
    for(j=1;j<=i;j++) { // iはもう使っているので、i以外の変数を使う
      if(i%j === 0) { //割り切れる場合に、countを1増やす。
        count++;
      } // 割り切れた個数分、countが増えている→約数の個数
    }
    sheet.getRange(i,1).setValue(count); // それを書き込む。
  }
}

 これを実行すると

約数の個数

 行数に応じた約数の個数が表示されている。そんなに難しいことをしているわけではないが、試しにこれをモジュール化してみよう。モジュール化とは、関数として機能をまとめてしまうことだ。今回は、「与えられた引数に対して、約数の個数を数えて返却する」という機能を持つ関数としてまとめておこうと思う。下のコードは、上のコードと機能は全く同じである。

function myFunction() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  for(i=1;i<101;i++) { // 1から100
    //iの約数の個数を数える
    var count = countYakusuu(i); // 返り値がある場合、このように代入させることができる
    Logger.log(i + "の約数の個数は" + count + "個");
    sheet.getRange(i,1).setValue(count);
  }
}

function countYakusuu(num) { // 引数として調べたい数を受け取る
  var count = 0; // 初期化、と言う。
  for(j=1;j<=num;j++) {
    if(num%j === 0) {
      count++;
    }
  }
  return count; // 返り値として、約数の個数を返す。
}

 このくらい短いコードだとあまりありがたさを感じられないかもしれないが、規模が大きくなってくるといかにうまく綺麗にモジュール化できるかどうかが大事になってくる。


 お金に余裕がある方は、ぜひ私にお金をめぐんでくだせえ

ここから先は

0字

¥ 100

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