GAS スプレッドシートにUIを追加

目次
  1. Uiクラス
  2. メニュー
  3. ダイアログ
  4. カスタムインターフェイス
    1. カスタムダイアログ
    2. カスタムサイドバー
  5. ダイアログでGoogle Pikerを表示する(ファイルを開く)

Uiクラス

メニュー・サイドバー・ダイアログなどの機能をスクリプトで追加できるようにします

Uiクラスはコンテナバインドスクリプトでのみ利用可能です
*例:スプレッドシートからスクリプトを開きます

onOpenでシンプルトリガーを設定します
onOpen(e) 関数はユーザーが「Googleドキュメント・Googleスプレッドシート・Googleスライド・Googleフォーム」のファイルを開いたときに実行されます

function onOpen() {
  const ui  = SpreadsheetApp.getUi();
  
}

メニュー

createMenu(caption)
caption :String メニューのラベル
*ドキュメントによると最上位のメニューは大文字にまたはサブメニューの最初の単語を大文字となっていますが日本語でも大丈夫でした
戻り値はMenuです
Menuをチェーンで繋ぐことができます

Menuクラス
*「functionName」はユーザーがアイテムを選択したときに呼び出す関数の名前

  • addItem(caption, functionName) :メニューにアイテムを追加します(戻り値はMenu)
  • addSeparator() : メニューに区切りを追加します(戻り値はMenu)
  • addSubMenu(menu) :メニューにサブメニューを追加します(戻り値はMenu)
  • addToUi() :ユーザーのインターフェース(スプレッドシート)にメニューを挿入します
function onOpen() {
const ui = SpreadsheetApp.getUi();
     ui .createMenu('My Menu')
      .addItem('Menu item', 'myFunction')
      .addSeparator()
      .addSubMenu(SpreadsheetApp.getUi().createMenu('sub-menu')
          .addItem('sub-menu1 item', 'secondFunction')
          .addItem('sub-menu2 item', 'thirdFunction'))
      .addToUi();
}

ダイアログ

ダイアログが開いている間にサーバー側のスクリプトを停止し、ユーザーがダイアログを閉じるとスクリプトが再開されます

alert(prompt):メッセージとOKボタン
alert(prompt, buttons):メッセージとボタンのセット
alert(title, prompt, buttons) :タイトルとメッセージとボタンセット
title: String ダイアログ ボックスの上に表示するタイトル
prompt :String ダイアログ ボックスに表示するメッセージ
buttons:ButtonSet ダイアログ ボックスの表示を設定するボタン

function onOpen() {
const ui = SpreadsheetApp.getUi();
const response = ui.alert('確認です', '続けますか?', ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) {
  //YESの時
  } else {
  //Noが押されたとき
  }
}

入力ダイアログボックス
prompt(prompt):メッセージとOKボタン
prompt(prompt, buttons):メッセージとボタンのセット
prompt(title, prompt, buttons):タイトルとメッセージとボタンセット

function onOpen() {
const ui = SpreadsheetApp.getUi();
const response = ui.prompt('タイトル', 'お名前は?', ui.ButtonSet.YES_NO);
 //getSelectedButton()
 //ユーザーがダイアログを閉じるためにクリックしたボタンを取得します
 //閉じるボタンをクリックした場合 Button.CLOSE を返します
if (response.getSelectedButton() == ui.Button.YES) {
   //  入力フィールドに入力したテキストを取得
   // response.getResponseText()
  } else if (response.getSelectedButton() == ui.Button.NO) {
  // Noが押されたとき
  } else {
  // 閉じるが押された時
  }
}

ui.ButtonSet

  • OK:OKボタン(閉じることができません)
  • OK_CANCEL :OK/キャンセルボタン(操作を続行または停止できます)
  • YES_NO :はい/いいえボタン。(はい/いいえで答える)
  • YES_NO_CANCEL:はい/いいえ/キャンセルボタン(はい/いいえで答えるか操作を停止)

カスタムインターフェイス

開いてもサーバー側スクリプトは停止されません

HTMLサービスを利用してカスタムダイアログ(クライアント側コンポーネント)を表示します
カスタムインターフェイス(クライアント側コンポーネント)は「 google.script API 」を使用してサーバー側スクリプトに対して非同期呼び出しを行います
プログラムからカスタムインターフェイスを「閉じる」には google.script.host.close() を呼び出します

カスタムダイアログ

showModalDialog(htmlOutput, title)
*モーダルダイアログは、ユーザーがダイアログ以外を操作できないようにします

function onOpen() {
   SpreadsheetApp.getUi() 
      .createMenu('Menu')
      .addItem('Modal', 'showModal')
      .addToUi();
}
function showModal() {
  const html = HtmlService.createHtmlOutputFromFile('index')
      .setWidth(200)
      .setHeight(100);
  SpreadsheetApp.getUi()
      .showModalDialog(html, 'My Modal');
}
<p>Hello world</p>
<input type="button" value="Close" onclick="google.script.host.close()" />

