Google スプレッドシートには、AVERAGE
、SUM
、VLOOKUP
など、数百もの組み込み関数が用意されています。これらの機能が十分ではない場合は、Google Apps Script を使用してカスタム関数を作成できます(メートルをマイルに変換する、インターネットからライブ コンテンツを取得するなど)。これは、組み込み関数と同様に Google スプレッドシートで使用できます。
はじめに
カスタム関数は、標準の JavaScript を使用して作成されます。JavaScript を初めて利用する場合は、Codecademy の初心者向けのコースとしておすすめです。(注: このコースは Google が開発したものではないため、Google とは関係ありません。
以下に、入力値に 2 を乗算する DOUBLE
という名前のシンプルなカスタム関数を示します。
/**
* Multiplies an input value by 2.
* @param {number} input The number to double.
* @return The input multiplied by 2.
* @customfunction
*/
function DOUBLE(input) {
return input * 2;
}
JavaScript の記述方法がわからず、学ぶ時間がない場合は、アドオンストアを確認して、必要なカスタム関数を他のユーザーがすでに作成していないか確認してください。
カスタム関数の作成
カスタム関数を作成するには:
- Google スプレッドシートでスプレッドシートを作成するか開きます。
- メニュー項目 [拡張機能] > [Apps Script] を選択します。
- スクリプト エディタ内のコードをすべて削除します。上記の
DOUBLE
関数に関しては、コードをコピーしてスクリプト エディタに貼り付けます。 - 上部の保存アイコン( )をクリックします。
これで、カスタム関数を使用できるようになりました。
Google Workspace Marketplaceからカスタム関数を取得する
Google Workspace Marketplace には、Google スプレッドシートのアドオンとしていくつかのカスタム関数が用意されています。これらのアドオンを使用または確認するには:
- Google スプレッドシートでスプレッドシートを作成するか開きます。
- 上部にある [アドオン] > [アドオンを取得] をクリックします。
- Google Workspace Marketplace が開いたら、右上の検索ボックスをクリックします。
- 「カスタム関数」と入力して Enter キーを押します。
- 使用したいカスタム関数アドオンが見つかった場合は、[インストール] をクリックしてインストールします。
- アドオンには認証が必要であることを示すダイアログ ボックスが表示されることがあります。その場合は、通知をよく読んでから [許可] をクリックします。
- スプレッドシートでアドオンを使用できるようになります。別のスプレッドシートでアドオンを使用するには、別のスプレッドシートを開き、上部にある [アドオン] > [アドオンを管理] をクリックします。使用するアドオンを見つけて、オプション > [このドキュメントで使用] をクリックします。
カスタム関数の使用
カスタム関数を作成するか、Google Workspace Marketplaceからインストールした後は、組み込み関数と同様に簡単に使用できます。
- 関数を使用するセルをクリックします。
- 等号(
=
)を入力し、続けて関数名と任意の入力値(=DOUBLE(A1)
など)を入力し、Enter キーを押します。 - セルにすぐに
Loading...
が表示され、結果が返されます。
カスタム関数のガイドライン
独自のカスタム関数を作成する前に、把握しておくべきガイドラインがいくつかあります。
命名
JavaScript 関数の標準の命名規則に加えて、次の点に注意してください。
- カスタム関数の名前は、
SUM()
などの組み込み関数の名前とは異なる必要があります。 - カスタム関数の名前の末尾をアンダースコア(
_
)にすることはできません。アンダースコアは Apps Script の非公開関数を示します。 - カスタム関数の名前は、
var myFunction = new Function()
ではなくfunction myFunction()
構文で宣言する必要があります。 - 従来、スプレッドシートの関数名は大文字で表記されていますが、大文字と小文字は区別されません。
引数
組み込み関数と同様に、カスタム関数は入力値として引数を取ることができます。
- 1 つのセルへの参照を引数として関数を呼び出す場合(
=DOUBLE(A1)
など)、引数はセルの値になります。 セル範囲の参照を引数として関数を呼び出す場合(
=DOUBLE(A1:B10)
など)、引数はセル値の 2 次元配列になります。たとえば、以下のスクリーンショットでは、=DOUBLE(A1:B2)
の引数は Apps Script によってdouble([[1,3],[2,4]])
と解釈されます。上記のDOUBLE
のサンプルコードは、配列を入力として受け入れるように修正する必要があります。カスタム関数の引数は確定的である必要があります。つまり、計算のたびに異なる結果を返す組み込みのスプレッドシート関数(
NOW()
やRAND()
など)は、カスタム関数への引数として使用できません。カスタム関数が、このような揮発性組み込み関数のいずれかに基づいて値を返そうとすると、Loading...
が無期限に表示されます。
戻り値
カスタム関数は、表示する値を次のように返す必要があります。
- カスタム関数が値を返すと、関数の呼び出し元のセルにその値が表示されます。
- カスタム関数が 2 次元の値配列を返す場合、隣接するセルが空である限り、値は隣接するセルにオーバーフローします。この場合、配列によって既存のセルの内容が上書きされると、カスタム関数は代わりにエラーをスローします。例については、カスタム関数の最適化のセクションをご覧ください。
- カスタム関数は、値を返すセル以外のセルには影響を及ぼしません。 つまり、カスタム関数は任意のセルを編集できず、呼び出し元のセルと隣接するセルの編集のみを行います。任意のセルを編集するには、代わりにカスタム メニューを使用して関数を実行します。
- カスタム関数呼び出しは、30 秒以内に返される必要があります。そうしないと、セルに
Internal error executing the custom function.
というエラーが表示されます。
データの種類
Google スプレッドシートは、データの性質に応じてさまざまな形式でデータを保存します。これらの値がカスタム関数で使用される場合、Apps Script では、これらの値が JavaScript で適切なデータ型として扱われます。混乱しやすい分野は次のとおりです。
- スプレッドシートの時刻と日付は、Apps Script では日付オブジェクトになります。スプレッドシートとスクリプトでタイムゾーンが異なる場合(まれな問題)、カスタム関数で補正を行う必要があります。
- スプレッドシートの時間値も
Date
オブジェクトになりますが、操作が複雑になる場合があります。 - スプレッドシートのパーセンテージ値は、Apps Script では 10 進数になります。たとえば、値が
10%
のセルは Apps Script では0.1
になります。
オートコンプリート
Google スプレッドシートでは、組み込み関数と同様に、カスタム関数のオートコンプリートがサポートされています。セルに関数名を入力すると、入力内容に一致する組み込み関数とカスタム関数のリストが表示されます。
カスタム関数は、以下の DOUBLE()
の例のように、スクリプトに JsDoc
@customfunction
タグが含まれている場合、このリストに表示されます。
/**
* Multiplies the input value by 2.
*
* @param {number} input The value to multiply.
* @return The input multiplied by 2.
* @customfunction
*/
function DOUBLE(input) {
return input * 2;
}
上級
Google Apps Script サービスの使用
カスタム関数は、特定の Google Apps Script サービスを呼び出して、より複雑なタスクを実行できます。たとえば、カスタム関数は Language サービスを呼び出して、英語のフレーズをスペイン語に翻訳できます。
他の多くのタイプの Apps Script とは異なり、カスタム関数はユーザーに個人データへのアクセスの承認を求めることはありません。そのため、個人データにアクセスできないサービスのみを呼び出すことができます。具体的には次のようなサービスがあります。
サポート対象のサービス | メモ |
---|---|
キャッシュ | 機能するが、カスタム関数では特に有用ではない |
HTML | HTML を生成することはできますが、表示することはできません(ほとんど有用です)。 |
JDBC | |
言語 | |
ロック | 機能するが、カスタム関数では特に有用ではない |
マップ | ルートの計算はできますが、地図の表示はできません |
プロパティ | getUserProperties() は、スプレッドシートのオーナーのプロパティのみを取得します。スプレッドシート エディタでは、カスタム関数にユーザー プロパティを設定することはできません。 |
スプレッドシート | 読み取り専用(ほとんどの get*() メソッドを使用できますが、set*() は使用できません)。他のスプレッドシート( SpreadsheetApp.openById() または SpreadsheetApp.openByUrl() )を開くことはできません。 |
URL 取得 | |
ユーティリティ | |
XML |
カスタム関数がエラー メッセージ You do not have permission to
call X service.
をスローした場合、サービスはユーザー認証を必要とするため、カスタム関数では使用できません。
上記以外のサービスを使用するには、カスタム関数を記述する代わりに、Apps Script 関数を実行するカスタム メニューを作成します。メニューからトリガーされる関数は、必要に応じてユーザーに承認を求めるため、すべての Apps Script サービスを使用できます。
共有
カスタム関数は、作成されたスプレッドシートにまずバインドされます。つまり、あるスプレッドシートで作成したカスタム関数は、次のいずれかの方法を使用しない限り、他のスプレッドシートで使用できません。
- [拡張機能] > [Apps Script] をクリックしてスクリプト エディタを開き、元のスプレッドシートからスクリプト テキストをコピーして、別のスプレッドシートのスクリプト エディタに貼り付けます。
- [ファイル] > [コピーを作成] をクリックして、カスタム関数を含むスプレッドシートのコピーを作成します。スプレッドシートがコピーされると、添付されたスクリプトもコピーされます。スプレッドシートへのアクセス権を持つユーザーなら誰でもスクリプトをコピーできます。(閲覧権限しかない共同編集者は、元のスプレッドシートでスクリプト エディタを開くことはできません。ただし、ユーザーがコピーを作成すると、そのコピーの所有者となり、スクリプトを表示できるようになります)。
- スクリプトを Google スプレッドシートのエディタ アドオンとして公開します。
最適化
スプレッドシートでカスタム関数が使用されるたびに、Google スプレッドシートでは Apps Script サーバーに対して個別に呼び出しが行われます。スプレッドシートに数十(数百、数千)のカスタム関数呼び出しが含まれている場合、このプロセスは非常に遅くなる可能性があります。
そのため、大量のデータに対してカスタム関数を複数回使用する場合は、2 次元配列形式の入力として範囲を受け入れ、適切なセルにオーバーフローできる 2 次元配列を返すように関数を変更することを検討してください。
たとえば、上記の DOUBLE()
関数は、次のように 1 つのセルまたはセル範囲を受け入れるように書き換えることができます。
/**
* Multiplies the input value by 2.
*
* @param {number|Array<Array<number>>} input The value or range of cells
* to multiply.
* @return The input multiplied by 2.
* @customfunction
*/
function DOUBLE(input) {
return Array.isArray(input) ?
input.map(row => row.map(cell => cell * 2)) :
input * 2;
}
上記のアプローチでは、JavaScript の Array
オブジェクトの map メソッドを使用して、2 次元のセル配列内のすべての値に対して DOUBLE
を再帰的に呼び出します。この関数は、結果を含む 2 次元配列を返します。これにより、次のスクリーンショットに示すように、DOUBLE
を 1 回呼び出して、多数のセルを一度に計算できます。(map
呼び出しの代わりに、ネストされた if
ステートメントを使用して同じことを実現できます)。
同様に、次のカスタム関数は、インターネットからライブ コンテンツを効率的に取得し、2 次元配列を使用して 1 回の関数呼び出しで 2 列の結果を表示します。各セルで独自の関数呼び出しが必要な場合は、Apps Script サーバーで毎回 XML フィードをダウンロードして解析する必要があるため、オペレーションにかなりの時間がかかります。
/**
* Show the title and date for the first page of posts on the
* Developer blog.
*
* @return Two columns of data representing posts on the
* Developer blog.
* @customfunction
*/
function getBlogPosts() {
var array = [];
var url = 'https://gsuite-developers.googleblog.com/atom.xml';
var xml = UrlFetchApp.fetch(url).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
var entries = document.getRootElement().getChildren('entry', atom);
for (var i = 0; i < entries.length; i++) {
var title = entries[i].getChild('title', atom).getText();
var date = entries[i].getChild('published', atom).getValue();
array.push([title, date]);
}
return array;
}
これらの手法は、スプレッドシート全体で繰り返し使用されるほぼすべてのカスタム関数に適用できますが、実装の詳細は関数の動作によって異なります。