2021年8月29日日曜日

GASで簡単0円な検索システムを作る。


栽培データを登録・検索するためのシステム(のテスト版)をGAS(Google Apps Script)で作ってみました。

備忘録として、以下作り方です。


① ベータベースの作成

データベースへのデータの登録は、Google フォームを使います。


登録するデータは、①作成者、②作成者URL(任意)、③作成者メールアドレス(任意)、④栽培地、⑤品目、⑥データ種別、⑦栽培データへのリンク、⑧備考(任意)です。

(テスト版なので、登録できる栽培地、品目、データ種別のリストは一部のみ。)


フォームから登録したデータが入ったスプレッドシート。これが、検索するデータベース(代わり)になります。


①~⑧のデータが、それぞれB~I列に入っています。今回、とりあえず動かすためのサンプルとして、7データほど入れました。

シート名は「cdb」としています(スクリプト内でこの名前で使います)。


② スクリプトファイルの作成

GASのスクリプトファイルを作成します。トップページを表示するためのdoGet関数と、検索結果を返すdoPost関数があります。

function doGet() {
  let htmlIndex = HtmlService.createTemplateFromFile("index");
  let result = "";
  htmlIndex.result = result;
  return htmlIndex.evaluate().setTitle("栽培データ検索システム");
}

function doPost(e) {
  let item = e.parameter.item;
  let typ = e.parameters.typ;
  let pref = e.parameter.pref;
  let kywd = e.parameter.kywd;
  let htmlResult = HtmlService.createTemplateFromFile("index");

  let cdbSt =  SpreadsheetApp.openById("スプレッドシートID").getSheetByName("cdb");
  let rowNum = [];
  
  if(item != "未選択") {
    let itemFinder = cdbSt.getRange("F2:F").createTextFinder(item).findAll();
    for(let i in itemFinder) {
      rowNum.push(itemFinder[i].getRow());
    }
  } else {
    htmlResult.result = "品目を選択してください。";

    return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
  }

  if(typ == null) {
    htmlResult.result = "データ種別を選択してください。";

    return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
  } else if(typ[0] != "全部") {
    let num = 0;
    const itemRowNum = rowNum.length;
    for(let x = 0; x < itemRowNum; x++) {
      let check = false;
      for(let y = 0; y < typ.length; y++){
        let typCheck = cdbSt.getRange(rowNum[x - num], 7).getValue().split(", ");
        for(let i = 0; i < typCheck.length; i++) {
          if(typ[y] == typCheck[i]) {
            check = true;
          }
        }
      }
      if(check == false) {
        let dlt = rowNum.indexOf(rowNum[x - num]);
        rowNum.splice(dlt,1);
        num++;
      }
    }
  }

  if(pref != "全国") {
    let prefFinder = cdbSt.getRange("E2:E").createTextFinder(pref).findAll();
    for(let i in prefFinder) {
      rowNum.push(prefFinder[i].getRow());
    }
    rowNum = rowNum.filter(function (x, i, self) {
      return self.indexOf(x) === i && i !== self.lastIndexOf(x);
    });
  }

  if(kywd != "") {
    let kywdFinder = cdbSt.getRange("B2:I").createTextFinder(kywd).findAll();
    for(let i in kywdFinder) {
      rowNum.push(kywdFinder[i].getRow());
    }
    rowNum = rowNum.filter(function (x, i, self) {
      return self.indexOf(x) === i && i !== self.lastIndexOf(x);
    });
  }

  rowNum.sort((a, b) => {return a - b;});
  
  let num = rowNum.length;
  let result = ["<table><tr><th>作成者</th><th>作成者URL</th><th>作成者メールアドレス</th><th>栽培地</th><th>品目</th><th>データ種別</th><th>栽培データへのリンク</th><th>備考</th></tr>"];
  for (let i = 0; i < num; i++) {
    result.push("<tr><td>");
    result.push(Array.prototype.concat.apply([], cdbSt.getRange(rowNum[i], 2, 1, 8).getValues()).join("</td><td>"));
    result.push("</td></tr>");
  }
  result.push("</table>");

  htmlResult.result = result.join("");

  return htmlResult.evaluate().setTitle("検索結果 - 栽培データ検索システム");
}
※ コードを一部修正しました。(2021-8-31)

