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

谷歌表格员工排班表转置需求:自定义公式或脚本方案咨询

嘿,我来帮你搞定这个排班表转置的问题!先给你两种实用方案:不用写代码的纯公式解法,以及更灵活的Google App Script自定义函数,你可以根据自己的需求来选。

方案一:纯公式解法(无需代码)

Google Sheets的新函数(比如LET、FLATTEN、SEQUENCE)可以轻松实现这个需求,不用依赖脚本。假设你的原始排班数据在Sheet1,第一行是班次表头(Shift A、Shift B…),从第二行开始每两行对应一天(第一行是日期,第二行是补充排班),可以用下面的公式生成所有员工的排班记录,再筛选特定员工的班次:

生成全量排班映射表

先在空白单元格输入这个公式,它会把所有日期、班次、员工对应起来:

=LET(
  rawData, Sheet1!A:E,
  // 提取所有日期(每两行取一次第一行的日期)
  dates, INDEX(rawData, SEQUENCE((ROWS(rawData)-1)/2, 1, 2, 2), 1),
  // 把每个日期重复两次,对应当天的两行排班
  repeatedDates, FLATTEN(ARRAYFORMULA(REPT(dates&"|", 2))),
  // 提取所有班次的员工数据并扁平化
  shiftAssignments, FLATTEN(INDEX(rawData, 2:ROWS(rawData), 2:COLUMNS(rawData))),
  // 把班次名称重复对应每一行数据
  repeatedShiftNames, FLATTEN(ARRAYFORMULA(REPT(Sheet1!B1:E1&"|", ROWS(rawData)-1))),
  // 合并并拆分数据,得到日期、班次、员工三列
  combinedData, SPLIT(FLATTEN(repeatedDates&repeatedShiftNames&shiftAssignments), "|"),
  // 过滤掉空员工的记录
  FILTER(combinedData, INDEX(combinedData, , 3) <> "")
)

提取特定员工的班次

如果要单独提取某个员工(比如单元格A1是员工名字)的所有班次,用QUERY嵌套上面的逻辑即可:

=QUERY(LET(
  rawData, Sheet1!A:E,
  dates, INDEX(rawData, SEQUENCE((ROWS(rawData)-1)/2, 1, 2, 2), 1),
  repeatedDates, FLATTEN(ARRAYFORMULA(REPT(dates&"|", 2))),
  shiftAssignments, FLATTEN(INDEX(rawData, 2:ROWS(rawData), 2:COLUMNS(rawData))),
  repeatedShiftNames, FLATTEN(ARRAYFORMULA(REPT(Sheet1!B1:E1&"|", ROWS(rawData)-1))),
  combinedData, SPLIT(FLATTEN(repeatedDates&repeatedShiftNames&shiftAssignments), "|"),
  FILTER(combinedData, INDEX(combinedData, , 3) <> "")
), "SELECT Col1, Col2 WHERE Col3 = '"&A1&"'")

逻辑解释:用LET简化变量命名,先把日期、班次名称分别重复对应每行排班数据,再通过分隔符合并拆分,最后过滤出有效记录,完美解决单日多班次的情况。

方案二:Google App Script自定义函数

如果数据量很大或者需要更灵活的扩展(比如自动更新、批量导出),用自定义函数会更高效。

步骤1:编写脚本

  1. 打开你的Google表格,点击顶部菜单的「扩展」→「Apps Script」
  2. 清空默认代码,粘贴下面的脚本:
function GET_EMPLOYEE_SHIFTS(employeeName, dataRange) {
  // 初始化结果数组,添加表头
  const result = [["日期", "班次"]];
  
  // 跳过表头行,从第二行开始处理
  const shiftHeaders = dataRange[0];
  const rows = dataRange.slice(1);
  
  // 每两行对应一天,循环处理
  for (let i = 0; i < rows.length; i += 2) {
    // 获取当天日期(取两行中第一行的日期,第二行日期为空)
    const currentDate = rows[i][0];
    if (!currentDate) break; // 防止数据结束时越界
    
    // 处理当天的两行排班数据
    const dayShifts = [rows[i], rows[i+1] || []];
    
    dayShifts.forEach(row => {
      row.forEach((employee, colIndex) => {
        // 跳过日期列,只处理班次列
        if (colIndex === 0) return;
        // 如果当前单元格是目标员工,添加记录到结果
        if (employee === employeeName) {
          result.push([currentDate, shiftHeaders[colIndex]]);
        }
      });
    });
  }
  
  return result;
}

步骤2:使用自定义函数

回到表格,在空白单元格输入:

=GET_EMPLOYEE_SHIFTS("员工姓名", Sheet1!A:E)

把"员工姓名"换成实际的员工名字,或者引用单元格(比如A1),Sheet1!A:E换成你的原始数据范围。函数会自动返回该员工的所有班次记录,包括单日多班次的情况。

优势:脚本逻辑更直观,数据量较大时性能比公式更好,还可以后续扩展比如自动发送排班提醒等功能。

内容的提问来源于stack exchange,提问作者Andrea Volontè

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:01:57