Original image by martarey84 from Pixabay and modified by author

最小限の知識で入門する Google Apps Script〜エディタ編〜

プログラムを書くときには、エディタと呼ばれるアプリ(ソフトウェア)が使われます。この記事では、Google Apps Script でプログラムを書くときに使われるエディタについて説明します。

目次

予備知識

クライアントとサーバー

インターネットが普及するにつれ、コンピュータを単独で使う機会は減っていき、ネットワークでつながった別のコンピュータと通信を行いながら使うということが普通に行われるようになりました。

例えば、インターネット上で提供されているサービスは、サービスを利用する人が使うコンピュータが、サービスを提供する側のコンピュータにインターネット回線で接続して利用します。

サービスを利用する人が使うコンピュータをクライアントと呼び、サービスを提供する側が使っているコンピュータをサーバーと呼びます。

ウェブサイト(いわゆるホームページ)はインターネット上で提供されるサービスの典型的なものです。ブログ記事やニュース記事を配信しているサイトだけではなく、ネットショップ、ネットバンキング、X(旧twitter)や Facebook などの SNS 、検索エンジンなどもウェブサイトです。

かつてパーソナルコンピュータが普及しはじめたころ、自分が使うコンピュータに様々なアプリをインストールして使うということが普通に行われるようになりました。しかしインターネットが普及する前では、それらのアプリは自分のコンピュータの中だけで動くもので、他のコンピュータと接続して使われるようなことはほとんど行われませんでした。

その後インターネットが登場し普及するにつれ、サービス提供事業者は様々なアプリを事業者自身で管理するサーバーに導入するようになり、ユーザーはインターネットで事業者の管理するサーバーへ接続してアプリを使うということが行われるようになりました。

つまり、アプリはサーバーがサービスとして提供し、ユーザーはクライアントとしてのコンピュータでインターネットでアクセスすることによりそれらのアプリを利用するわけです。アプリは基本的に、ユーザーの使っているコンピュータではなくサービス提供事業者の管理するサーバー上で動いています。Google が提供している Google ドキュメント、Googleスプレッドシートなどもそのようなアプリの1つです。

また、現在では、プログラミングをするときに使うアプリ一式をサービスとしてインターネット上で提供するものもあらわれています。このようなサービスを利用すると、自分のパーソナルコンピュータにプログラミングをするための実行環境を構築しなくても、ブラウザ(Chrome や Edge など)さえあれば、それらのサービスにアクセスしてプログラミングをすることができます。Google Apps Script もそのようなものの1つと言えるでしょう。

Apps Script はサーバー上で実行されるプログラム

インターネットでユーザーがクライアントとしてのコンピュータでサーバーに接続しサービスを利用するとき、クライアント側のコンピュータとサーバー側のコンピュータの両方で様々なプログラムが実行されています。

Google Apps Script は Google の提供する様々なアプリ(ドキュメント、スプレッドシート、Gmailなど)を連携、自動化、機能拡張するために使われるプログラミング言語でした。

これらのアプリは Google が管理しているサーバーで提供されています。ですから、これらを操作するプログラムである Google App Script も Google の管理しているサーバー上で動くようになっているわけです。

エディタ

プログラムを書くときに使うアプリをエディタと呼びます。

Google Apps Script では、エディタもサービスの一部として使えるようになっているので、自分でエディタを用意する必要はありません。

自分のパーソナルコンピュータで実行するプログラムを書く場合は、自分のパーソナルコンピュータに何かしらのエディタをインストールしておく必要があります。(Windows を使っている人の場合、インストールしなくても初めから入っている「メモ帳」というエディタでプログラミングをすることができます。しかし、このアプリは機能がとても少なくかなり骨の折れるプログラミングをすることになります。)

Google Apps Script エディタの使い方

コンテナバインドスクリプトとスタンドアロンスクリプト

Google Apps Script で書くことのできるプログラムは大きく「コンテナバインドスクリプト」と「スタンドアロンスクリプト」の2種類に分類されています。

コンテナバインドスクリプトは Google スプレッドシート、ドキュメント、スライド、フォームで作られた特定のファイルに紐付けられて使われるものです。紐付いているファイルを簡単に呼び出して操作するため命令コードが使えるようになっています。また、紐付いているファイルに対して、カスタムのメニュー、ダイアログ、サイドバーを表示することを可能にするプログラムを書くことができます。

スタンドアロンスクリプトは、特定のファイルには紐付けないで実行するプログラムです。ファイルの ID や URL を指定して命令コードを書くことにより、コンテナバインドスクリプトと同様に、 Google ドキュメント、スプレッドシート、スライド、フォームで作られたファイルを呼び出して操作することはもちろん可能です。

