見出し画像

#14 GAS は、Google の VBA マクロを分析する(その1 絶対参照)

記事のタイトルの通りですが、GAS(Google Apps Script)って、Microsoft で言うところの VBA のようなものなのです。
わたしが作った GAS のスクリプトも、Google スプレッドシートから動作させていますが、これは Microsoft Excel で動作する VBA(マクロ)のようなものなのです。
この記事では、Google スプレッドシートで記録したマクロが、GAS のプログラムであることを確認し、どのようなプログラムが記録されるのかを確認していきます。

マクロを記録する(絶対参照)

実際にどういうことなのかを確認してみましょう。
まず、Google スプレッドシートを開きます。

ただ、Google スプレッドシートを開いた状態

ここで、メニューバーから「拡張機能」→「マクロ」→「マクロを記録」と選択します。

メニューから「マクロを記録」

すると、画面の下部に「新しいマクロを記録していま…」と見慣れないウィンドウが表示されました。

マクロの記録中

ウィンドウの下部では「絶対参照を使用」と「相対参照を使用」という選択肢があり、きっと「絶対参照を使用」が選択されているはずです。 ※もし、「相対参照を使用」が選ばれていたら、ひとまず「絶対参照を使用」を選択してください。

とりあえず、記録してみる

そこで、次のように操作します。このときカーソルは A1 にあるところからはじめます。

  1. 「1」を入力
    → 入力すると、カーソルは A2 に移動

  2. 「→」を押してカーソルを移動
    → カーソルは B2

  3. 「2」を入力
    → 入力すると、カーソルは B3 に移動

  4. 「→」を押してカーソルを移動
    → カーソルは C3

  5. 「3」を入力
    → 入力すると、カーソルは C4 に移動

ここまで操作したところで、下部に表示されているウィンドウの「保存」ボタンを押します。
すると、下図のような「新しいマクロの保存」ダイアログが表示されるので、適当な名前をつけて保存します。今回は、「絶対参照マクロ」と設定してみます。「ショートカット」には保存されたマクロを呼び出すためのキーを割り当てられるので、ひとまず「1」を設定しておきます。

「新しいマクロの保存」ダイアログ

これでマクロが保存されました。
保存されたマクロは設定したショートカットだけでなく、メニューから「拡張機能」→「マクロ」に表示されるので、呼び出せます。

保存されたマクロはメニューから実行できる

保存されたマクロの内容は、「拡張機能」→「マクロ」→「マクロを管理」で、確認したいマクロのメニューから「スクリプトを編集」で確認できます。

「マクロの管理」から「スクリプトを編集」

記録されたマクロを確認

「スクリプトを編集」を選択すると、「スクリプトエディタ」が起動します。先の操作を行ったマクロは、次のように記録されているはずです。

スクリプトエディタ(絶対参照のマクロ)

先に行った 5つの操作が、このような GAS のスクリプトとして記録されています。この 12行がそれぞれ、どんな意味を持っているのかを、順に説明していきます。

1 ~ 2行目

/** @OnlyCurrentDoc */

1 ~ 2行目は、/* と */ で囲まれた中はコメントとして扱われるので、動作に意味がありません。

3行目

