なんかの券をスプレッドシートとHTMLで管理する話

こんにちはAtsu1209です。
今回はなんかの券をHTMLとGASで管理できるようにした話を書いていきます。

# 今回使う方法
今回は 券に番号をつけてその番号をGASとHTMLで管理できるようにします。

# スプレッドシートの用意
早速用意していきます。
名前は`なんかの券管理シート`とでもしておきます。
| 1 | 2 |
|:-:|:-:|
|担当 |券番号 |
|例 太郎| 0  |

とりあえずこんなかんじです。

# GAS
GoogleSpreadSheetにはスクリプトを書くことができる拡張機能の`GoogleAppsScript`
というものがあります。
これを使って管理していきます。

```js:script.gs
function doGet(e) {
  const spredSheetByActive = SpreadsheetApp.getActive();
  const sheet = spredSheetByActive.getActiveSheet();
  
  // パラメータ 'num' で送られてきた番号があるかをチェック
  const numParam = e.parameter.num;  // パラメータ 'num' の値
  const dataRange = sheet.getRange(1, 2, sheet.getLastRow(), 1).getValues(); // B列の値を取得
  
  let found = false;
  
  // B列をループしてパラメータ 'num' の値を探す
  for (let i = 0; i < dataRange.length; i++) {
    if (dataRange[i][0] == numParam) {
      // 該当する番号が見つかった場合、その行の取り消し線の状態を確認
      const row = i + 1;  // 行番号は配列のインデックス+1
      const range = sheet.getRange(row, 1, 1, sheet.getLastColumn());
      
      // 取り消し線がすでに引かれているか確認
      if (range.getFontLine() === "line-through") {
        return HtmlService.createHtmlOutput("使用済みです");  // すでに棒線がある場合は "使用済みです" を返す
      } else {
        // 棒線が引かれていない場合は棒線を引き、セルの背景色を赤に設定
        range.setFontLine('line-through');
        range.setBackground('red');
        found = true;
        return HtmlService.createHtmlOutput("使用しました");
      }
    }
  }
  
  if (!found) {
    // 番号が見つからなかった場合は "そのコードは見つかりませんでした" を返す
    return HtmlService.createHtmlOutput("そのコードは見つかりません");
  }
}
```
デプロイURLを通じでHTMLから送られてきた数字がシートの中にあるかないかを判断して
あった場合はセルの背景色を赤にして線を引くようにしました。
もし数字がない場合は`return HtmlService.createHtmlOutput`で
`そのコードは見つかりません`を返しています。

### デプロイ
手順は`デプロイ>新しいデプロイ>歯車マーク>ウェブアプリ>デプロイ` です。
デプロイURLをコピーしておきます。

# HTML
次はなんかの券を使用できるようにHTMLを書きます。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>なんかの券を使用する</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f4f4f9;
        }

        form {
            background-color: #fff;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
            max-width: 400px;
            width: 100%;
        }

        form h3{
            color: #4CAF50;
            text-align: center;
        }

        input[type="number"] {
            width: 100%;
            padding: 12px;
            margin: 15px 0;
            border: 1px solid #ccc;
            border-radius: 8px;
            font-size: 16px;
            box-sizing: border-box;
            transition: border-color 0.3s;
        }

        input[type="number"]:focus {
            border-color: #4CAF50;
            outline: none;
        }

        button {
            background-color: #4CAF50;
            color: white;
            padding: 12px 0;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 18px;
            width: 100%;
            transition: background-color 0.3s;
        }

        button:hover {
            background-color: #3e8e41;
        }

        button:focus {
            outline: none;
        }

        @media (max-width: 600px) {
            form {
                padding: 20px;
            }

            h1 {
                font-size: 24px;
            }

            button {
                font-size: 16px;
            }
        }
    </style>
</head>
<body>
    <form id="form">
        <h3>なんかの券を使用する</h3>
        <input id="input" type="number" placeholder="券番号" autocomplete="off" required>
        <button type="submit">使用する</button>
    </form>
</body>
</html>

```
CSSは苦手なので一部ChatGPTにやらせました。
だれかCSS教えて

### JavaScript
情報をおくるJSを書きます。

```js:script.js
        const form = document.getElementById("form");

        form.addEventListener('submit', function(event) {
            event.preventDefault(); 
            const input = document.getElementById("input").value;
            window.open("デプロイURL?num=" + input);            
        });
```
`addEventListener`を使ってフォームが送信されたときに処理を行うようにしました。

# 最後に
もうちょい効率的なやり方や改善点があると思うのでコメントかなんかでご指摘いただけると嬉しいです。
ではまた次の記事で

#### 追記
前の記事でエラーが起きたので再掲です。