さて、どちらのスクリプトを書くとしても、まず、エディタを開く必要があります。

スプレッドシートやドキュメントなどからエディタを開く

コンテナバインドスクリプトを書きたい場合は、これから説明するように、紐付けようと思っているファイルからエディタを開きます。

まず、紐付けようと思っているファイル(つまり Google ドキュメント、スプレッドシートなど)を開きます。新規に作成しても良いですし、既にあるものでも構いません。

次に、メニュー項目の 「拡張機能」をクリックします。すると小さなメニューがポップアップするのでその中から 「Apps Script」をクリックします。すると、Apps Script でプログラミングをするためのエディタが開きます。

次の図は、スプレッドシートからエディタを開こうとしているところをあらわしています。

スプレッドシートからエディタを開く

単独でエディタを開く

スタンドアロン スクリプトを書きたい場合は、これから説明するように、Apps Script の管理ページまたは Google Drive からエディタを開きます。

Apps Script の管理ページから開く

管理ページをひらくために、script.google.com へアクセスします。

そして、左上の「+ 新しいプロジェクト」 をクリックします。

すると、Apps Script でプログラミングをするためのエディタが開きます。

Google ドライブから開く

Google ドライブ へアクセスします。

そして、左上の「+ 新規 」をクリックします。

すると小さなメニューがポップアップするので

その他 > Google Apps Script

をクリックします。

すると、Apps Script でプログラミングをするためのエディタが開きます。

コンテナバインド、スタンドアロンのどちらの場合も次のように「無題のプロジェクト」という名前でエディタが開きます。

「無題のプロジェクト」という名前でエディタが開く

この名前は自分のわかりやすいものに変更しておきましょう。

エディタで編集できるファイルの種類

Google Apps Script のエディタでは2種類のファイルを編集することができます。

1つは「.gs」という拡張子がついたものでもう一つは「.html」という拡張子がついたものです。

.gs ファイル

サーバー側で実行される Google Apps Script の命令コードを書き込んでおくファイルです。Google ドキュメント、スプレッドシート、Gmail などの連携、自動化を行ったりスプレッドシートの自作関数を作る場合にはこのファイルを作成します。

.html ファイル

実は Google Apps Script を使ってウェブアプリを作ることができます。そして、ウェブアプリにはユーザーがアプリを操作するための画面が必要です。その画面を作るために使うファイルです。ウェブアプリを作る場合は .html ファイルも作成することになります。

Google Apps Script のエディタには、次のように初めから「コード.gs」という名前の「.gsファイル」が読み込まれ表示されています。基本的にはこのファイルに Google Apps Script のコードを記述してプログラムを作成していくことになります。

初めから「コード.gs」という名前の「.gsファイル」が読み込まれ表示されている

ファイルの名前は自由につけることができます。「コード.gs」も、必要に応じて自分の好きな名前に変えて構いません。

また、ファイルを複数作ることもできます。

ファイルを追加するには、「ファイル」と書かれているところの右側の「+」をクリックします。すると小さなメニューがポップアップし、「スクリプト」または「HTML」のどちらかを選ぶように促されます。そして、適当なファイル名をつけます。(ただし拡張子は自動的に補われます。「スクリプト」を選択した場合は 「.gs」、「HTML」を選択した場合は「.html」が自動的につけられます。)

プログラムの記述

Google Apps Script のエディタをはじめて開くと、次のように、コード.gs ファイルには初めから myFunction という名前の関数が書き込まれています。

コード.gs ファイルには初めから myFunction という名前の関数が書き込まれている

この関数は、 { } の中に何も書かれてないので、呼び出して実行しても、なにも処理を行わない関数です。

myFunction という名前の関数を今後使う予定がなければ邪魔になるだけなので消してしまって構いません。

次の図は、コード.gs ファイルに書かれていた myfunction を消してから、前回の記事で紹介した自作関数を書き込んでみたところです。

myfunction を消してから、前回の記事で紹介した自作関数を書き込んでみたところ

あるスプレッドシートファイルのコンテナバインドスクリプトとしてエディタを開いている場合、つまり、あるスプレッドシートに紐付けられているプログラムを書こうとしてエディタ開いている場合は、前回の記事で述べたように、この時点でこの関数はスプレッドシートのセルで呼び出して使うことができるようになっています。

また、次の図は、コード.gs ファイルに書かれていた myfunction を消してから、前々回の記事で紹介した自動化サンプルプログラムを書き込んでみたところです。

