はじめに
自己紹介
こんにちは。アベです。
普段はプロジェクトマネージャーをやりつつ自分でもコードを書いている、業界で言うところのプレイングマネージャーをやっています。
エンジニアとしては、Flutterを使ったスマホアプリ開発やNext.jsを使ったWebフロントエンド開発が得意分野です。
そんな僕に、最近プログラミング未経験者からプログラミング教えて的な相談が増えてきまして、
そこで、効率化も兼ねてプログラミング初学者が学ぶのにありだと思うGoogleAppsScriptという言語を紹介します。
GoogleAppsScriptとは
通称GASと言います。以下GASとします。
GASは、Googleスプレッドシート上で書けるプログラミング言語です。
JavaScriptという言語とほぼ同じ書き方ができるのが特徴です。
なぜGASがいいのか
JavaScriptライク
GASは、JavaScriptという言語とほぼ同じ書き方ができます。
JavaScriptは、今最もフロントエンドで使われている言語の1つで、バックエンドでも一部使われています。
つまり、GASを通してフロントエンド/バックエンド問わずWeb開発に入りやすいというのが魅力になります。
環境構築が楽
通常の言語だと、言語自体もそうですが、プログラムを書くためのIDEやエディタ、プログラムを実行するためのコンパイラやVM(仮想マシン)などが必要になってきます。
また、それらのパッケージはバージョンによって構築方法などが異なる場合が多く、ネットで調べてもさまざまな情報が出てきてうまくいかないこともザラです。
そのため、「よし、実際にプログラムを書いてみよう!」とせっかく意気込んでも、その前の環境構築でつまづいてしまい、プログラムを書き始める前に挫折したなんて話も聞きます。
しかしGASの場合、Googleスプレッドシートにログインできれば最低限の環境は整っており、Googleアカウントさえあればログインできます。
なので、「よし、実際にプログラムを書いてみよう!」と意気込んだ直後には書き始められるというのが大きいですね。
成果がわかりやすい
実際にプログラムを書いて実行してみても、それで得られた成果がわかりにくいとその次に進みにくかったりします。
例えばいきなりバックエンドの開発をしたところで、「で、これで何ができるの?」となりかねません。
しかしGASの場合、Googleスプレッドシートに結果を反映できます。
業務でPCを使う民の場合、ほとんどはExcelを含むスプレッドシートを避けては通れません。そういう意味では誰でも使うスプレッドシートであれこれできるのはわかりやすいだろうと僕は考えています。
実践
準備する
早速使っていきましょう。
Googleスプレッドシートを開く
-
Googleを開きます
GASのエディタを開く
エディタとは、実際にプログラムを書く部分のことです。
途中解説
functionとは
関数を定義するときに書きます。
関数とは、{
から}
までの処理を上から順に実行する塊です。
関数を定義すると、別の関数から呼び出すことができます。
myFunction()とは
関数の名前です。自由に定義できます。
()
の中は空でも書けるし引数を定義することもできます。
引数を定義した場合、関数の呼び出し元で値を渡し、関数の中でその値を実行することができます。
簡単なプログラムを書いて実行してみる
コンソールログにテキストと数値を出力する
console.logとは、JavaScriptの標準的な実装に組み込まれている機能の一つで、実行環境に用意された文字による入出力画面(コンソール)に指定された文字列を出力(表示)するもの。
意味わかんないですよね、とりあえず書いてみましょう。
- myFunction()の中にコンソールログの出力処理を書きます。
function myFunction() {
// added
console.log('ログだよ');
console.log(5);
}
書いてみると途中で入力補助が出てくるので、全部手打ちしなくていいのは楽ですね。
「ログだよ」というテキストを'
(シングルクォーテーション)で囲っていますが、これは'
の中に書いたものがテキストであること示しています。
逆に、5
は'
で囲っていませんが、これは数値を表しています。'5'
のように'
で囲うとテキスト扱いになります。テキストと数値の違いは後述します。
また、各文末に;
(セミコロン)がありますが、これはそのまま文末を表す記号です。ここでこの処理は終わりですよってことです。
- 「プロジェクトを保存」のアイコンをクリックします。
エディタに書いたプログラムは、書いただけでは保存されないのでこれで保存されます。保存すると、「実行」から右のアイコンがクリックできるようになります。
また、「myFunction ▼」というドロップダウンがありますが、これはどの関数を実行するか?という設定です。
- 「実行」をクリックします。
実行すると、エディタの下に「実行ログ」というビューが生えてきます。
実行ログには、「実行開始」と「実行完了」のお知らせがあり、それぞれプログラムの実行と実行の完了を表しています。
「実行開始」と「実行完了」の間には「情報」とありますが、これが前述のコンソールログに値するものです。
console.log()
の中に記載したログだよ
と5
がそれぞれ出力されているのがわかります。
引数に数値を与え、倍の数を返す関数を作ってみる
- myFunction()の下にgetDouble()を定義します。
function myFunction() {
}
// added
function getDouble() {
}
実行内容が空の新しい関数が定義できました。
予想はついていると思いますが、同じ名前の関数は2つ以上定義できません。
ちなみに、さっきからさらっと// added
と書いていますが、これはコメントと言います。コメントは、エディタ内にプログラムのように書けるが実行されないテキストになります。
自分が書いたプログラムを見返したときに、例えば「これってどんなことする関数だっけ?」とならないように、適度にコメントを書いておくとわかりやすくなります。
- getDouble()に引数を定義します。
function myFunction() {
}
// added
function getDouble(number) {
}
引数の名前も自分で定義できます。ここではnumber
とします。
これで呼び出し元から値を渡すことができます。
- numberの値を倍にし、変数に入れます。
function myFunction() {
}
function getDouble(number) {
// added
let double = number * 2;
}
変数とは、値を格納する箱のようなものです。
ここではdouble
という名前の変数を定義し、number
の数を倍にした値を格納しています。
double
はgetDouble()
内に定義した変数のため、myFunction()
などgetDouble()
外では使用できません。
変数を定義するには、主にlet
を使用します。
変数の定義にはlet
の他にvar
があり、またconst
という定数の定義もありますが、ここは割愛します。
numberは数値が来る想定なので計算ができます。それが前述したテキストと数値の違いになります。テキストはこのような計算ができません。
四則演算で言うと、足し算は+
、引き算は-
、掛け算は*
、割り算は/
を使います。他にも計算記法がありますが、これも割愛します。
- myFunction()からgetDouble()を実行してみる
function myFunction() {
// added
getDouble(2);
}
function getDouble(number) {
let double = number * 2;
}
無事に実行されました。しかしcosole.log()
を書いてないため実行ログで値が見れません。
これでは計算内容が合っているかわかりませんね。
ただ、getDouble()
内にcosole.log()
を書いたのではあまり意味がありません。getDouble()
は「引数に数値を与え、倍の数を返す」ための関数であり、返してほしいのはmyFunction()
だからです。
では、どのようにgetDouble()
の中で計算された値を返すのでしょうか。
- getDouble()の計算結果を返す
function myFunction() {
// added
let double2 = getDouble(2);
console.log(double2);
}
function getDouble(number) {
let double = number * 2;
// added
return double;
}
関数の中の値をどのように返すか、それはreturn
を使います。
getDouble()
の中で計算した結果を格納した結果double
をreturn
で返しています。
そうすると、getDouble()
を実行しているmyFunction()
で受け取れるようになります。
これを戻り値といいます。
ただ、それだけだと受け取れるようになっただけで実際には受け取っていません。
なのでlet double2 = getDouble(2);
のようにgetDouble()
の戻り値をdouble2
という変数に格納しています。
そしてdouble2
をコンソールログとして出力しています。
実行結果を見てみましょう。
引数として渡した2
の倍の数である4
が出力されました。
これで「引数に数値を与え、倍の数を返す」関数の実行と確認ができましたね。
これまではmyFunction()内で完結するプログラムを書いてきましたが、これではまだ「それで何ができるの?」という状態です。
ここからは実際に何ができるかの部分に触れていきます。
スプレッドシートと連携する
GASの特徴として、Googleスプレッドシートと連携しシートからデータを取得して加工しシートに反映することができます。
そこまでできれば実用的な使い方もできると思いますので、実際にやっていきましょう。
スプレッドシートの特定のセルから値を取得する
セルA1から値を取得する処理を書きます。
- あらかじめセルA1に値を入れておく
セルA1の値をGASで取得するため、あらかじめ値を入れておきます。
- セルA1から値を取得する
先ほどセルに入れた値をGASから取得してみます。
SpreadsheetAppのActiveSheetのRangeの中にあるgetValue()
という関数を使います。
function myFunction() {
// テキストでセル位置(A1)を引数として渡し、そのセルの値を取得
let value = getSellValue('A1');
console.log('A1', value);
}
// 指定したセル位置の値を返す関数
function getSellValue(sell) {
// 1. 現在のスプレッドシートを取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 2. 現在のシートを取得
var sheet = spreadsheet.getActiveSheet();
// 3. 引数で指定したセルの範囲を取得
var range = sheet.getRange(sell);
// 4. 値を取得する
var value = range.getValue();
return value;
}
ちなみにSpreadsheetAppからgetValue()までを1行で書くこともできますが、メンテ性と可読性が悪いのでちゃんと分けましょう。
無事にセルA1の値を取得できました。
次はセルへの書き込みをしてみましょう。
スプレッドシートの特定のセルに値を書き込む
セルA2に値を書き込む処理を書きます。
GASからセルに値を書き込みます。
SpreadsheetAppのActiveSheetのRangeの中にあるsetValue()
という関数を使います。
function myFunction() {
// テキストでセル位置(A1)を引数として渡し、そのセルの値を取得
let value = getSellValue('A1');
console.log('A1', value);
// テキストでセル位置(B1)と書き込む値を引数として渡し、指定のセルに指定の値を書き込む
setSellValue('B1', 'A1:' + value);
}
// 指定したセル位置の値を返す関数
function getSellValue(sell) {
//1. 現在のスプレッドシートを取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//2. 現在のシートを取得
var sheet = spreadsheet.getActiveSheet();
//3. 指定するセルの範囲(A1)を取得
var range = sheet.getRange(sell);
//4. 値を取得する
var value = range.getValue();
return value;
}
// 指定したセル位置に値を書き込む関数
function setSellValue(sell, value) {
//1. 現在のスプレッドシートを取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//2. 現在のシートを取得
var sheet = spreadsheet.getActiveSheet();
//3. 指定するセルの範囲(B1)を取得
var range = sheet.getRange(sell);
//4. 値を書き込む
range.setValue(value);
}
ここで'A1:' + value
という引数を渡していますが、テキストとテキストを+
で繋ぐと文字列が結合されます。数値の時と+
の挙動が違いますね。
それでは実行します。今回は書き込みがメインなので、コンソールログの確認はしません。
無事にセルB1に値が書き込まれました。
これでスプレッドシートとGASとの連携はバッチリですね。
【おまけ】処理を共通化する
先ほど書いたプログラム、動作的には問題ないですが構造的には少し微妙なところがあります。
getSellValue
とsetSellValue
の手順1〜3の処理がまったく同じなんですよね。手順が同じ複数の処理があるのならば、同じコードを2つ書いていることになります。無駄ですし、メンテ性も悪いです。
ここで「共通化」をすることで、この問題を解消します。
function myFunction() {
// テキストでセル位置(A1)を引数として渡し、そのセルの値を取得
let value = getSellValue('A1');
console.log('A1', value);
// テキストでセル位置(B1)と書き込む値を引数として渡し、指定のセルに指定の値を書き込む
setSellValue('B1', 'A1:' + value);
}
// 指定したセル位置を返す関数
function getSellRange(sell) {
//1. 現在のスプレッドシートを取得
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//2. 現在のシートを取得
var sheet = spreadsheet.getActiveSheet();
//3. 指定するセルの範囲(A1)を取得
return sheet.getRange(sell);
}
// 指定したセル位置の値を返す関数
function getSellValue(sell) {
// 指定したセル位置を返す
var range = getSellRange(sell);
// 値を取得し、返す
return range.getValue();
}
// 指定したセル位置に値を書き込む関数
function setSellValue(sell, value) {
// 指定したセル位置を返す
var range = getSellRange(sell);
// 値を書き込む
range.setValue(value);
}
関数getSellRange()
を新しく作り共通化した処理を入れました。
こうすることで、getSellValue
とsetSellValue
の中身はすっきりしたかと思います。
「指定したセル位置を返す関数」と「指定したセル位置の値を返す関数」、「指定したセル位置に値を書き込む関数」のそれぞれに役割を明確にし、責任を持たせるという意図があります。
これらのフローで何かバグがあった場合、箇所を特定しやすかったり、修正箇所が少なく済んだりします。最高ですね。
さいごに
ここまで読んでくださった方、なんなら試してくださった方、ありがとうございました。
プログラミング初学者向けの記事でしたが、いかがでしょうか。
これを読んだことでエンジニアを目指してみたり、エンジニアを目指さなくとも便利なツールとして使ってみたりと、何かのきっかけになればと思います。
それではさいなら。