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 スプレッドシートのアドオンとしていくつかのカスタム関数があります。これらのアドオンを使用する方法や確認する方法は次のとおりです。

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

カスタム関数を使用する

カスタム関数を作成するか、からインストールすると、組み込み関数と同じように簡単に使用できます。

  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 秒以内に返す必要があります。一致しない場合、セルには #ERROR! が、セルのメモには Exceeded maximum execution time (line 0). が表示されます。

データ型

Google スプレッドシートでは、データの性質に応じてデータがさまざまな形式で保存されます。これらの値がカスタム関数で使用されている場合、Apps Script はこれらの値を JavaScript の適切なデータ型として扱います。混乱しがちな部分は次のとおりです。

  • スプレッドシートの時刻と日付は、Apps Script では Date オブジェクトになります。スプレッドシートとスクリプトで異なるタイムゾーンを使用している場合(まれな問題です)、カスタム関数で調整する必要があります。
  • スプレッドシートの長さの値も Date オブジェクトになりますが、操作が複雑になる可能性があります
  • スプレッドシートの割合値は、Apps Script では小数値になります。たとえば、値が 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 Scripts とは異なり、カスタム関数では、個人データへのアクセスを承認するようユーザーに求めることは決してありません。そのため、呼び出せるのは、個人データにアクセスできないサービス(具体的には次のサービス)のみです。

サポート対象のサービス メモ
キャッシュ 機能はしますが、カスタム関数では特に役に立ちません
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 サービスを使用できます。

共有

カスタム関数は、作成されたスプレッドシートにバインドされています。つまり、次のいずれかの方法を使用しない限り、1 つのスプレッドシートで記述されたカスタム関数を他のスプレッドシートで使用することはできません。

  • [拡張機能] > [Apps Script] をクリックしてスクリプト エディタを開き、元のスプレッドシートからスクリプト テキストをコピーして、別のスプレッドシートのスクリプト エディタに貼り付けます。
  • [ファイル] > [コピーを作成] をクリックして、カスタム関数を含むスプレッドシートのコピーを作成します。スプレッドシートをコピーすると、それに関連付けられているスクリプトもコピーされます。スプレッドシートにアクセスできるユーザーは誰でもスクリプトをコピーできます。(閲覧専用権限を持つ共同編集者は、元のスプレッドシートのスクリプト エディタを開くことができません。ただし、コピーを作成すると、コピーの所有者になり、スクリプトを確認できるようになります)。
  • スクリプトを Google スプレッドシートのエディタ アドオンとして公開します。

最適化

スプレッドシートでカスタム関数が使用されるたびに、Google スプレッドシートは Apps Script サーバーを個別に呼び出します。スプレッドシートに数十(または数百、数千)のカスタム関数呼び出しが含まれている場合、このプロセスは非常に遅くなる可能性があります。

したがって、広範なデータに対してカスタム関数を複数回使用する場合は、関数を変更して、範囲を 2 次元配列の形式で入力として受け取り、適切なセルにオーバーフローできる 2 次元配列を返すようにすることを検討してください。

たとえば、上記の DOUBLE() 関数は、単一のセルまたはセル範囲を受け取れるように次のように書き換えることができます。

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

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