myfunction を消してから、前々回の記事で紹介した自動化サンプルプログラムを書き込んでみたところ

この関数は特に何らかのファイルと紐付けて使われることが想定されていません。ですからコンテナバインドスクリプトの中の1つの関数として使うこともできますし、スタンドアロンスクリプトの中の1つの関数としても使うことができます。

プログラムの保存

エディタを使って作成したファイルに書き込んだ内容は自動的に保存されません。必ず、メニューにある「保存ボタン」を押す、キーボードで 「Ctrl + s」 を押すなどして保存してください。

書いたコードに文法エラーがある場合、保存をするとエラーメッセージが英語で表示されます。

エラーが起きている行番号、エラーが起きた理由が表示されます。

プログラムの実行

Google Apps Script のエディタでは、これから説明するように、作った関数を選んで実行することができるようになっています。

エディタのメニューには関数を選択するためのプルダウンメニューがあります。

まずそこから、実行したい関数を選択します。

そしてエディタのメニューにある実行ボタンを押します。

すると選択した関数が実行されます。

はじめて実行するときには、本当に実行してよいのかどうか、承認を求められます。

Google Apps Script は Google アカウントを持っているユーザーが管理しているドキュメント、スプレッドシートをはじめとする様々なリソースへアクセスして動くプログラムですが、そのようなプログラムはあくまでもユーザーが作ったもので、Google が作ったわけではありません。ですから、自己責任でプログラムを実行するように求められるわけです。

次のスライドで示される手続きを行うことによって、関数の実行ができるようになります。

  • 承認を求められる
    1. 承認を求められるので、権限を確認をクリック
  • アカウントを選択
    2. 誰のアカウントで実行するのか選択を求められる
  • 詳細をクリック
    3. Google で確認してないと言われるが、詳細をクリックし先に進む
  • 安全ではないページに移動
    4. 安全ではないページに移動をクリック
  • アクセスできるリソースをすべて選択
    5. 自分のプログラムがユーザーのリソースにアクセスしようとしていると言われるが、とりあえずアクセスできるリソースをすべて選択
  • 続行をクリック
    6. 続行をクリック
  • エディター画面に戻り、関数が実行できる
    7. エディター画面に戻るが、今度は関数を実行できるようになっている

エディタのメニューにある実行ボタンは基本的には「開発時(つまりプログラミング中)に関数をテストするためのもの」といえます。プログラミングが終わり、関数を実用として実行する場合には、例えば、スプレッドシートやドキュメントのメニューなどに実行ボタンを用意しておきボタンを押すと実行される、スプレッドシートやドキュメントが編集されたときに自動的に実行されるなどとしておいたり、決まった時間に自動的に実行されるようにしておくといった使い方をすることになるでしょう。

実行ログ

関数を選んで実行すると実行ログが表示されます。

文法的に正しいプログラムを書いても、実行してみたときにエラーが出ることは普通に起こります。そのようなとき、実行ログにエラーに関する情報が表示されます。

エラーが出ずに処理が完了したとしても、目的としたものとは違う結果がでていることが疑われるということもよくあります。また、何行にも渡る長い処が書かれている場合、全部を実行するのではなく、とりあえず途中まで目的どおり動くか試してみたいときもあります。

これらは実行時のエラーではないので、実行ログには何も出力されません。そこで、プログラムのところどころに、実行結果に関するなにかしらの内容を出力する命令を記述しておき、変数に目的通りの値がちゃんと代入されるかどうか確認するということがよく行われます。

Google Apps Script では、そのような目的を果たすための2つの関数 logger.log と Logger.log を使うことができます。

console.log は Google Apps Script で独自に用意されている関数というわけではなく、Google Apps Script の文法が従っている JavaScript で用意されている関数です。

ここでは Javascript でも共通に使われる console.log について簡単にみてみることにしましょう。

次のコードは Google Apps Script 公式ページ ロギング からの引用です。

今ここではこのコードを理解する必要はありません。

とりあえず、// から始まるコメント行だけを上から順に読んで、どんな処理をしているのか辿ってみてください。

/**
 * 行番号、メルアドを与えるとこのスクリプトが紐付いているスプレッドシートからその
 * 行番号にある行のデータを取得し、題名をつけてその内容をそのメルアドへ送信する関数
 * @param {number} rowNumber スプレッドシートの行番号をあらわす変数
 * @param {string} email スプレッドシートでその行にある行データの
 * 内容を送るメールの名前をあらわす変数
 */