showModelessDialog(htmlOutput, title)
*モードレスのダイアログはユーザーはダイアログの背後のシートを操作できます

カスタムサイドバー

showSidebar(htmlOutput)

function onOpen() {
  SpreadsheetApp.getUi() 
      .createMenu('Menu')
      .addItem('Sidebar', 'showSidebar')
      .addToUi();
}

function showSidebar() {
  const html = HtmlService.createHtmlOutputFromFile('index')
      .setTitle('My Sidebar');
  SpreadsheetApp.getUi() 
      .showSidebar(html);
}
<p>Hello world</p>
<input type="button" value="Close" onclick="google.script.host.close()" />

ダイアログでGoogle Pikerを表示する(ファイルを開く)

「Googleドライブの既存のファイル」を選択したり「新しいファイル」をアップロードしたりできます

Googleドライブの既存ファイルを選択

ローカルファイルを選択

「Google Piker API」を使います
Google Cloud Platform(GCP)で「Google Piker API」を有効にしてAPI Keyを取得します

GASダイアログガイド:https://developers.google.com/apps-script/guides/dialogs#file-open_dialogs

  1. GCPで新しいプロジェクトを作成
  2. Google Piker APIを有効にします
  3. 認証情報を作成する画面からAPI Keyを作成します
  4. アプリケーションの制限を設定して保存をクリック
function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('ファイル選択')
      .addItem('ファイルを開く', 'fileloader')
      .addToUi();
}
function fileloader() {
  var html = HtmlService.createHtmlOutputFromFile('index')
      .setWidth(600)
      .setHeight(425)
  SpreadsheetApp.getUi().showModalDialog(html, 'ファイルの選択');
}
//Tokenを取得する
function getOAuthToken() {
  DriveApp.getRootFolder();
  return ScriptApp.getOAuthToken();
}
//エラーメッセージの表示
function messager(msg){
  var ui = SpreadsheetApp.getUi();
  ui.alert(msg);
}
<link href="https://ssl.gstatic.com/docs/script/css/add-ons.css" rel="stylesheet" />
<script src="https://apis.google.com/js/api.js"></script>
<script>
  var DEVELOPER_KEY = 'ここにAPI KEY';
  var DIALOG_DIMENSIONS = {width: 600, height: 425};
  var pickerApiLoaded = false;
  var origin = google.script.host.origin;
  //PickerAPI読み込みます
  gapi.load('picker', {'callback': function() {
    pickerApiLoaded = true;
  }});
  //サーバーからユーザーのOAuth2.0アクセストークンを取得してピッカーに渡す
  //ピッカーのダイアログを表示
  google.script.run.withSuccessHandler(createPicker).withFailureHandler(showError).getOAuthToken();
 
  //ダイアログを表示する
  function createPicker(token) {
    if (pickerApiLoaded && token) {
      //DocsUploadView.setParent(string):指定したフォルダにアップロード先を設定します
      //DocsUploadView().setIncludeFolders(true):アップロード先が選択できます
      var uploadView  = new google.picker.DocsUploadView().setParent( "アップロード先のフォルダID");
      //https://developers.google.com/drive/picker/reference#picker-builder   
      var picker = new google.picker.PickerBuilder()
          //Googleドライブの画像のみを表示して保存先のIDを表示する場合
          //.addView(google.picker.ViewId.DOCS_IMAGES)  
           .addView(uploadView)//新しいファイルをドライブにアップロードする場合
            .hideTitleBar()
            .setOAuthToken(token)
            .setOrigin(origin)
            .setLocale("ja")
            .setDeveloperKey(DEVELOPER_KEY)
            .setCallback(pickerCallback)
            .setSize(DIALOG_DIMENSIONS.width - 2,
                DIALOG_DIMENSIONS.height - 2)
            //https://developers.google.com/drive/picker/reference#feature
            .enableFeature(google.picker.Feature.NAV_HIDDEN)   
            .build();
      picker.setVisible(true);
    } else {
      showError('Pickerが表示できませんでした');
    }
  }
  //Callback(JSONエンコードされたdataオブジェクトを受け取ります)
  //ファイル選択時やキャンセル時の処理
  function pickerCallback(data) {
    if (data.action == google.picker.Action.PICKED) {
      var length = data.docs.length; 
      for(var i = 0;i<length;i++){
        var fileId = data.docs[i].id;
        var url = data.docs[i].url;
        var title = data.docs[i].name;   
      //ファイルへのリンクとIDを表示する
        document.getElementById('result').innerHTML +=
            `ファイル名: <a href="https://drive.google.com/file/d/${fileId}/view?usp=sharing" target="_blank">${title}</a>
            <br/>ID:${fileId}<br>`;
      }
    } else if (data.action == google.picker.Action.CANCEL) {
      google.script.run.messager("キャンセルされました。");
    }
  }
  //エラー表示用
  function showError(message) {
    document.getElementById('result').innerHTML = `Error:${message}`;
  }
</script>
<div id = "result"></div>