Google公式User Guide勝手翻訳


ユーザーインターフェイスの構築

Google Apps スクリプトは、情報を入手したり、表示するためのユーザーインターフェイスを構築できる。


スクリプトによって次に示す広範囲のユーザーインターフェイス要素を作り出す事ができる。

  • プッシュボタン
  • ラジオボタン
  • トグルボタン
  • チェックボックス
  • テキストフィールド
  • ラベル
  • タイトル
  • リストボックス
  • ダイアログボックス
  • 色々なパネル
  • ここに載せられるよりずっと多い更なるUI要素が存在する。 どうやって利用可能な要素を見るかはこのセクションを参照  Viewing the Available User Interface Elements  ここもthe API documentation for this feature

ユーザーインターフェイスI要素をまとめ上げた結果、ユーザーインターフェイスとしてそれは働くことになる。ユーザーインターフェイスを表示するには3つの方法がある:

  • スプレッドシートから直接
  • サイトから直接
  • 独立したサーブレットとして

インターフェースをどう表示させるか決めるための情報は,こちら Deciding Whether to Run a Script from a Spreadsheet or as a Service


使用可能なユーザーインターフェイス要素を見る

Google Apps スクリプトで莫大な数のユーザーインターフェイス要素を作り出す事ができる。


全ての利用可能なユーザーインターフェイスをみるには:

  1. スプレッドシートを開く
  2. ツール>スクリプトエディタをクリック
  3. 次の命令文を打ち込む コピーアンドペーストはしてはならない
function myFunction() {
 
var app = UiApp.createApplication();
 
var button = app.
}

こうすることによって利用可能なユーザーインターフェイスの要素が、必要な引数と一緒にリストに表示されるのが見えると思う。もしこれが見れないなら、多分コピーアンドペーストしたからだろう。オートコンプリートが働くためには app に続くピリオドをタイプする必要がある。


ユーザーインターフェイスのデザイン

ユーザーインターフェイスを表示するスクリプトを書く前に、次のことをすること:
  1. スクリプトの計画 スクリプトにどんなことをやらせたいの?
  2. 何を表示したいのか、どんな情報をユーザーから集めたいのか、具体的に書くこと
  3. 表示するべきユーザーインターフェイスを実際に書いてみて、要素についてノートを取ってみる
  4. ユーザーが入力したらスクリプトと、インターフェースは何をするのかしっかりと決める
  5. スクリプトを抜けるときの状態を決める



ユーザーインターフェイスの要素の作成

ボタンとかダイアログボックスなどのユーザーインターフェイス要素を作る前に、それらを格納するため、UiApp アプリケーションオブジェクトが必要となる。そうしてから、ボタンや、パネル、ダイアログボックスなどをそこに追加することができる。


一般的な構文は次のようになる:

  •  var your_application_object_name = UiApp.createApplication();  UiAppアプリケーションオブジェクトを作るにはこのように書く。 your_application_object_nameは、あなたが決める。
  • var your_ui_element_name your_application_object_name.createElement_Name(); ユーザーインターフェイス要素を作って、  UiAppアプリケーションオブジェクトに組み込むには、このように書く。
  • your_ui_element_name1.add(your_ui_element_name2); ユーザーインターフェイス要素を他の要素に組み込むにはこのように書く。例えば、パネルにボタンを表示する場合など。


次の宣言により、UiAppクラスのcreateApplicationメソッドを呼び出して、myappというアプリケーションオブジェクトを作る。

var myapp = UiApp.createApplication();

ここでユーザーインターフェイスが作れるようになる。Press Meと表示されるボタンをここでは作る。

var mybutton = myapp.createButton('Press Me');

ボタンに表示させたい文字は、引数として、渡される。

パネルにボタンを表示させたいなら、垂直パネルを次で作ってみる。

var mypanel = myapp.createVerticalPanel();