function emailDataRow(rowNumber, email) {
  // 引数として受け取った rowNumber と email の値を使い、
  //'Emailing data row '、rowNumber、 ' to '、 emailという順に
  // つないでできる文字列を実行ログに出力
  console.log('Emailing data row ' + rowNumber + ' to ' + email);

  try {
    // スプレッドシートアプリに今紐付いているシートを取得してもらい変数 sheet に代入
    const sheet = SpreadsheetApp.getActiveSheet();
    // シートにあるデータを取得し変数 data へ代入
    const data = sheet.getDataRange().getValues();
    // sheeet から、引数で渡された rowNumber にある行のデータを取得し、
    // 各列の内容を順に、間にスペースを入れ文字列として連結
    const rowData = data[rowNumber - 1].join(' ');
    // 'Row'、rowNumber、'data:'、rowData を順につないでできる
    // 文字列を実行ログに出力
    console.log('Row ' + rowNumber + ' data: ' + rowData);
    // メールアプリに 送信先をを 変数 email に代入されている文字列、
    // 題名を 'Data in row'、変数 rowNumber に代入されている文字列、
    // 本文を 変数 rowNumber に代入されている文字列
    // として送信してもらう
    MailApp.sendEmail(email, 'Data in row ' + rowNumber, rowData);
  } catch (err) {
    // 例外処理
    // 'Failed with error %s' という文字列の %s の部分に try ブロックから
    // 投げられてきた errオブジェクトから message を取得したものを代入
    // してできる文字列を実行ログに出力
    console.log('Failed with error %s', err.message);
  }
}

このプログラムには、console.logを使って実行ログへの出力が3ヶ所で行われています。

console.log は引数に渡された文字列を「コンソール」と呼ばれるところへ出力する関数です。Google Apps Script では、関数を実行すると「コンソール」がエディタの画面に現れ、実行ログと表示されます。

12行目では、

console.log('Emailing data row ' + rowNumber + ' to ' + email);

として、関数 emailDataRow が引数として受け取った rowNumber と email の値を使い、’Emailing data row ‘、rowNumber、 ‘ to ‘、 email という順につないでできる文字列を実行ログに出力するようにしています。(Javascript では、 文字列と文字列の間に「+」をはさむとそれらの文字列が連結されるのでした。)

例えば、関数 emailDataRow の引数 email に ‘abc@example.com’ という(メルアドのつもりの)文字列、rowNumber に 6 という(行番号のつもりの)整数を渡して呼び出してみると、間違いがなければ実行ログには

'Emailing data row  6  to abc@example.com'

という文字列が出力されるはずです。

実行ログに出力されるこの文字列中の所定の位置に、 6 と ‘abc@example.com’ が出力されていることが確認できれば、この関数はとりあえず 12 行目までなら引数を正しく受け取って動いているということがわかるわけです。

次は 24行目です。

console.log('Row ' + rowNumber + ' data: ' + rowData);

このプログラムではこの行以前で、指定された行のデータをスプレッドシートから取得し、その行の各列(セル)の内容を順に、間にスペースを入れて文字列として連結し、 rowData という変数へ代入しています。

ここでは詳しいことは説明しませんが、21 行目に登場する join は、引数に渡された文字列を間に挟んで配列の要素を連結するメソッドです。

そしてこの 24 行目では、’Row’、rowNumber、’data:’、rowData を順につないでできる文字列を実行ログに出力するようにしています。

例えば今、次のように、紐付いているスプレッドシートの 6 行目ではセルの内容が左から「新保 藍」、「滋賀県」、「MaU9JQ8SgO@example.org」となっているとします。

紐付いているスプレッドシートの 6 行目ではセルの内容が左から「新保 藍」、「滋賀県」、「MaU9JQ8SgO@example.org」となっているとする

このとき、スプレッドシートの 6 行目をスペースを挟んで連結すると、

新保 藍 滋賀県 MaU9JQ8SgO@example.org

という文字列が出来上がります。

そこで、関数 emailDataRow の2番目の引数 である rowNumber に 6 という(行番号のつもりの)整数を渡して呼び出してみるとどうなるのか考えてみましょう。

24行目以前までに、スプレッドシートの 6 行目のデータが取得され、そのデータの列(セル)が左から順に連結され、連結して出来た文字列が rowData に代入されるのですから、24行目の処理が行われると、間違いがなければ実行ログには

'Row 6 data: 新保 藍 滋賀県 MaU9JQ8SgO@example.org'

という文字列が出力されるはずです。

スプレッドシートの 6 行目をみて、この実行ログと見比べることにより、24 行目まで正しく動いているかどうかを確認できるわけです。

最後に 35 行目です。

console.log('Failed with error %s', err.message);

