You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google Sheets App Script中循环定位数组符合条件的下一项

问题:Google Script垃圾值日轮换功能跳过休假用户的实现

需求背景

  • 开发每周六自动轮换垃圾值日的功能
  • 已实现功能:点击按钮可跳过当前轮次,自动分配列表下一位用户
  • 待解决问题:当用户状态标记为⛔ Vacation(休假)时,轮换需自动跳过该类用户

现有代码

var housemates = [
["User 1","✅ Active",false],
["User 2","⛔ Vacation",false],
["User 3","⛔ Vacation",true],
["User 4","✅ Active",false],
["User 5","✅ Active",false],
["User 6","✅ Active",false]
]
// 0. 获取所有用户列表
function getUsers(){
  var sheet = SpreadsheetApp.getActive();
  var range = sheet.getRangeByName("housemates");
  var values = range.getValues();

  return values;
}

// 1. 查找当前值日用户
function getCurrentUser(){
  var values = getUsers(); // 完整用户列表
  const columnIndex = 2; // 标记当前用户的列索引
  const matchText = true;

  let currentUser = values.findIndex(row => row[columnIndex] === matchText);

  return currentUser;
}

//2. 计算下一位值日用户
function getNextUser(){
  var values = getUsers(); // 未过滤的用户列表
  var currentUser = getCurrentUser(); // 当前值日用户索引

   if (currentUser < values.length - 1){
    var nextUser = currentUser + 1;
  }

  else {
     var nextUser = 0;
  }

  return nextUser;
}

//3. 提交按钮点击事件
function onSubmit() {
  var sheet = SpreadsheetApp.getActive();
  var range = sheet.getRangeByName("housemates");
  var values = getUsers(); // 未过滤的用户列表
  var currentUser = getCurrentUser(); // 当前值日用户索引
  var nextUser = getNextUser(); // 下一位值日用户索引

  values.forEach(function (row, index) {
    if(index != nextUser) {
      values[index][2] = false;
    }  
    else{
      values[index][2] = true;
    }
  });
  range.setValues(values);
  }

// 4. 确认弹窗
function confirm() {
  var range = SpreadsheetApp.getActive().getRangeByName("housemates");
  var values = range.getValues();

  const currentUser = getCurrentUser();
  const currentUserName = values[currentUser][0];
  
  const nextUser = getNextUser(); // 下一位值日用户索引
  const nextUserName = values[nextUser][0];

  var ui = SpreadsheetApp.getUi();

  const title = `⚠️ 确认切换?`;
  const description = `确认后,${nextUserName} 将成为下一位值日用户。`;
  var response = ui.alert(title, description, ui.ButtonSet.YES_NO);

  if (response == ui.Button.YES){
    onSubmit();
  }

  else if (response == ui.Button.NO){
    return;
  }
}

解决方案

核心修改getNextUser函数,实现循环查找有效用户的逻辑,同时补充边界异常处理,避免所有用户休假时的程序错误。

1. 修改getNextUser函数

//2. 计算下一位值日用户
function getNextUser(){
  var values = getUsers();
  var currentUser = getCurrentUser();
  var totalUsers = values.length;
  var nextUser = currentUser;

  // 循环查找下一位Active用户,最多遍历所有用户一次避免死循环
  do {
    nextUser = (nextUser + 1) % totalUsers;
    // 检查当前用户状态是否为Active
    if (values[nextUser][1] === "✅ Active") {
      return nextUser;
    }
  } while (nextUser !== currentUser);

  // 遍历一圈未找到有效用户,返回-1标记异常
  return -1;
}

2. 优化confirm函数,增加异常提示

// 4. 确认弹窗
function confirm() {
  var values = getUsers();
  const currentUser = getCurrentUser();
  const currentUserName = values[currentUser][0];
  
  const nextUser = getNextUser();
  
  var ui = SpreadsheetApp.getUi();

  // 处理所有用户都休假的异常情况
  if (nextUser === -1) {
    ui.alert("⚠️ 错误", "所有用户都处于休假状态,无法分配值日!", ui.ButtonSet.OK);
    return;
  }

  const nextUserName = values[nextUser][0];
  const title = `⚠️ 确认切换?`;
  const description = `确认后,${nextUserName} 将成为下一位值日用户。`;
  var response = ui.alert(title, description, ui.ButtonSet.YES_NO);

  if (response == ui.Button.YES){
    onSubmit();
  }
}

3. 优化onSubmit函数,适配异常情况

//3. 提交按钮点击事件
function onSubmit() {
  var sheet = SpreadsheetApp.getActive();
  var range = sheet.getRangeByName("housemates");
  var values = getUsers();
  var nextUser = getNextUser();

  // 异常情况直接终止并提示
  if (nextUser === -1) {
    SpreadsheetApp.getUi().alert("⚠️ 错误", "所有用户都处于休假状态,无法分配值日!", ui.ButtonSet.OK);
    return;
  }

  values.forEach(function (row, index) {
    values[index][2] = index === nextUser;
  });
  range.setValues(values);
}

功能说明

  • 修改后的getNextUser会从当前用户的下一位开始循环遍历,直到找到第一个状态为✅ Active的用户
  • 增加遍历次数限制,避免出现死循环
  • 当所有用户都处于休假状态时,会弹出提示告知无法分配值日,避免程序出错
  • 简化onSubmit中的赋值逻辑,代码更简洁高效

内容的提问来源于stack exchange,提问作者Designying

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:34:50