他にも、ポップアップパネル、スタックパネル、フォーカスパネルなどの様々なパネルがある。

パネルにボタンを表示するコードはこのようになる。

mypanel.add(mybutton);

次に、アプリケーションにパネルを加える。

myapp.add(mypanel);

最後に、Google Apps スクリプトにインターフェイスを表示するように命令する必要がある。

show(myapp);

ユーザーインターフェイス要素は、好きな順序で作ることができる。その順番が、表示される順番になる。例えば、VerticalPaneオブジェクトをつくって、a,b,cの順で要素を加えてったとすると、その順番で、上から下に表示される。要素を作ることと、加えることは別々のステップで、別々の命令文が必要になる。

下のは、パネルにポタンを表示するだけの、短いスクリプトであり。それぞれのラインのコメントに詳細を記する。.

function myAppFunction() { // 関数に名前をつける
// mydocに、現在のスプレッドシートを読み込む
 
var mydoc = SpreadsheetApp.getActiveSpreadsheet();

// UiApp オブジェクトの myapp を作成してタイトルを付ける
 
var myapp = UiApp.createApplication().setTitle('Here is the title bar');

// mybuttonというボタンを作成してボタン上のテキストをセットする
 
var mybutton = myapp.createButton('Here is a button');

// mypanelというverticalpanelを作成して、myappに加える
 
var mypanel = myapp.createVerticalPanel();

// mybuttonをmypanelに加える
  mypanel
.add(mybutton);

// mypanelをmyappに加える
  myapp
.add(mypanel);

 
// show()メソッドを使ってUiAppオブジェクトとすべての要素を表示する
  mydoc
.show(myapp);
}

オブジェクトに値をセットするセッターメソッドは一緒につなげることができる。上のスクリプトの例では、var myapp = UiApp.createApplication().setTitle('Here is the title bar'); によって、UiAppオブジェクトを作成して、タイトルをセットしている。同様に、オブジェクトのサイズもセット出来る。

var myapp = UiApp.createApplication().setTitle('Here is the title bar').setHeight(50).setWidth(100);

次にパネルを表示するだけの短いスクリプトを書いてみる。GridオブジェクトとsetWidgetメソッドを使って、更に複雑なレイアウトを作ることができる。更にここではテキストボックスをつくりそこにラベルの表示の仕方も示す。ここでのテキストボックスにはテキストを入力できるが、ボタンを押しても何も起こらない。

var mygrid = myapp.createGrid(3, 2); グリッドサイズ3 x 2という意味である。そして setWidgetメソッドでグリッドのどの位置に要素が表示されるかを定義する。

ポジションは、ゼロを起点としているので、行は1,2,3ではなく0,1,2になることに注意する。

function demoUI() {
 
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
 
var myapp = UiApp.createApplication().setTitle('An improved GUI');
 
 
var mygrid = myapp.createGrid(3, 2);
  mygrid
.setWidget(0, 0, myapp.createLabel('Name:'));
  mygrid
.setWidget(0, 1, myapp.createTextBox());
  mygrid
.setWidget(1, 0, myapp.createLabel('Age:'));
  mygrid
.setWidget(1, 1, myapp.createTextBox());
  mygrid
.setWidget(2, 0, myapp.createLabel('City'));
  mygrid
.setWidget(2, 1, myapp.createTextBox());
   
 
var mybutton = myapp.createButton('Press me');
 
var mypanel = myapp.createVerticalPanel();
  mypanel
.add(mygrid);
  mypanel
.add(mybutton);
  myapp
.add(mypanel);
  mydoc
.show(myapp);
}​


スプレッドシートをユーザーインターフェイスから更新

ユーザーインターフェイス要素の作成でパネルに様々なコントロールの表示の仕方を学んだが、そのままのスクリプトでは何もしない。ユーザーインターフェイスをもっと役立つものにするには、ユーザーがインターフェイスを通じて入力した情報を元に、スプレッドシートが更新されるようにしたいところだ。

