【GAS】モーダルに入力したデータに対応したセルの値を取得する方法を実例で解説|withSuccessHandlerの使い方(AppScript,簡単,わかりやすい)

AppScript appscript GAS-prograshi(プロぐらし)-kv AppScript
記事内に広告が含まれていることがあります。

Google App Script(GAS)では、ユーザーに入力をしてもらうモーダルを表示することができます。

そして、モーダルに入力したデータに基づいて、スプレッドシートの中の該当するデータを引っ張ってきて表示することもできます。

ここではその方法について解説しています。


どんなことができるのか?

例えば、メニューの中にカスタムメニュー「プログラム」を作成し、その中の「データ取得」をクリックします。


すると入力ボックスがあるモーダルが表示されます。


この中に、データを見たいセル番号を入力し、ボタンをクリックします。


すると、モーダルの中に取得してきた結果を表示してくれます。




作成方法(コードとファイル)

GASでHTMLを指定してダイアログを作成するには、HTMLファイルとそれを呼び出す.gsファイルを作成する必要があります。

今回作成するのは以下の2つのファイルです。

作成するファイル
  1. メニューバー.gs
  2. modal.html



それぞれのファイルのコードは以下になります。

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu('プログラム');
  menu.addItem('データ取得', 'showDialog');
  menu.addToUi();
}

function showDialog() {
  var html = HtmlService.createHtmlOutputFromFile('modal')
      .setWidth(400)
      .setHeight(300);
  SpreadsheetApp.getUi()
      .showModalDialog(html, 'セル番号を入力してください(例: A1)');
}


function getCellValue(e) {
  let cell = e.inputData;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();

  let value = sheet.getRange( cell ).getValue(); 
  
  return value;
}


<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      .exec-btn {
        display: block;
        text-align: center;
        vertical-align: middle;
        width: 170px;
        padding: 10px;
        font-weight: bold;
        border-radius: 100vh;
        border-bottom: 7px solid #0686b2;
        background: #27acd9;
        color: #fff;
      }
      .exec-btn:hover {
        margin-top: 6px;
        border-bottom: 1px solid #0686b2;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <form>
      <input type="textbox" id="idName" size="20" name="inputData">
      <br><br>

      <input type="button" value="セルの値を取得"
             onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
             class = "exec-btn"
      />
      <br>

      <div id="output"></div>
    </form>
    
    
    <script>
      function onSuccess(cellVal) {
        var div = document.getElementById('output');
        var inputVal = document.getElementById('idName').value;
        div.innerHTML = inputVal + 'セルの値:' + cellVal;
      }
    </script>
  </body>
</html>


メニューを追加する方法

スプレッドシートにメニューを追加する関数は以下です。

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu('プログラム');
  menu.addItem('データ取得', 'showDialog');
  menu.addToUi();
}

これで、「データ取得」というメニューをクリックすると「showDialog」という関数を実行します。

詳細については下記をご参考ください。


(参考)【GAS】メニューに自作した関数/プログラムを追加する方法を実例で解説


モーダルを開く|showModalDialogメソッド

function showDialog() {
  var html = HtmlService.createHtmlOutputFromFile('modal')
      .setWidth(400)
      .setHeight(300);
  SpreadsheetApp.getUi()
      .showModalDialog(html, 'セル番号を入力してください(例: A1)');
}

showDialog関数でモーダルを開く処理を行います。


HtmlService

一番最初の「HtmlService」とはAppScriptが提供しているクラスで、スクリプトによってHTMLなどのテキストコンテンツを作成するものです。

HtmlService.関数名()


createHtmlOutputFromFile

createHtmlOutputFromFileはHtmlServiceクラスに用意されたメソッドです。

HtmlService.createHtmlOutputFromFile(ファイル名)


引数にhtmlファイル名を指定することで、指定したファイルの内容のオブジェクト(HtmlOutputオブジェクト)を作成します。※ファイル名の.htmlは省略できます。


指定したファイルのHTML形式が正しくない場合はエラーを返します。


(参考)Class HtmlService: createHtmlOutputFromFile(filename)


setWidthとsetHight

HtmlOutputクラスのsetWidthとsetHightメソッドを使うと対象のHtmlOutputオブジェクトの横幅と高さを指定することができます。