function myFunction() {

3行目は、記録されたマクロを myFunction という名前の関数(function)として宣言している部分です。
関数には引数(パラメータ)を与えることができますが、マクロにはパラメータを与えられないので myFunction() と引数がないと宣言されています。
行末の { はブロックの始まりを意味していて、スクリプトの最後 12行目の } と対応しています。

4行目

var spreadsheet = SpreadsheetApp.getActive();

ここからちょっと難しくなってきます…
行頭の var は変数を宣言するときに使用します。var に続けて書かれている spreadsheet が変数名になります。

  • 変数とは、数学で出てきた x や y のように値を保持するための箱と思っておいてください。 ※ただ、GAS の場合には変数に保存されるのは、数値だけではありませんが、ここではその説明は省きます…

  • 変数の宣言には、var の他にも、let や const を用いて宣言する方法もありますが、その説明もここでは省きます。

= に続けて、SpreadsheetApp.getActive(); と書かれているのは、SpreadsheetApp というクラスの getActive() というメソッドを呼び出しています。行末の ; は、日本語の「。」に相当する 1つの命令の終わりを意味する文字です。
SpreadsheetApp や getActive() については、Google が用意するリファレンスには、次のように説明されています。

Class SpreadsheetApp
Access and create Google Sheets files. This class is the parent class for the Spreadsheet service.

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app

getActive()
Returns the currently active spreadsheet, or null if there is none.

Functions that are run in the context of a spreadsheet can get a reference to the corresponding Spreadsheet object by calling this function.

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#getactive

それぞれを日本語に機械翻訳してみると、

Google Sheetsのファイルにアクセスし、作成します。このクラスは、Spreadsheet サービスの親クラスです。

DeepL 翻訳ツールにて翻訳

getActive()
現在アクティブなスプレッドシートを返すか、存在しない場合は null を返す。
スプレッドシートのコンテキストで実行される関数は、 この関数をコールすることで対応するスプレッドシートオブジェクトへの参照を取得することができます。

DeepL 翻訳ツールにて翻訳

要約すると、「SpreadsheetApp.getActive() によって、現在アクティブなスプレッドシートにアクセスするためのスプレッドシートオブジェクトが取得できます」ということです。
この得られたスプレッドシートオブジェクトを、変数 spreadsheet に代入しています。数学では = の両辺は等しくなりますが、こういったプログラムでの = は ← で表現するような「右辺を左辺に代入する」という意味になります。

もう一つ気にして欲しいのは、この 4行目の var の前に空白が入っていることです。
この空白は、プログラムの動作には影響のないものですが、3行目の { と 12行目の } のブロックの中にあることを表すためにネスト(段下げ)されているものです。
後からプログラムを見るときに、どの部分がブロックになっているのかを見やすくするための配慮です。

5行目

  spreadsheet.getRange('A1').activate();

5行目では、前提条件であった『このときカーソルは A1 にあるところからはじめます。』がプログラムになっている部分です。
3行目で得られた spreadsheet(スプレッドシートオブジェクト)を用いて、getRange() でセルを指定して、そのセルをアクティブセルにしています。すなわち、カーソルを A1 に指定しています。

Class Spreadsheet
Access and modify Google Sheets files. Common operations are adding new sheets and adding collaborators.

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet

getRange(a1Notation)
Returns the range as specified in A1 notation or R1C1 notation.

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getrangea1notation

Class Range
Access and modify spreadsheet ranges. A range can be a single cell in a sheet or a group of adjacent cells in a sheet.

https://developers.google.com/apps-script/reference/spreadsheet/range

activate()
Sets the specified range as the active range, with the top left cell in the range as the current cell.

https://developers.google.com/apps-script/reference/spreadsheet/range#detailed-documentation

スプレッドシートオブジェクトは Spreadsheet というクラス(Class)で、そのクラスの中にある getRange() メソッドを使って範囲を指定する。指定した範囲は、Range クラスとして取得して、activate() メソッドでアクティブセルを指定する。
という感じになります。何だか複雑な感じですが、もう少しお付き合いください。

6行目

spreadsheet.getCurrentCell().setValue('1');

6行目では、『「1」を入力』が実行されている部分です。5行目と同じように、getCurrentCell() でカーソル位置のセルを取得して、setValue() で値を設定しています。
setValue() の かっこの中が '1' となっているのは、setValue() というメソッド(関数)にパラメータとして '1' を渡しています。数字の 1 が ’ で囲まれているのは文字として入力していることを意味しています。

getCurrentCell()
Returns the current cell in the active sheet or null if there is no current cell. The current cell is the cell that has focus in the Google Sheets UI, and is highlighted by a dark border. There is never more than one current cell. When a user selects one or more cell ranges, one of the cells in the selection is the current cell.

https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getCurrentCell()

setValue(value)
Sets the value of the range. The value can be numeric, string, boolean or date. If it begins with '=' it is interpreted as a formula.

https://developers.google.com/apps-script/reference/spreadsheet/range#setValue(Object)

7 ~ 8行目

  spreadsheet.getRange('B2').activate();
  spreadsheet.getCurrentCell().setValue('2');

7行目は、

  • 意図して行った操作ではなく、入力した操作によって行われた「→ 入力すると、カーソルは A2 に移動」

  • 「→」を押してカーソルを移動

による結果として、「→ カーソルは B2」がプログラムになったものです。
プログラムの内容としては、5行目と同じです。
8行目は、6行目と同じように次の操作がプログラムになったものです。

  • 「2」を入力

9 ~ 10行目

  spreadsheet.getRange('C3').activate();
  spreadsheet.getCurrentCell().setValue('3');

9 ~ 10行目は、7 ~ 8行目と同様に、

  • アクティブなセルを C3 に指定

  • アクティブなセルに ’3’ を入力

を行っています。

11行目

  spreadsheet.getRange('C4').activate();

11行目は、入力した結果にともなった、「→ 入力すると、カーソルは C4 に移動」という結果がプログラムになったものです。

12行目

};