インターフェイスのアクションに反応して、スプレッドシートを更新する短いスクリプトを次に示す。セルA1の値を、ボタンをクリックする度に1つずつ増やしていく。


function foo() {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var app = UiApp.createApplication();
 
 
var button = app.createButton('submit');
  app
.add(button);
 
 
var handler = app.createServerClickHandler('b');
  button
.addClickHandler(handler);
 
  doc
.show(app);
}


function b() {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var cell = doc.getRange('a1');
  cell
.setValue(Number(cell.getValue()) + 1);
 
 
var app = UiApp.getActiveApplication();
  app
.close();

// 次のラインはwidgetが実際に閉じるのに必要となる
 
return app;
}

スクリプトエディタにこれをコピーして実行してみると、ボタンをクリックする度に、パネルを再表示するために関数を再実行しなければならないことに気が付くことだろう。これはパネルをアクティブ状態で表示し続けるためのループ構造がスクリプトにないためである。この例では、パネルはapp.close();return app;の位置まで来ると、画面から消えてしまうことになる。

関数 foo() 内のコードの意味は、ここまでの説明でだいたいわかってることと思う。新たに付け加えた部分は:

  var handler = app.createServerClickHandler('b');
  button
.addClickHandler(handler);

var handler = app.createServerClickHandler('b');の部分で、handlerというサーバーサイドのクリックハンドラーを、UiAppオブジェクトをappの一部分として作成している。クリックハンドラーは、マウスのクリックに対して、アクションを実行する。サーバーサイドとは、サーバーでアクションが行われるということである。ここではGoogle App スクリプトのサーバーだ。引数 ('b' ) の意味は、ハンドラーアクションは関数 b() を実行する事という意味だ。

ボタンには、複数のクリックハンドラーを付け加える事ができる。それらは、並行して働くことになる。

button.addClickHandler(handler);の意味は、すでに定義されたbuttonオブジェクトにクリックハンドラーをくっつけるという意味。

二番目の関数 b() は、セルA1の値を増やし、アプリケーションappを閉じ、スタート地点に戻る命令文で構成されている。

次に示すのは、もっと長くて複雑なスクリプトだ。パネルのテキストフィールドから情報を集め、スプレッドシートに書き込む。行間のコメントにこのスクリプトの解説が書いてある。

function foo() {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var app = UiApp.createApplication().setTitle('New form!');
 
// 3つのテキストボックスとそれのラベルが入るグリッドを作成する
 
var grid = app.createGrid(3, 2);
  grid
.setWidget(0, 0, app.createLabel('Name:'));
 
 
// テキストボックスに入力されたテキストははuserNameに渡される
  grid
.setWidget(0, 1, app.createTextBox().setName('userName'));
  grid
.setWidget(1, 0, app.createLabel('Age:'));
  grid
.setWidget(1, 1, app.createTextBox().setName('age'));
 
 
// テキストボックスに入力されたテキストは、ageに渡される
  grid
.setWidget(2, 0, app.createLabel('City'));
  grid
.setWidget(2, 1, app.createTextBox().setName('city'));
 
 
//テキストボックスに入力されたテキストは、cityに渡される
 
 
// 垂直パネルを作製し..
 
var panel = app.createVerticalPanel();
 
 
// ...グリッドを加える
  panel
.add(grid);
 
 
// ボタンとクリックハンドラーを作成する。グリッドオブジェクトをコールバックエレメントとして渡す。
 
// 関数bをサーバークリックハンドラーとして識別する
 
var button = app.createButton('submit');
 
var handler = app.createServerClickHandler('b');
  handler
.addCallbackElement(grid);
  button
.addClickHandler(handler);
 
 
// ボタンをパネルに加え、パネルをアプリケーションに加える。そして、スプレッドシートdocにアプリケーションを表示する
  panel
.add(button);
  app
.add(panel);
  doc
.show(app);
}