これは、前々回の記事で説明したように、try ブロックでエラーが発生し catch ブロックへ 例外が投げられてきたときに実行されます。

実行ログに「’Failed with error %s’ という文字列の %s の部分に err に含まれている メッセージを入れたもの」が表示されます。そして、try ブロックでエラーが発生したこと、発生したエラーに関する情報が確認できるわけです。

では、実際に関数 emailDataRow を実行したときの実行ログがどんなものになるのか見てみます。

実はエディタで関数 emailDataRow を選んで実行ボタンを押して実行しても意味のある情報が取得できません。それは、この関数には引数があるからです。しかし、実行ボタンを押しても引数を与えることはできません。そこで、関数 emailDataRow をエディタで実行たいときには、まず、引数のない、なにか別の関数を定義します。その時、その関数が行う処理として引数の用意と関数 emailDataRow の呼び出しをするようにします。そしてその関数をエディタで選択し実行します。例えば、エディタで関数 emailDataRow の下などに次のようなコードの関数 test を書き、エディタで関数 test を選択し実行すればよいわけです。

function test(){
  const email = 'abc@example.com';
  const rowNumber = 6;
  emailDataRow(email, rowNuimber);
}

次の図は、関数 emailDataRow の引数 email に ‘abc@example.com’ という文字列、rowNumber に 6 という整数を渡して実行したときの実行ログです。

関数 emailDataRow の引数 email に 'abc@example.com' という文字列、rowNumber に 6 という整数を渡して実行したときの実行ログ

このログを見ると、

まず、

Emailing data row 6 to abc@example.com

と出力されています。これは目的通りの動作です。

次に、

Failed with error Cannnot read properties of undefined (reading 'join')

と表示されています。このことから「try ブロックでエラーが発生し catch ブロックへ 例外が投げられてきた」ということがわかります。また、投げられてきた例外の中のメッセージは「Cannnot read properties of undefined (reading ‘join’)」です。これは、「定義されていないもののプロパティは読むことはできない(join というプロパティを読もうとしたけど)」ということを言っています。プログラムをよく見ると、21 行目に join というプロパティが出てきています。ですから、ここで例外が発生し、catch ブロックへ処理が移ったことがわかります。その結果、24 行目の console.log は実行されなかったわけです。

21行目で例外が発生した理由は、16行目の処理でスプレッドシートを取得できずに undefined が得られたからです。実は、このプログラムをコンテナバインドスクリプトでは無く、スタンドアロンスクリプトとして実行するとスプレッドシートを取得することができません。Google Apps Script の公式ページなどで 16 行目にあらわれている SpreadsheetApp.getActiveSheet() について調べてみてください。

デバッグ

文法上の間違いも含め、あらゆるエラーの原因になるものをバグといいます。

そして、プログラムを見直し、バグを減らしていく作業はデバッグと呼ばれます。

プログラムの中で調べたいところに logger.log や Logger.log のような出力を行う関数をおいておき、変数の値を確認できるように実行ログに出力させ、結果を見てみるということももちろんデバッグ手法の1つです。

ところで、プログラミングを行うときに使う多種多様なエディタには、たいてい様々なプログラミングに対応してデバッグを行う機能がついています。そして Google Apps Script のエディタにもデバッグを行う機能があります。

デバッグはブレークポイントでの結果を確認したり、1行1行ステップを進めながら確認をしていきます。

ブレークポイントでの確認をするときには次のような流れで実行されます。

  1. プログラム中で調べたい行をいくつかあらかじめ選んでおきマークします。
    マークした行はブレークポイントと呼ばれます。
  2. デバッグボタンをクリックします。
  3. プログラムが上から実行されていき、ブレークポイントに到達すると一旦実行を中止します。そしてその時点でどの変数にどんな値が代入されているのか表示されます。ここで、目的通りの動作をしているのかどうかを確認します。
  4. そのブレークポイントから再び実行を継続するボタンをクリックすることにより、次のブレークポイントへ向かってプログラムが実行されます。
  5. 最後の行へ到達した場合はデバッグは終了しますが、そうではない場合は 3 に戻ります。

ある関数の中で別の関数を呼ぶということが行われているプログラムでは、ブレークポイントを利用するだけではなく、1行1行進めながら確認をする方法がよくとられます。その場合、ステップイン、ステップアウト、ステップオーバーと呼ばれることを行って、関数の中に入ったり、関数から出たり、関数の残りの処理を飛ばしたりしてデバッグをすることになります。 これらについての詳しいことは、検索エンジンなどを使って調べてみてください。

上部へスクロール