Google スプレッドシートのカスタム関数

Google スプレッドシートには、AVERAGESUMVLOOKUP など、何百もの組み込み関数が用意されています。ニーズに十分に対応できない場合は、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 の記述方法がわからず、学ぶ時間がない場合は、アドオンストアを確認して、必要なカスタム関数を他のユーザーがすでに作成していないか確認してください。

カスタム関数の作成

カスタム関数を作成するには:

  1. Google スプレッドシートでスプレッドシートを作成するか開きます。
  2. メニュー項目 [拡張機能] > [Apps Script] を選択します。
  3. スクリプト エディタ内のコードをすべて削除します。上記の DOUBLE 関数については、コードをコピーしてスクリプト エディタに貼り付けます。
  4. 上部の保存アイコン()をクリックします。

これで、カスタム関数を使用できるようになりました。

Google Workspace Marketplaceからカスタム関数を取得する

Google Workspace Marketplace には、Google スプレッドシートのアドオンとしていくつかのカスタム関数が用意されています。これらのアドオンを使用または確認するには:

  1. Google スプレッドシートでスプレッドシートを作成するか開きます。
  2. 上部にある [アドオン] > [アドオンを取得] をクリックします。
  3. Google Workspace Marketplace が開いたら、右上の検索ボックスをクリックします。
  4. 「カスタム関数」と入力して Enter キーを押します。
  5. 目的のカスタム関数アドオンが見つかった場合は、[インストール] をクリックしてインストールします。
  6. ダイアログ ボックスに、アドオンに認証が必要というメッセージが表示されることがあります。その場合は、通知をよく読み、[許可] をクリックします。
  7. スプレッドシートでアドオンが使用可能になります。別のスプレッドシートでアドオンを使用するには、別のスプレッドシートを開き、上部にある [アドオン] > [アドオンを管理] をクリックします。使用するアドオンを見つけて、オプション > [このドキュメントで使用] をクリックします。

カスタム関数の使用

カスタム関数を記述するか、Google Workspace Marketplaceからインストールすれば、組み込み関数と同じくらい簡単に使用できます。

  1. 関数を使用するセルをクリックします。
  2. 等号(=)に続けて関数名と入力値(=DOUBLE(A1) など)を入力し、Enter キーを押します。
  3. セルに 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 オブジェクトになります。スプレッドシートとスクリプトで異なるタイムゾーンを使用している場合(まれな問題です)、カスタム関数で補正する必要があります。
  • スプレッドシートの期間値も Date オブジェクトになりますが、操作は複雑になる可能性があります
  • スプレッドシートにおけるパーセンテージ値は、Apps Script では 10 進数になります。たとえば、値が 10% のセルは Apps Script では 0.1 になります。

オートコンプリート

Google スプレッドシートでは、組み込み関数と同様に、カスタム関数のオートコンプリートをサポートしています。セルに関数名を入力すると、その内容に一致する組み込み関数とカスタム関数のリストが表示されます。

カスタム関数のスクリプトに JsDoc @customfunction タグが含まれている場合、このリストにはカスタム関数が表示されます。下記の DOUBLE() の例をご覧ください。

/**
 * 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;
}

これらの手法は、スプレッドシート全体で繰り返し使用されるほぼすべてのカスタム関数に適用できますが、実装の詳細は関数の動作によって異なります。