// スプレッドシートの値を記録する関数
function b(e) {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var lastRow = doc.getLastRow(); //スプレッドシートの値を含む最後の行を判別する
 
var cell = doc.getRange('a1').offset(lastRow, 0); // 列Aにおける次の空欄のなセルに決める
  cell
.setValue(e.parameter.userName); // セルの値を userName でセットする
  cell
.offset(0, 1).setValue(e.parameter.age); //隣接するセルの値を age でセットする
  cell
.offset(0, 2).setValue(e.parameter.city); // 次のセルの値を city でセットする
 
// 消去 - UiAppを獲得して, 閉じて, 戻る
 
var app = UiApp.getActiveApplication();
  app
.close();
 
// 次のラインはwidgetが実際に閉じるのに必要である
 
return app;
}​

上のスクリプトを、exitを選ぶまで、何回でも使えるフォームに改良したものを次に示す。行間コメントに新たな命令文の詳細を記す。

function foo() {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var app = UiApp.createApplication().setTitle('form!');

// 入力フォームを作る。3 x 2のグリッドに、name,age,cityのテキストボックスを組み入れ、vertical パネルに加える。  
 
var grid = app.createGrid(3, 2);
  grid
.setWidget(0, 0, app.createLabel('Name:'));
  grid
.setWidget(0, 1, app.createTextBox().setName('userName').setId('userName'));
  grid
.setWidget(1, 0, app.createLabel('Age:'));
  grid
.setWidget(1, 1, app.createTextBox().setName('age').setId('age'));
  grid
.setWidget(2, 0, app.createLabel('City'));
  grid
.setWidget(2, 1, app.createTextBox().setName('city').setId('city'));
 
// verticalパネルを作り、グリッドを加える。
 
var panel = app.createVerticalPanel();
 
  panel
.add(grid);
 
//ここが前述のスクリプトと違うところ
// buttonPanelという水平パネルを作製する。そこにはsubmitとcloseのボタンを入れる。
//
 
var buttonPanel = app.createHorizontalPanel();

// 二つのボタンをbuttonPanelに追加する。button(送信) closeButton(閉じる)
// submitボタンのためのサーバークリックハンドラーsubmitHandlerを作成し、submitHandlerをクリックハンドラーとしてbuttonに渡す。
// 関数submitはsubmitボタンがクリックされると呼ばれる。
 
var button = app.createButton('submit');
 
var submitHandler = app.createServerClickHandler('submit');
  submitHandler
.addCallbackElement(grid);
  button
.addClickHandler(submitHandler);
  buttonPanel
.add(button);
 
//closeボタンに対応するサーバークリックハンドラーcloseHandlerを作成してクリックハンドラーとして、closeボタンに対応させる。
// 関数closeはcloseボタンはクリックされると呼ばれる。
 
var closeButton = app.createButton('close');
 
var closeHandler = app.createServerClickHandler('close');
  closeButton
.addClickHandler(closeHandler);
  buttonPanel
.add(closeButton);
 

// statusLabelとよぶラベルを作成し、見えないようにする。そしてbuttonPanelとstatusLabelをメインパネルに加える。
 
var statusLabel = app.createLabel().setId('status').setVisible(false);
  panel
.add(statusLabel);
 
  panel
.add(buttonPanel);
 
  app
.add(panel);
  doc
.show(app);
}

// closeボタンがクリックされると、全て閉じて戻る
function close() {
 
var app = UiApp.getActiveApplication();
  app
.close();
 
// 次のラインははwidgetが実際に閉じるのに必要である
 
return app;
}