HtmlOutputオブジェクト.setWidth(整数)
HtmlOutputオブジェクト.setHeight(整数)


注意点

setWidthとsetHightの引数は半角整数を記述します。pxなどの単位は不要です。

〇 setWidth(200)
✕ setWidth(200px)

指定した数値の単位は自動的にピクセルとなります。



SpreadsheetApp

次に、スプレッドシートにサイドバーを実装するコードを見ていきます。

SpreadsheetApp.getUi().showModalDialog(html, 'セル番号を入力してください(例: A1)');


一番最初に出てくる「SpreadsheetApp」はGASでスプレッドシートを操作するためのクラスです。様々な便利なメソッドが用意されています。


getUi

getUiメソッドはSpreadsheetAppクラスに用意されたメソッドで、ユーザーインターフェースのインスタンスを取得します。

これで実際に表示されているスプレッドシートの画面を操作することがっできるようになります。引数は不要です。


(参考)SpreadsheetApp: getUi


showModalDialog

スプレッドシート上にモーダルを表示するにはshowModalDialogメソッドを使います。

基本構文は以下のようになります。

ユーザーインターフェース.showModelessDialog(HtmlOutputオブジェクト, タイトル) 


ユーザーインターフェースとは、スプレッドシートであれば「SpreadsheetApp.getUi()」とします。

HtmlOutputオブジェクトとは、htmlファイルをオブジェクト化したものです。

なお、タイトルはモーダルの左上に表示される文字列で省略不可です。


(参考)AppScript > showModeless


以上でモーダルが完成します。



データ処理の流れ

続いて、モーダルの入力ボックスにセル番号を入力し、ボタンをクリックすると、スプレッドシートの対象のセルの値を取得してきてモーダル上に返す処理を行います。

まずはHTMLファイル上の処理が走ります。

  <body>
    <form>
      <input type="textbox" id="idName" size="20" name="inputData">
      <br><br>

      <input type="button" value="セルの値を取得"
             onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
             class = "exec-btn"
      />
      <br>

      <div id="output"></div>
    </form>
    
    
    <script>
      function onSuccess(cellVal) {
        var div = document.getElementById('output');
        var inputVal = document.getElementById('idName').value;
        div.innerHTML = inputVal + 'セルの値:' + cellVal;
      }
    </script>
  </body>


onclickメソッド

コードの中でも最初に動くのがボタンクリック時のonclickメソッドです。

<input type="button" value="セルの値を取得"
  onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
 class = "exec-btn"
/>

 ↓ onclickで実行する処理

google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);

まずgetCellValueを実行し、その結果が問題なければonSuccessという関数を実行します。

以下でもう少し細かく解説します。



google.script.runとは何か?

onlickイベントで作動する処理の一番最初にgoogle.script.runがあります。

これはAppScriptで作成したHTMLファイルの中でAppScriptを実行できるとても便利な処理です。


App Scriptではファイルの種類として「スクリプト」と「HTML」を作成することができます。


このHTMLファイルの中で使う処理になります。


(参考)クラス google.script.run(クライアントサイド API)



withSuccessHandler

withSuccessHandlerはgoogle.script.runクラスの中で使えるメソッドです。

以下のように使用します。

google.script.run.withSuccessHandler(HTMLファイル上の関数).先に実行する関数

withSuccessHandlerを使うと、後ろに指定したサーバーサイド関数(AppScriptファイルの関数)が正常に返された場合に実行するコールバック関数(HTMLファイル上の関数)を設定することができます。

簡単に言うと、先に用意されている関数がエラーなく実行されたら次にこの処理を行うということです。

つまり、先にgetCellValue(this.parentNode)を実行し、その結果を受けてwithSuccessHandlerの処理を行うという処理になります。


(参考)クラス google.script.run: withSuccessHandler



this.parentNode

getCellValueを実行するときに、引数で「this.parentNode」を指定しています。

getCellValue(this.parentNode)


これは、現在のノードの親ノードを取得しています。parentNodeはセレクタに対して使用します。

セレクタ.parentNode

セレクタが「this」の場合、現在の要素を指します。

なお、親要素が存在しない場合はbodyを取得します。


今回の場合、parentNodeを指定しているinputタグの親要素はformタグになります。

    <form>
      <input type="textbox" id="idName" size="20" name="inputData">
      <br><br>

      <input type="button" value="セルの値を取得"
             onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
             class = "exec-btn"
      />
      <br>
      <div id="output"></div>
    </form>


