目標
要怎麼將我們的 GAS 成果打包成別人可以使用的版本?我們已經學了快一個月的 GAS 使用方式,但並不是每個人都熟悉 GAS 的進入與使用。我們要怎麼樣讓其他人也便於上手運用我們 GAS 的成果?這就是今天的主題。

我會介紹其中最主要的兩種方式——
- 包成擴充功能(Add-On)似的 UI 選項
- 包成能用於連接的 API / HTML page
那這兩題分別是這兩天的主題。那我們今天會主要介紹這個第一個主題背後的「關鍵問題」——
- 怎麼將我的 GAS 成果包裝成像是擴充功能那樣的 UI 介面,給他人使用?
那我們就開始吧!
Q1. 怎麼將我的 GAS 成果包裝成像是擴充功能那樣的 UI 介面,給他人使用?
首先先幫大家釐清,我們今天講的 Add-On 其實翻譯上是「外掛功能」,是可以在 Google Workspace Marketplace 上取得的。但因為「外掛」比較不一定好理解,我在上方用「擴充功能」主要是為了初期閱讀時的理解方便。實際上的「擴充功能」對應的英文是 Extension,是我們可以掛載在 Chrome 上的像是 OneTab 等,可以在 Google Extensions 取得。

以下實作部分,為了用語上讓大家搞混,接下來都會用 Add-On 來說明我們的主題。
Input
- Google Workspace 系列產品
- 舉凡 Google Docs / Google Sheet / Google Form / Google Slides …. 都算是!
- 已經完成的 GAS 程式碼
那我們今天用的案例是 Google Sheet,會將 D26 的「造表單」 和 D27 的「拿分數」成果轉乘 Google Apps Script。
Output
- 換一個帳號,也能在同一個頁面開啟的 Add-On。
也分享下,目前做的僅僅是「綁定表單」。如果要上架 Google Workspace Marketplace,那會有另外的 流程 要申請。
Step 1 從 Google Sheet 進入 GAS
今天我們用 Google Sheet 作為連結 GAS 的管道,讓我們借用 D14 的影片。

一樣第一次按下 GAS 中的「執行」會有「存取驗證」需要大家按一下。這邊仍是借用一下 D2 的影片。

接著,我們要進入 GAS 中設定 UI 畫面。
Step 2 透過 getUi() 來設定
在 Google Workspace 系列產品中,我們主要都是透過 getUi() 來取得可以調整的 UI,再進行調整。使用方式如下主要是透過像 let ui = SpreadsheetApp.getUi(); 來取得可以調整的項目。好,接著我們看完整可以用的程式碼——
function greeting_toast_hello(){
SpreadsheetApp.getActiveSpreadsheet().toast("Hello!")
}
function greeting_toast_hi(){
SpreadsheetApp.getActiveSpreadsheet().toast("Hi!")
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('客製化工具列')
.addSubMenu(ui.createMenu('打招呼')
.addItem('Say Hi', 'greeting_toast'))
.addToUi();
}
跑起來長這樣——

那接下來一步步說明。以下兩個是為了方便展示,我先弄的一份比較好觀察的程式碼。
SpreadsheetApp.getActiveSpreadsheet().toast("Hi!");
跑起來長這樣——
接著用 onOpen() 這個 Opening Trigger 來設定,換句話說是設定完後會在每次開啟 Google Sheet 時同時幫你自動執行的。所以當然也可以不用設定 UI,也可以是每次有人打開表單就把裡面資料清乾淨,只要改其中的程式碼即可。
但,如果你發現自己的 onOpen() 程式碼改了,但結果還沒有更新,比較簡單的方式是重新整理你的 Google Sheet。要注意的是, onOpen() 是不用也不能執行的,它會顯示錯誤給你如下面影片——

UI 主要有幾種主要的案件—— addItem()、Prompt、Alert(prompt)、shoeModeless
ui.addItem() 設定基本按鍵
最基本的按鍵是透過 addItem() 來達成
function onOpen() {
let ui = SpreadsheetApp.getUi();
ui.createMenu('客製化工具列')
.addItem('Say Hi', 'greeting_toast_hi')
.addSubMenu(ui.createMenu('打招呼')
.addItem('Say Hello', 'greeting_toast_hello')
)
.addToUi();
}
這段跑起來就是我們上面說明的——