//submitボタンがクリックされた時に呼ばれる関数
function submit(e) {

//テキストボックスのデータをスプレッドシートに書き込む
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
 
var lastRow = doc.getLastRow();
 
var cell = doc.getRange('a1').offset(lastRow, 0);
  cell
.setValue(e.parameter.userName);
  cell
.offset(0, 1).setValue(e.parameter.age);
  cell
.offset(0, 2).setValue(e.parameter.city);
 
// 新たな値を入力できるように、テキストボックスをクリアする
 
var app = UiApp.getActiveApplication();
  app
.getElementById('userName').setValue('');
  app
.getElementById('age').setValue('');
  app
.getElementById('city').setValue('');
// ステイタス行を見えるようにして、ユーザーに可能な行為を伝える
  app
.getElementById('status').setVisible(true).setText('User ' + e.parameter.userName + ' entered.
  To add another, type in the information and click submit. To exit, click close.'
);
 
return app;
}​  

クライアントハンドラの使用

前述のクリックハンドラーは、サーバーサイドハンドラーである。ユーザーのブラウザーからサーバーへ、またそこからブラウザーへ戻ってくる。そのため、状況によっては反応が遅すぎることになる。クライアントハンドラーはサーバーに接続することなく、ブラウザ内でスクリプトをイベントに反応させることができる。イベントに対して何ができるかは、前もって定義された共通アクションに制限されるがそれでも、appを機敏に反応するように作るような柔軟性は充分ある。前述の例では、submitボタンを押しただけ、submit関数を呼ぶことになる。これはネットワークが遅くて、ユーザーが即座にフィードバックを手に入れられない時に更に深刻な問題になることだろう。


この問題を解決するには、サーバーを介する事なくブラウザ上で実行されるハンドラーを作成することである。クライアントハンドラーを使うことによって、Google Appsスクリプトサーバーへいちいち飛ぶことなく、ブラウザのイベントを処理する事ができる。これらのクライアントサイドのハンドラーは、安全上の理由から複雑なアクションには対応していないが、多くの上記のような一般的な問題を解決することができる。

同様の例で、あなたのAppのユーザーに素早いレスポンスを与えたいケースを考える。例えば数字を入力する所で文字をユーザーが入力したとすると、送信した後じゃなくて、タイプしてる途中でユーザーに注意を促したいような時があると思う。サーバイベントハンドラはこのような単純で良く使われるような処理には重すぎる。Apps スクリプトの新クライアントハンドラーとバリデーターはこのような場合をサポートしてるよ!

次のシンプルなアプリケーションはユーザーがボタンをクリックすることで 、"Hello world”と表示します。

function doGet() {
 
var app = UiApp.createApplication();
 
var button = app.createButton("Say Hello");

 
// "Hello World!"のテキストが書かれたラベルを作製し、今のところは隠しとく
 
var label = app.createLabel("Hello World!").setVisible(false);

 
//サーバーを必要としないハンドラーをを作る
 
//ハンドラーに違うターゲットに対応する二つのアクションを与える
 
//最初のアクションはハンドラーを呼び出すwidgetを無効化する
 
//で2つ目はラベルを表示する
 
var handler =
    app
.createClientHandler().forEventSource().setEnabled(false).forTargets(
      label
).setVisible(true);

 
//ボタンがクリックされると呼び出されるようにハンドラーを加える
  button
.addClickHandler(handler);

  app
.add(button);
  app
.add(label);
 
return app;
}

上のクライアントハンドラー例は二つのステップを踏みます

  1. サーバーハンドラーと同様にクライアントハンドラーを作成する
  2. このハンドラーがターゲットとするwidgetを指定する。ターゲットwidgetとはハンドラーがそのwidgetに対して働くと言うことである。ハンドラーのターゲットに設定するには次の2つの内いずれかの方法をとる。(a)forTargetsメソッドを使ってターゲットwidgetを指定する。(b)forEventSourceメソッドを使って(イベント元である)widget自体をクライアントハンドラーに繋げる。

