【GAS】Webアプリでスプレッドシートの内容からドロップダウンを作成する方法

GAS

どうもcoto.です。
今回はGASで作成したウェブアプリにスプレッドシート内のデータを利用したドロップダウンを設置する方法をご紹介します。

必要なデータとコード

アプリ公開方法の詳細は割愛しますが、GASを利用したウェブアプリを作るときはコードを書くためのgsファイルとユーザーに表示するためのhtmlファイルが必要になります。

今回は表示する内容の元になるスプレッドシートのシート名を「test」、gsファイルを「コード.gs」、htmlファイルを「index.html」としています。

スプレッドシートの内容

以下のようにドロップダウンに入るデータを作成します。1行ごとでドロップダウン中の1つの選択肢になるイメージです。今回はB~Dの3列を作りましたが、1列、もしくは4列以上でも問題ありません。

ドロップダウンの中身になるデータリスト

内容はなんでも良かったんですが、顧客をデータベースから呼び出すような使い方を想定して作成してみました。当然ですが氏名等は架空のものです。

GAS(gs)側のコード

実際に使用するときは9行目のスプレッドシートIDを書き換えて使ってください。

//▼Webアプリを表示するための関数▼
function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}


//▼ドロップダウンの中身になるデータを取得▼
function dropData(){
  const ss      = SpreadsheetApp.openById("1Myi1VVx2AY●●●●●●●●●●●●●●●●");     //スプレッドシートIDを指定
  const sheetDB = ss.getSheetByName("test");                   //シートtestを開く
  var   list    = sheetDB.getRange("B3:D7").getValues();       //リストを取得

  //取得データを返す
  return JSON.stringify(list);
}

コード.gsには上記のように最低限2つの関数が必要です。

HTML側のコード

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">

    <script type="text/javascript">  

  //▼ドロップダウンの一覧データを取得する▼
  google.script.run.withSuccessHandler(onSuccess).dropData();  

  //▼取得したデータでドロップダウンを作る▼

   function onSuccess(list){   
      var data = JSON.parse(list);      //dataをJSONに変換
      var datalength = data.length;     //dataの要素数を定義
  
      //selectタグの頭を入れる
      var html =  "";
      html += "<select title='顧客を選択する'><option>顧客を選択して下さい</option>";
  
      //ドロップダウンの中身の生成
      for(var i = 0;i<datalength;i++){   //顧客を1人ずつドロップダウンにいれていく。要素数分繰り返し、次が空白になったら脱出
       if(data[i] == ""){
          break;                         
         }

      //オプション項目を追加
       html += "<option>" + data[i] + "</option>"
      }
  
      //selectタグ終わりを入力
       html += '</select>';
    
      //ドロップダウンメニューを設置する
       document.getElementById("drop").innerHTML = html;  //以下のbody内のidがdropの部分にここで作ったhtmlを追記
    }

  </script>

  </head>
  <body>

      <!-- ドロップダウンを設置 -->
      <div id="drop">
      </div>
    
  </body>
</html>

結果

このコードでウェブアプリを起動すると、

ウェブアプリ上に表示されたドロップダウン

こんな感じにドロップダウンが表示され、スプレッドシートに作った表の内容が反映されます。列ごとにカンマで区切られて並べられます。

機能的には問題ないですが、このままだと見た目がアレなのでCSSなどでスタイルをかっこよくしてあげてください。

解説

コード内になるべくこまかくコメントアウトを入れたのでお分かりかと思いますが補足をすると、

function doGet はドロップダウン云々関係なくGoogle App Scriptのウェブアプリを作るときには必要な部分です。(ここをいじくるとhtml同士のページ遷移などが行えます)

HTML側9行目の google.script.run.withSuccessHandler(onSuccess).dropData();  の部分は、
「ウェブアプリ(index.html)が開かれたらコード.gsのdropData()を実行し、成功したらindex.htmlのonSuccess()に戻すよ」の意味です。

データ数が変わる場合のコード

もしデータ数が固定のものではなく、場合によって増減するなら以下のように変更すると良いかもしれません。
testシートの中でデータがあるセルの一番下の行を取得してその行までのリストを作成するコードです。

function dropData(){
  const ss      = SpreadsheetApp.openById("1Myi1VVx2AY●●●●●●●●●●●●●●●●");     //スプレッドシートIDを指定
  const sheetDB = ss.getSheetByName("test");                   //シートtestを開く
  const rowDB   = sheetDB.getLastRow();               //シートtestの最終行を取得
  var   list    = sheetDB.getRange("B3:D"+rowDB).getValues();  //リストを取得

  //取得データを返す
  return JSON.stringify(list);
}

注意

このコードでは、データをいったんJSON形式(?)に変換してコード.gsとindex.htmlの間をやり取りさせるので表示前にローディング時間が入ります。

検証はしてないですがHTML側のほうでデータを取得(sheetDB.getRange(“B3:…の部分)したほうがおそらく速くなります。

よりスピード感を求める場合はお試しください。

御託

今回のは仕事の一環で作ったコードです。上司がね。やりたいっていうんですよ。アレとかコレとか…。やれと言われればやりますけども。

なんというかまあ、ドロップダウン作ったらそれで終わりなんてことはもちろんないですよね。次回はドロップダウンで選択したものをアレコレするコードを紹介できたらなーなんで思っています。

あとご紹介しているコードはかなり簡略化していますので、セキュリティ諸々は各環境に合わせて工夫をお願いします。

コメント

  1. 初めてWEBアプリを作成し、HTML側のコードを勉強中の初心者です。
    教えていただきたいのですが、プルダウンで選択できる表示まではできました。
    この選択した結果をスプレッドシートの記録させたいのですが、どの様に記述すればよろしいのでしょうか?お忙しいところ申し訳ございません。お時間あるときご指導お願いいたします。

    • コメントありがとうございます。私がよく使うのはボタンの設置です。
      流れとしては、
      ① ドロップダウンの隣にボタンを設置(html側)
      例:input type=”button” value=”記録” onclick=”Btn1()” class=”btn1″

      ② ボタン押下するとドロップダウンの選択値をgs側に投げる関数をscriptタグ内に記述(html側)
      例: google.script.run.withSuccessHandler(viewComm).insertData(txt);
         これは③で記述する関数insertDataにtxtを投げて、処理が完了したら、html側に設置した関数viewCommに返してねという指示になります。これを使うことで、スプレッドシートへの記録成功→webアプリ上で「記録しました」などのメッセージを表示といった挙動が可能になるのでユーザビリティ的に親切です。
         ただgs側に投げるだけでよければ google.script.run.insertData(txt); でも動きます。 

      ③ ②の値を受け、スプレッドシートに記録する関数をに記述(gs側)
       ここで記述する関数名はもちろん②で指定するもの(例ではinsertData)と一致していなければならないので注意してください。

      になります。実際に動く例をお見せできず残念ですが、参考にしていただければ幸いです。

      • 早速のご指導ありがとうございました。心より感謝します。まずは内容を確認して作成してみたいと思います。