15行目の「スプレッドシートID」は、書き換えてください。当該スプレッドシートURLの下記部分です。

https://docs.google.com/spreadsheets/d/ここの値をコピペ/edit#gid=0


③ HTMLファイルの作成

GASのHTMLファイルを作成します。ファイル名は「index.html」としています(スクリプト内でこの名前で使っています)。検索フォームと検索結果を表示します。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <center><h1><a href="ウェブアプリURL">栽培データ検索システム</a>(β版)</h1></center>
    <form method="post" action="ウェブアプリURL">
      <p><b><品目>*</b><br>
        <select name="item">
          <option value="未選択">選択してください…</option>
          <option value="シイタケ">シイタケ</option>
          <option value="キクラゲ">キクラゲ</option>
          <option value="エノキ">エノキ</option>
        </select>
      <p><b><データ種別></b><br>
       <input type="checkbox" name="typ" value="全部" checked="checked">全部
        <input type="checkbox" name="typ" value="温度">温度
        <input type="checkbox" name="typ" value="湿度">湿度
        <input type="checkbox" name="typ" value="照度">照度
      </p>
      <p><b><栽培地></b><br>
       <input type="radio" name="pref" value="全国" checked="checked">全国
        <input type="radio" name="pref" value="福島県">福島県
        <input type="radio" name="pref" value="茨城県">茨城県
        <input type="radio" name="pref" value="栃木県">栃木県
      </p>
      <p><b><キーワード></b><br>
        <input type="text" name="kywd" size="30">
      <p>
        <input type="submit" value="検索">
      </p>
    </form>
    <p>
      * 必須
    </p>
    <br>
    <p>
      <?!=result?>
    </p>
  </body>
</html>

7、8行目の「ウェブアプリURL」は、ウェブアプリケーションの公開後に取得できるウェブアプリのURLを記述します。


④ ウェブアプリケーションの公開と共有

作成したスクリプとHTMLトファイルを、ウェブアプリケーションとして公開、共有します。

「デプロイ」→「新しいデプロイ」から、

「説明」→「簡単検索システム」(適当に)
「次のユーザーとして実行」→「自分」
「アクセスできるユーザー」→「全員」

として、デプロイを実行。

「アクセスを承認」がまだの場合は、承認します。

ウェブアプリのURLが発行されますので、HTMLファイルにウェブアプリURLを記述し、「デプロイを管理」から「新バージョン」のデプロイを実行します。

プロジェクトの「共有」設定を、「リンクを知っている全員」に変更。

これで、ウェブアプリURLから検索トップページにアクセスして、検索ができるようになります。


⑤ 動かしてみる

動かしてみます。


品目は、選択必須。

データ種別は、チェックボックスで複数選択が可能となっているので、選択された品目のうちチェックされたデータ種別を1つでも含むものが検索されます。

栽培地は、ラジオボタンで1つ選択。キーワードは、入力されたキーワードを含むものを検索します。

また、品目が未選択、もしくはデータ種別が1つも選択されていないと検索されません。


上の写真の条件での検索結果。


こんな感じになります。


こちら↓から動かせます。


***

ということで、GASで作る簡易的な検索システムでした。

スプレッドシートの1シートに収まる程度の小規模なデータの運用であれば、けっこう十分なのではなかろうかと(厳密にはどの程度まで耐えられるのか分かりませんけども)。何よりGASの場合、サーバーの準備を考える必要がなく、維持費ゼロというのが素晴らしいですね。

先日、BloggerでTwitterカードを表示するために投稿ULRから画像のURLをリダイレクトするウェブアプリケーションを作ろうとして失敗しましたが、この検索システムはそこから転生したものなので、何でもやってみるものですね。

表示する情報を整理したり、URLはリンクにしたり等々、もう少し手を加えて、栽培データのオープンデータ化に活用していきたいと思います。


・追記(2022-7-9)

こちらの検索システムを活用して、請求書等の発行、及び受領システムなんかも作りました。