12行目は、3行目の行末にある { に対応した、ブロックの終わりを示す } になります。
行末の ; はなくても動作には関係ないと思いますが、Google が記録したマクロには記述されています。恐らく、3行目の関数の宣言を一つの命令として考えたときに、その終わりとして記述しているのでしょう。
細かに解説すると、12行のプログラムはこんな感じです。

マクロを実行してみる

記録されたマクロを実行してみましょう。
このまま実行しても変化がわからないので、

  1. いくつかのセルに入力されている内容をクリア

  2. セル C6 をクリック
     ※マクロを記録したときとは違って、A1 にカーソルがない

  3. 「Ctrl」+「Alt」+「Shift」+「1」を押す

と操作すると、マクロが実行されます。はじめてマクロを実行するときには、下図のように「承認が必要」ダイアログが表示され、マクロを実行してもよいかの確認が行われます。

「承認が必要」ダイアログ

この辺りの確認について、以下の別の記事で説明しているので、それにならって実行を許可してください。「承認が必要」ダイアログが表示された場合には、許可するだけで実際にマクロは実行されていません。もう一度、「Ctrl」+「Alt」+「Shift」+「1」を押して、マクロを実行します。

マクロを実行すると、マクロを実行したときのカーソル位置(アクティブセルの位置)に関係なく、A1、B2、C3 に値が入力され、C4 にカーソルが移動したはずです。

マクロを実行した結果(絶対参照)

これは、上記のプログラムの各行でも解説したように、入力するセルの位置を A1、B2、C3、C4 と絶対位置で指定されているので、このように動作します。
この「絶対参照を使用」と「相対参照を使用」については、ヘルプ記事では次のように説明されています。

絶対参照を使用: 記録時に使用したセルでタスクを実行するマクロが作成されます。たとえば、セル A1 を太字にする操作を記録すると、クリックしたセルに関係なくセル A1 を太字にするマクロが作成されます。
相対参照を使用: 選択したセルとその周辺のセルでタスクを実行するマクロが作成されます。たとえば、セル A1 と B1 を太字にする操作を記録すると、作成されたマクロを使用してセル C1 と D1 を太字にすることができます。

Google スプレッドシートでタスクを自動化する - パソコン - ドキュメント エディタ ヘルプ

要約すると、

  • 「絶対参照を使用」で作成されたマクロは、マクロを実行するときのカーソル位置に関係なく、必ず同じ結果となる

  • 「相対参照を使用」で作成されたマクロは、マクロを実行するときのカーソル位置に応じて、実行結果は変化する。

という感じです。

次回に続く…

たった 12行のプログラムでしたが、細かく説明すると長くなりました。
次回は、「相対参照を使用」のマクロについて説明します。


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