getCellValue(this.parentNode)

ノードの要素.name属性の値(e.inputData)

先に実行するgetCellValue(this.parentNode)はAppScriptに記述してある処理になります。

function getCellValue(e) {
  let cell = e.inputData;

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();

  let value = sheet.getRange( cell ).getValue(); 
  
  return value;
}


引数で渡された親ノード(this.parentNode)が変数eに入ります。

  <form>
      <input type="textbox" id="idName" size="20" name="inputData">
      <br><br>

      <input type="button" value="セルの値を取得"
             onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
             class = "exec-btn"
      />
      <br>

      <div id="output"></div>
    </form>


ポイントは入力ボックスとして表示しているinputタグです。

<input type="textbox" id="idName" size="20" name="inputData">


name属性に「inputData」とすることで、入力したデータのプロパティ名が「inuptData」入力値が値として格納されています。

このため、「e.inputData」とすることで、inputボックスに入力されたデータを取得できます。ここでは取得した値を変数「cell」に入れています。

let cell = e.inputData;


セルの値を取得して返す

 const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();

  let value = sheet.getRange( cell ).getValue(); 
  
  return value;


SpreadsheetApp.getActiveSpreadsheetで現在のスプレッドシートを取得し、ssという変数に入れます。

ss.getActiveSheetで現在のシートを取得します。

sheet.getRange( cell ).getValue()でinputボックスに入力したセルの値を取得します。

最後にreturnで結果を返します。


withSuccessHandlerの引数で指定した関数の実行(onSuccess関数)

getCellValue関数の処理が終わったら、withSuccessHandlerの引数で指定した関数onSuccessを実行します。

  <body>
    <form>
      <input type="textbox" id="idName" size="20" name="inputData">
      <br><br>

      <input type="button" value="セルの値を取得"
             onclick="google.script.run.withSuccessHandler(onSuccess).getCellValue(this.parentNode);"
             class = "exec-btn"
      />
      <br>

      <div id="output"></div>
    </form>
    
    
    <script>
      function onSuccess(cellVal) {
        var div = document.getElementById('output');
        var inputVal = document.getElementById('idName').value;
        div.innerHTML = inputVal + 'セルの値:' + cellVal;
      }
    </script>
  </body>


onSuccess関数はHTMLファイルのscriptタグの中に記述してあります。

    <script>
      function onSuccess(cellVal) {
        var div = document.getElementById('output');
        var inputVal = document.getElementById('idName').value;
        div.innerHTML = inputVal + 'セルの値:' + cellVal;
      }
    </script>


戻り値を引数として受けとる

onSuccess(cellVal)の引数「cellVal」には、getCellValue関数のreturnの戻り値が入ります。

つまり、変数cellValの値は指定したセルの値になります。


document.getElementById

次にdocument.getElementByIdメソッドを使って、指定したIDをHTMLエレメントとして取得し、変数divに格納します。

var div = document.getElementById('output');


ここで取得しているid=”output”は以下のタグになります。

<div id="output"></div>

現時点ではid属性以外何もありません。


入力フォームの値を取得する|document.getElementById(‘id属性名’).value

入力フォームの値を取得するには.valueを使います。「.value」は対象のエレメントの中のvalueプロパティの値を取得するための記述です。

エレメント.value


ここではエレメントの指定にgetElementByIdメソッドを使い、ID名で指定しています。

document.getElementById('id属性名').value


innerHTML

最後にinnerHTMLを使って、指定したエレメントのHTML要素を変更しています。

エレメント.innerHTML = 変更後の文字列


ここではdocument.getElementById('output');で取得したdivタグに対して値を指定しています。

div.innerHTML = inputVal + 'セルの値:' + cellVal;

inputValはinputボックスに入力された値、cellValはスプレッドシート上で対象のセルに入力されている値になります。


対象のdivタグが以下のように変化します。

<div id="output"></div>

 ↓ innerHTML実行後

<div id="output">[入力値]セルの値: [スプレッドシートのセルの値]</div>


これにより、モーダル上にスプレッドシートから取得してきた値が表示されます。


以上で解説は終わりです。

お疲れさまでした^^

タイトルとURLをコピーしました