上の例では、ハンドラーターゲットがイベントソース(ここではボタン)になるように設定した。そうすることによって、クリックされたボタンに適用される。最終的に、ハンドラーがとる処理を定義する。この場合は、setEnabled(false)を使って、ボタンを無効化している。setEnabledとは別に、setStyleAttributeを使ってスタイルを変えることができるし、setTextをつかってテキストを変えることもできる。一つのクライアントハンドラーは複数の処理を行うことができる。ただ繋げて書いていけばいい。更に、widgetごとに処理を変える為に、ターゲットを変えることさえできる。我々の例では、ボタンを無効化することに加えて、setVisibleを使って、ラベルを表示するようにしてある。



バリデーターの使用

バリデーターはクライアントハンドラーとサーバーハンドラー両方において、それらが呼び出されれる前に単純なチェックを行う事ができるものです。例えば、次のアプリケーションはユーザーが入力した二つの数字を足すだけのものだが、バリデーターによって、両方のテキストボックスが数字であることが確認された時のみサーバーが呼び出されるようにしている。

function doGet() {
 
var app = UiApp.createApplication();

 
// インプットボックスとボタンの作成
 
var textBoxA = app.createTextBox().setId('textBoxA').setName('textBoxA');
 
var textBoxB = app.createTextBox().setId('textBoxB').setName('textBoxB');
 
var addButton = app.createButton("Add");

 
//加算関数を呼ぶためのハンドラーの作成
 
// textBoxAとtextBoxB両方が数字の場合のみaddが呼び出されるように
 
// ハンドラーにバリデーターを加える。
  var handler =
    app
.createServerClickHandler('add').validateNumber(textBoxA).validateNumber(
      textBoxB
).addCallbackElement(textBoxA).addCallbackElement(textBoxB);

  addButton
.addClickHandler(handler);

  app
.add(textBoxA);
  app
.add(textBoxB);
  app
.add(addButton);
 
return app;
}

function add(e) {
 
var app = UiApp.getActiveApplication();
 
var result =
    parseFloat
(e.parameter.textBoxA) + parseFloat(e.parameter.textBoxB);
 
var newResultLabel = app.createLabel("Result is: " + result);
  app
.add(newResultLabel);
 
return app;
}

様々なバリデーターがそれぞれ違う仕事をするために存在する。入力が数字、整数、メールアドレスでそれらが特定の長さ又は、指定された範囲の値であるように確認することができる。更に正規表現も使うことができる。またNOT演算もできる。 追記)バリデーターはクライント、サーバーハンドラーいずれでも動く。

バリデーターとクライアントハンドラーはとても相性がいい。例えば上の追加した例では、Addボタンは入力が数字でない場合は無効化しておくべきだ。そしてユーザーにボタンが無効化されている理由を表示したほうがいい。そうするためには、サーバーハンドラー、クライアントハンドラー、バリデーター3つの力をあわせて以下のようにする。

