久しぶりにGAS関係の投稿です。しばらくGAS触っていませんでした。。
年内最後かなと思うので、blogの初心に戻ってGASを触っていきたいと思います。
今回はカスタムメニューを作成して、メニューバーから自作のGASコードを呼び出す方法を紹介していきます。
読んで欲しい人
- いつもスクリプトのページからスクリプトを実行している人
- Triger設定しているが、シート画面からも随時スクリプトを実行したい人
- 自分独自のスプレッドシートを作りたい人
- GASでUIいじってみたい人
やれること(ゴール)
以下のようなカスタムメニューをメニューバーに表示して、タブの選択からスクリプトを実行できるようになること。

上のスクリーンショットのように自分独自のメニューバーを作成していきます。メニューバーの項目は全てスクリプトと連動しており、独自スクリプトをGASエディター画面を開くことなく実行可能です。
実際のコード
function myFunction(){
SpreadsheetApp.getUi().alert('Hello, world');
}
function sheetIDopen() {
//処理をかく
}
function sendemail(){
var recipient = "adress";
var subject = "test from menubar";
var body = "test mail from menubar";
GmailApp.sendEmail(recipient, subject, body)
}
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('CustomeAddOn')
.addItem('画面にhello world', 'myFunction')
.addSeparator()
.addSubMenu(SpreadsheetApp.getUi().createMenu('サブメニュー')
.addItem('対象シートを開く', 'sheetIDopen')
.addItem('test_email', 'sendemail'))
.addToUi();
}
スクリプトが3つと、onOpen()で作成されたスクリプト群で上記のような画面構成が可能になります。といか、onOpen以外は全てメニューバーで項目をクリックしたときに動作するスクリプト内容を記載しただけなので、説明は特に不要かもですが。
それでは、少しずつみていきます。
コード解説
メインとなるonOpen
さて、今回のメインとなるのは以下のonOpen部分です。
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('CustomeAddOn')
.addItem('画面にhello world', 'myFunction')
.addSeparator()
.addSubMenu(SpreadsheetApp.getUi().createMenu('サブメニュー')
.addItem('対象シートを開く', 'sheetIDopen')
.addItem('test_email', 'sendemail'))
.addToUi();
}
関数名のonOpenとは?イベントハンドラを軽く理解する
まず、onOpenという関数名自体に意味があります。
これは、イベントハンドラと呼ばれる、関数名称です。イベントハンドラとは何でしょうか?
イベントハンドラとは、特定のイベントに応じてなんらかの処理を実行するもの
という感じで、特定の条件時に勝手に実行してくれる処理を定義したものというニュアンスで理解してもらえればと思います。
具体的には以下のものがあります。詳細はGAS documentのsimple trigerを参照ください。
onOpen(e)
runs when a user opens a spreadsheet, document, presentation, or form that the user has permission to edit.onEdit(e)
runs when a user changes a value in a spreadsheet.onInstall(e)
runs when a user installs an add-on.doGet(e)
runs when a user visits a web app or a program sends an HTTPGET
request to a web app.doPost(e)
runs when a program sends an HTTPPOST
request to a web app.
この中のonOpenが今回利用しているものです。内容としては、スプレッドシートやその他のGoogleサービスが開かれた時(リロードされたときも含む)に実行されるスクリプトだと理解してください。
要は、onOpenと関数名を定義すれば、スプレッドシートなどが開いた時に勝手に実行してくれます。そのため、カスタムメニューバーの内容をこの関数内に定義すれば、スプレッドシートを開いた時に、自動的に定義内容(メニューバーの作成と表示)がなされます。
メニューバーの内容の作成方法
さて、メニューバーがどうなっているかもう一度みてみましょう。

要約すると以下のようになっています。
メニューバー:CustomeAddOnというタブが作成されている → 構成要素 →①画面にhello world →②サブメニュー →サブメニュー①:対象シートを開く →test_email
では、コードはどうなっていたでしょうか?
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('CustomeAddOn')
.addItem('画面にhello world', 'myFunction')
.addSeparator()
.addSubMenu(SpreadsheetApp.getUi().createMenu('サブメニュー')
.addItem('対象シートを開く', 'sheetIDopen')
.addItem('test_email', 'sendemail'))
.addToUi();
}
どの要素が何に対応しているかを理解できれば作成できますので、一つづつ対応と機能をみていきましょう。
SpreadsheetApp.getUi()
まずは、SpreadsheetAppを呼び出して、getUi()メソッドを取っています。
getUi()メソッドは、名前の通りUiを操作するためのインスタンスを作成するメソッドです。

ちなみに今回はSpreadsheetのUiを操作するために、SpreadsheetAppクラスのgetUiメソッドを利用していますが、getUiメソッドはdocumentクラスとかにも存在します(ドキュメントのuiに独自のメニューバーを作成したい場合に利用)。
さて、これで対象とすべきインスタンスが立ち上がったということで、実際の内容を書いていきます。
.createMenu(‘CustomeAddOn’)
.createMenu()メソッドは、引数にstr(メニュー名)を取って、そのstrがメニュー名になるメソッドです。
これを実行した結果、メニューバーにCustomeAddOnという独自のタブが追加できます。名前は皆さんのご自由に付けてもらっていいです。
.addItem(‘画面にhello world’, ‘myFunction’)
.addItem()メソッドは、引数str(メニュー名)とfunction(実行する関数)を取るメソッドです。
CustomeAddOnメニューにカーソルを合わせた時に一つ目の要素に出てきた”画面にhello world”という要素を指しています。ちなみにこれを実行すると、以下のようになります。

さて、これは以下のコードで定義されている関数ですね。
function myFunction(){
SpreadsheetApp.getUi().alert('Hello, world');
}
要は、”画面にhello world”という要素に、別に定義したmyFunction関数を紐付けて、スプレッドシート画面からこのスクリプトを呼び出しているということです。
.addSeparator()
名前のままです、セパレータとして線を引いています。
.addSubMenu(SpreadsheetApp.getUi().createMenu(‘サブメニュー’)
.addSubMenuメソッドは、構成要素を有するメニュー(要はサブメニューを保持したメニュー)を作成するメソッドです。
サブメニューの作り方は、CustomeAddOnのメニューを作成した場合と同じで、createMenu()メソッドを使用していきます。
そして、作成したサブメニューの親に対して子の要素として、以下の要素をaddItemで追加しています。
.addItem('対象シートを開く', 'sheetIDopen')
.addItem('test_email', 'sendemail'))
.addItemの使い方は前段と同じで、表示名と対象とする関数を紐付ける方法です。
.addToUi()
.addToUi()メソッドで、今まで定義してきた要素を実際のUiインスタンスに追加していきます。
これを忘れると表示されないので、ご注意ください。
まとめ
さて、スプレッドシートやGoogleサービスのUiは既定のものかと思っていたかもしれませんが、実はこれもカスタマイズできるんですね。
久しぶりのGAS記事でしたが、単純にスプレッドシートのデータだけを取り扱うのではなく、作業を効率化するためにスプレッドシート自体もカスタマイズしていこうという話でした。
そこまで多くの方がカスタマイズしているか分かりませんが、同じような作業を繰り返すマスタースプレッドシートとかだと一度Uiを自分仕様にカスタマイズしておくと、その後の作業は捗るかもですね。