2026年1月12日月曜日

大問ごとに配点に対する得点率を10点満点で表すGAS (Google Apps Script)

以下はChatGPTに書いてもらった Google Apps Script のコードです。

  • 配点に対する得点率を10点評価するプログラムです。
  • 大問6問の得点「1得」から「6得」の合計点と評価点「1評」から「6評」を算出します。
  • グーグルフォームをトリガーに、
    • if文、for文でつくる、
    • 未入力は空欄(空文字)にして返す、
    • グーグルフォームの学校名先頭5文字をコード化する、など
    指示してつくってもらいました。

配点シートの形式

配点は、同一スプレッドシート内の別シート「配点」で、次のような形式で管理しています。

コード 1配 2配 3配 4配 5配 6配
26A01 25 35 40
26A02 17 27 32
26A03 8 10 6 10 10 12
26A04 10 11

※ 配点が空欄の大問は、その問題が存在しない、または評価対象外として扱い、評価(◯評)は空欄になります。

function onFormSubmit(e) {
  const sheet = e.range.getSheet();
  const row = e.range.getRow();
  const ss = sheet.getParent();

  // ===== 列番号(決め打ち)=====
  const keyCol = 3;          // フォーム選択肢(長い文字列)
  const scoreStartCol = 5;   // 1得
  const scoreCount = 6;      // 1得〜6得
  const totalCol = 11;       // 合計
  const evalStartCol = 12;   // 1評

  // ===== キー取得(先頭5文字をコード化)=====
  const raw = sheet.getRange(row, keyCol).getValue();
  if (!raw) return;

  const code = String(raw).trim().slice(0, 5); // 例: "26A01"

  // 形式チェック(事故防止)
  if (!/^\d{2}[A-Z]\d{2}$/.test(code)) return;

  // ===== 配点シート取得 =====
  const haitenSheet = ss.getSheetByName("配点");
  if (!haitenSheet) throw new Error("配点シートが見つかりません");

  const haiten = haitenSheet.getDataRange().getValues();

  // ===== コード → 配点行(VLOOKUP相当)=====
  let haitenRow = null;
  for (let i = 1; i < haiten.length; i++) {
    if (haiten[i][0] === code) {
      haitenRow = haiten[i];
      break;
    }
  }
  if (!haitenRow) return; // 配点未登録なら何もしない

  // ===== 得点取得(1得〜6得)=====
  const scores = sheet
    .getRange(row, scoreStartCol, 1, scoreCount)
    .getValues()[0]
    .map(v => Number(v) || 0);

  // ===== 合計(単純合計)=====
  const total = scores.reduce((s, v) => s + v, 0);
  sheet.getRange(row, totalCol).setValue(total);

  // ===== 評価(1評〜6評:10点換算)=====
  const evals = [];

  for (let i = 0; i < scoreCount; i++) {
    const score = scores[i];
    const maxScore = Number(haitenRow[i + 1]); // B列=1配 → i+1

    if (!maxScore || score === 0) {
      evals.push(""); // 未入力・配点なしは空欄
    } else {
      evals.push(Math.floor((score / maxScore) * 10));
    }
  }

  sheet
    .getRange(row, evalStartCol, 1, scoreCount)
    .setValues([evals]);
}

このコードについてコメントください。