function doGet() {
 
var app = UiApp.createApplication();

 
// インプットボックスとボタンを作成
 
var textBoxA = app.createTextBox().setId('textBoxA').setName('textBoxA');
 
var textBoxB = app.createTextBox().setId('textBoxB').setName('textBoxB');
 
var addButton = app.createButton("Add").setEnabled(false);
 
var label = app.createLabel("Please input two numbers");

 
// 加算関数を呼ぶためのハンドラーを作成
 
// textBoxAとtextBoxB両方共数字の場合のみaddが呼ばれるように
 
//二つのバリデーターをハンドラーに加える
 
var handler =
    app
.createServerClickHandler('add').validateNumber(textBoxA).validateNumber(
      textBoxB
).addCallbackElement(textBoxA).addCallbackElement(textBoxB);

 
// 全ての入力が有効なものであるならばボタンが有効になるようなハンドラーを作成する
 
var onValidInput =
    app
.createClientHandler().validateNumber(textBoxA).validateNumber(textBoxB).forTargets(
      addButton
).setEnabled(true).forTargets(label).setVisible(false);

 
// textBoxAの無効な入力を赤くマークして、ボタンを無効化するハンドラーを作成する
 
var onInvalidInput1 =
    app
.createClientHandler().validateNotNumber(textBoxA).forTargets(addButton).setEnabled(
     
false).forTargets(textBoxA).setStyleAttribute("color", "red").forTargets(
      label
).setVisible(true);

 
// textBoxAの有効な入力を黒くマークするハンドラーを作成する
 
var onValidInput1 =
    app
.createClientHandler().validateNumber(textBoxA).forTargets(textBoxA).setStyleAttribute(
     
"color",
     
"black");

 
// textBoxBの無効な入力を赤くマークして、ボタンを無効化するハンドラーを作成する
 
var onInvalidInput2 =
    app
.createClientHandler().validateNotNumber(textBoxB).forTargets(addButton).setEnabled(
     
false).forTargets(textBoxB).setStyleAttribute("color", "red").forTargets(
      label
).setVisible(true);

 
//textBoxBの有効な入力を黒くマークするハンドラーを作成する
 
var onValidInput2 =
    app
.createClientHandler().validateNumber(textBoxB).forTargets(textBoxB).setStyleAttribute(
     
"color",
     
"black");

 
//ユーザがテキストボックスにタイプしたら呼ばれるように、すべてのハンドラーを加える
  textBoxA
.addKeyUpHandler(onInvalidInput1);
  textBoxB
.addKeyUpHandler(onInvalidInput2);
  textBoxA
.addKeyUpHandler(onValidInput1);
  textBoxB
.addKeyUpHandler(onValidInput2);
  textBoxA
.addKeyUpHandler(onValidInput);
  textBoxB
.addKeyUpHandler(onValidInput);
  addButton
.addClickHandler(handler);

  app
.add(textBoxA);
  app
.add(textBoxB);
  app
.add(addButton);
  app
.add(label);
 
return app;
}

function add(e) {
 
var app = UiApp.getActiveApplication();
 
var result =
    parseFloat
(e.parameter.textBoxA) + parseFloat(e.parameter.textBoxB);
 
var newResultLabel = app.createLabel("Result is: " + result);
  app
.add(newResultLabel);
 
return app;
}

スクリプトをスプレッドシートから実行するかサービスとして実行するか決める

スクリプトユーザーインターフェイスは、スプレッドシート又はサイト内から実行するか、サービスとして独立して実行させるか選択することができる。このセクションでは、それぞれの違いを説明し、どうやってサービスとしてユーザーインターフェイスを作るか教える。

ユーザーインターフェイスを表示するコードを書くときの心得

  • 独立したユーザーインターフェイスを表示するスクリプトには、HTML送信フォームのための、doGet(e)又は、doPost(e)関数が含まれていなければならない。
  • スプレッドシートから使用するユーザーインターフェイスを表示するには、doc.show(app)が必要。
  • doGet(e)関数は引数eを取り、ユーザーインターフェイスに引き渡す。

スクリプトを書いた後は、それをサービスとして発行します。発行する過程で、誰がそのスクリプトにアクセスできるのか設定します。

  • Google Apps ドメイン内において、あなた自身のみにアクセス権を与える、もしくはそのドメインの全員にアクセス権を与えるか選択して発行できる。
  • Google コンシューマアカウント内においては、あなただけか、それとも全世界誰でもアクセスできることにするか選んで発行できる。

Updating a Spreadsheet from the User Interface,にある例では、ユーザーインターフェイスはスクリプトが置かれているスプレッドシートから表示されている。

次のコードは、ユーザーインターフェイスをどうやって表示するかを決めるものだ。

function showGui() {
 
var doc = SpreadsheetApp.getActiveSpreadsheet();
// UiApp オブジェクトをappという名で作成する
 
var app = UiApp.createApplication().setTitle('my title');
//  ....必要なUIオブジェクトでappを埋めていく...
// ..で現在のスプレッドシートから表示する
  doc
.show(app);
}

