2024年10月15日 星期二

Google Apps Script:Google 試算表 - 班級抽籤+排序記錄

 學校辦理營隊時,想要抽籤讓學生先後上台分享,
但目前的抽籤平台都只能抽學生姓名,最後還是需要自行登記排序,
感覺有點沒那麼便利,於是想看看是否能運用 Gemini 幫忙把這個想法實現。
結果就有這支 Apps Script 啦!如果有需要的可以自行下載運用!!


這次的想法:
1.抽籤前詢問想一次抽幾個
2.抽到後標註底色
3.登記抽籤順序
4.中獎後不再重複抽籤

👉👉 範本下載 👈👈



🎯 將下方程式複製到 - 擴充功能 - Apps Script

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('🎁抽獎')
    .addItem('🎁抽獎', 'showPrompt')
    .addItem('🗑️清除中獎', '清除中獎')
    .addToUi();
}

function showPrompt() {
  var ui = SpreadsheetApp.getUi();
  var result = ui.prompt(
    '請輸入要抽取的人數',
    ui.ButtonSet.OK_CANCEL);

  var button = result.getSelectedButton();
  var text = result.getResponseText();
  if (button == ui.Button.OK) {
    var numWinners = parseInt(text);
    if (isNaN(numWinners) || numWinners <= 0) {
      ui.alert("請輸入有效的抽獎人數!");
      return;
    }
    抽獎(numWinners);
  } else if (button == ui.Button.CANCEL) {
    // User clicked "Cancel".
  } else if (button == ui.Button.CLOSE) {
    // User clicked X in the title bar.
  }
}

function 抽獎(numWinners) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();

  // 取得所有參與者資料
  var range = sheet.getRange(2, 1, lastRow - 1, 5); // 從第二列開始取 A到E欄位
  var values = range.getValues();

  // 從隱藏欄位(假設為 F 欄)讀取已中獎者索引
  var wonIndexes = sheet.getRange(2, 6, lastRow - 1).getValues().flat().filter(index => index !== "");

  // 如果未中獎者數量小於要抽取的人數
  if (values.length - wonIndexes.length < numWinners) {
    SpreadsheetApp.getUi().alert("未中獎者人數不足!");
    return;
  }

  // 抽取指定人數的中獎者
  var winners = [];
  for (var i = 0; i < numWinners; i++) {
    var randomIndex;
    do {
      // 產生隨機數,範圍為 0 到未中獎者總數 - 1
      randomIndex = Math.floor(Math.random() * values.length);

      // 檢查 wonIndexes 中是否已包含該列的完整資料
      var formattedNumber = ("00" + values[randomIndex][1]).slice(-3); // 將 B 欄數值格式化為帶前導零的文字
      var targetString = `${randomIndex + 2} - ${values[randomIndex][0]} ${formattedNumber} ${values[randomIndex][2]}`;
    } while (wonIndexes.includes(targetString));

    // 標記中獎者
    var winnerRow = randomIndex + 2; // +2 是因為資料從第二列開始
    sheet.getRange(winnerRow, 4).setValue("中獎");

    // 設定 A、B、C、D 欄儲存格背景顏色為黃色
    sheet.getRange(winnerRow, 1, 1, 4).setBackground("yellow");

    // 將中獎者姓名加入 winners 陣列,以空格分隔各欄位,B 欄使用 formattedNumber
    winners.push([values[randomIndex][0], formattedNumber, values[randomIndex][2], values[randomIndex][3]].join(" "));

    // 在 F 欄記錄「索引數字 - A欄資料 B欄資料 C欄資料」
    wonIndexes.push(`${winnerRow} - ${values[randomIndex][0]} ${formattedNumber} ${values[randomIndex][2]}`);
  }

  // 將已中獎者索引儲存到隱藏欄位(F 欄)
  sheet.getRange(2, 6, wonIndexes.length).setValues(wonIndexes.map(index => [index]));

  // 顯示中獎者資訊
  var message = "恭喜以下 " + numWinners + " 位中獎:\n" + winners.join("\n");
  SpreadsheetApp.getUi().alert(message);
}

function 清除中獎() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  sheet.getRange(2, 4, lastRow - 1).setValue(""); // 清除 D 欄「中獎」標記
  sheet.getRange(2, 1, lastRow - 1, 4).setBackground(null); // 清除 A、B、C、D 欄背景顏色
  sheet.getRange(2, 6, lastRow - 1).clearContent(); // 清除 F 欄已中獎者索引
}

快來試試吧~~




沒有留言:

張貼留言

歡迎大家一起留言討論!