概要
スプレッドシートで、電子印鑑を簡単に配置する方法を実装した際に、カスタムメニューを動的に作成できないかと試行錯誤したので残しておきます。
そもそも、電子印鑑の必要な数だけメニューを作ればと思っていたのですが、カスタムメニューを作成する際は、関数名を引数に渡す仕様で引数を渡せないため、なかなか思うようにできず。
結果、「【GAS】スプレッドシートのカスタムメニューでアイテム毎に関数を動的(?)に割り当てる」を参考に、動的にカスタムメニューを作成することができました。

【GAS】スプレッドシートのカスタムメニューでアイテム毎に関数を動的(?)に割り当てる – Qiita
概要これに回答したので。カスタムメニューって便利なんだけど、関数指定が文字列だけだったり、関数に引数が渡せなくていやんな感じなので、それを打開したい!結論からいうと!カスタムメニューアイテム毎に別々の関数を定義…
サンプルスクリプト
/**
* 参考:https://qiita.com/neonemo/items/86f34ecb0db3cfc51c8d
*/
const SAMPLE = (function() {
// 関数
let autoFunc = {};
// サブメニューの数だけ繰り返し
// メニューの作成と同じ条件で繰り返す必要あり。
for (let i = 1; i <= 5; i++) {
// 連想配列のキーを関数名にする
autoFunc[`sample_menu_${i}`] = function() {
// TODO ここにメニューで呼び出された時の処理を書く
// 今回はダイアログを表示するだけ
Browser.msgBox(`sample_menu_${i}`);
}
}
return autoFunc;
})();
/**
* メニューの作成
*/
function setMenu() {
// サブメニュー
let menu = [];
// サブメニューの数だけ繰り返し
// (サンプルなので固定で5つ、作成する)
for (let i = 1; i <= 5; i++) {
// メニューの名前
let name = `menu${i}`;
// メニューでクリックされて呼び出される関数名
let funcName = `SAMPLE.sample_menu_${i}`;
// サブメニューのname、functionNameを配列に設定
menu.push({
name: name,
functionName: funcName
});
}
// メニューの作成
SpreadsheetApp.getActiveSpreadsheet().addMenu('サンプルメニュー', menu);
}
できるだけ、サンプルスクリプトにコメントを載せていますのでそちらを確認してください。
今回、このスクリプトのポイントとしては、
- JavaScriptでいう「即時関数」を使用すること
- 即時関数内の繰り返し処理と、メニューの作成をする繰り返し処理の条件は同じにする
- メニューの作成で、「SpreadSheetオブジェクト.addMenu(name, subMenus)」を使用する
になると思います。
最後に
電子印鑑を簡単に配置する方法は近日中に別途、紹介をしたいと思います。