独立サービスのユーザーインターフェイスを表示するための骨組みは以下のようになる。

function doGet(e) {
 
var app = UiApp.createApplication();
// .... UIオブジェクトで埋める...
 
return app;
}

下のはユーザーインターフェイスを表示する二つの方法の比較表

表示メソッドスクリプトは~として実行提供方法スクリプト可能範囲スクリプトアクセス可能範囲
スプレッドシート内から実行したユーザーとしてスプレッドシートへのアクセスからユーザーができることユーザーのアクセス権範囲
独立したサーブレットスクリプト管理者としてURL管理者ができること管理者のアクセス権範囲

サービスとしてスクリプトを発行する

スクリプトをサービスとして発行し、スプレッドシートから閲覧するには


  1. スクリプトエディタで, 公開 >サービスとして公開 をクリック

  2. 誰がアクセス権を持つか決める.
    • 自分自身のみに制限する場合  Allow only myself (your_email_address) to use this.
    • ドメイン内の他のユーザーに許可する場合 Allow only members of your_domain to invoke this service.
  3.  Enable Service をチェック
  4. URLをコピー
  5. 保存をクリック
  6. URLをブラウザのアドレスバーに貼り付ける そしてEnterを押す。スクリプトで作製したユーザーインターフェイスが表示される

次の説明は、すでにサイト上でスクリプトを作製したという前提である。

Apps スクリプトガジェットをグーグルサイトに挿入して、サービスとして発行する

  1. サイトに移動する
  2. 編集をクリック
  3. 挿入>Apps スクリプトガジェットをクリック。サイトのスクリプトのリストのダイアログボックスが表示される
  4. スクリプトを選んで選択をクリック。 Appsスクリプトガジェットを挿入のパネルが表示される
  5. アクセス権を設定
    • 自分自身のみに制限する場合  Allow only myself (your_email_address) to use this.
    • ドメイン内の他のユーザーに許可する場合 Allow only members of your_domain to invoke this service.
  6. ガジェットに枠をつけるなら、 最初のチェックボックスにチェック
  7. タイトルを付けたり変えたりするには、 2つ目のチェックボックスにチェック。必要なら新しいタイトルを付けられる
  8. オプションでディフォルトのガジェットの大きさを変えられる
  9. 保存をクリック
  10. サイトページで保存をクリック。ページにガジェットとスクリプトの出力が表示される

Google Apps ScriptとGoogle Web Toolkit

Google Apps スクリプトは。内部ではGoogle Web Toolkit(GWT)を使って、ユーザーインターフェイスの要素群を生成して、表示している。内側の仕組みまで詳しく知る必要はないが、もしGWTに馴染みがあるなら、Google Appsスクリプトにおいてどんなタイプのオブジェクトが利用可能で、どうsetterが働くかすでに知っていることと思う。例えば、GWT Grid クラスとGoogle Apps スクリプトにおいて、setWidgetメソッドを次のように呼ぶことができる。


setWidget(row, column, widget);

GWTとGoogle Appsスクリプトにおいて幾つかの構文上の違いがある。GWTはJavaの構文を受け継ぎ、Google AppsスクリプトはJavaScriptを受け継いでる。例えば、次にGWTのコードを示してみる。

Grid g = new Grid(rows, cols);
g
.setVisible(false);
g
.setHeight("100px");

次に同じ事をGoogle Apps スクリプトでやると

var g = app.createGrid(rows, cols);
g
.setVisible(false);
g
.setHeight("100px");

GWTオブジェクトは newXYZ を使うことによって作られる。同様の物が、Google Apps スクリプトでは、メソッドcreateXYZのようになる。






Google Apps Script












































































































































































































































































































































































































































































































































































































上は、左のスクリプトをスプレッドシート上で実行出来るようにして実行表示したもの。
















































































































































自分の環境でやったら下のような画面になった