那 onOpen() 裡面的程式邏輯是這樣,首先用 getUi() 抓出 ui 後——
- 用
createMenu()先設定一個 Menu 叫做「客製化工具列」(可以改自己想要的名字) - 再來跟它說,我要設定一個按鍵(
addItem()),這個按鍵顯示叫「Say Hi」要能幫我執行名叫greeting_toast_hi的程式碼 - 再跟它說,我要一個有按鍵跑出子目錄(
addSubMenu()),說我要一個顯示「Say Hello」的按鍵,幫我執行greeting_toast_helloi()的程式碼
這邊就是基礎的部分。接著我們來講解其它用法。
用 ui.alert 設定提醒視窗
先來個我們常用的「提醒視窗」,這邊都先上程式碼——
function onOpen() {
let ui = SpreadsheetApp.getUi();
ui.alert('Hello, world');
}
跑起來長這樣,一使用功能就會跳蓋版通知。
用 ui.prompt() 設定可回應的彈跳視窗
這邊的話則是可回應的彈跳視窗,也看說看回應,可以直接抓出回應的數值,甚至是直接回傳。
function onOpen() {
let ui = SpreadsheetApp.getUi();
let response = ui.prompt('我想認識你', '可以知道你的名字是?', ui.ButtonSet.YES_NO);
if (response.getSelectedButton() == ui.Button.YES) {
SpreadsheetApp.getActiveSpreadsheet().toast('使用者的大名是 %s.', response.getResponseText());
} else if (response.getSelectedButton() == ui.Button.NO) {
SpreadsheetApp.getActiveSpreadsheet().toast('使用者不想提供大名');
} else {
SpreadsheetApp.getActiveSpreadsheet().toast('使用者連直接關掉');
}
}
跑起來長這樣——
以上的功能雖然都用 onOpen 舉例,但實際上都是可以搭配其他 GAS 的功能使用,以下就示範搭配的方式。
用 showModalDialog 呈現 HTML 的頁面
那我們要怎麼樣用更浮誇的 頁面 呢?可以考慮加上 HTML
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show dialog', 'showDialog')
.addToUi();
}
function showDialog() {
var html = HtmlService.createHtmlOutput('<p>這是一種簡單的小程式</p>')
.setWidth(250)
.setHeight(300);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, '客製化外掛');
}
主要就是,設定好頁面的長與寬,以及你要丟進去的 HTML body即可。跑起來長這樣——

用 showSidebar 呈現 HTML 的頁面
同樣地, HTML 頁面也可以用成 Sidebar 的形式。程式碼如下——
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show Sidebar', 'showSideBar')
.addToUi();
}
function showSideBar() {
var html = HtmlService.createHtmlOutput('<p>這是一種簡單的小程式</p>')
.setTitle('我的 Side Bar');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showSidebar(html);
}
跑起來長這樣——

而以上這兩個案例的 HTML 頁面中,也可以鑲入簡單的 CSS 語法,並將 createHTMLOU 變成 createHtmlOutputFromFile 即可,可以參考官方的範例 與玩一下 HTML 與 CSS。如果想知道原本的 API 是怎麼寫,可以參考 Google Apps Script Class Ui。
如果要用 Google Slides、Google Document、Google Form 等,基本上是只要將上方五個案例的 SpreadSheetApp 換成 SlidesApp 、DocumentsApp或 FormApp 即可。
好,那今天我們主要到這邊,今天我們學了——
- 透過
onOpen()設定一開始就開啟的程式 - 透過
getUi設定五種不同的打包方式
以上可以幫助我們打包。而只要打包好(設定好onOpen())之後,那不管是誰,只要用電腦的瀏覽器打開 Google Sheet 等產品,就可以看到我們的「客製化工具列」,基本上就可以使用囉。



