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

需求:仅当今日在Calendar!A2:A范围时运行Google Apps Script

出勤追踪表格脚本优化需求

我为学校制作了一款出勤追踪表格,目前可正常使用但希望进一步优化。现有逻辑为每日清晨通过Apps Script复制Template工作表并重命名,数据从数据工作表(实际版本由Google表单填充)拉取。现需优化:仅当今日日期属于Calendar工作表A2:A范围内的日期时,才执行该脚本。

当前代码如下:

//=================================================================================
// Creates a copy template and renames the new sheet between 0200-0300 every day
//=================================================================================
function createNewSheet(){
  const sh = SpreadsheetApp.getActiveSpreadsheet();
  const ss = sh.getSheetByName("Template");
  const prot = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  const date = Utilities.formatDate(new Date(),"America/New_York","dMMMyy")

  let nSheet = ss.copyTo(sh).setName(date);
  nSheet.showSheet()
  
  let p;
  
  for (let i in prot){
    p = nSheet.getRange(prot[i].getRange().getA1Notation()).protect();
    p.removeEditors(p.getEditors());
    if (p.canDomainEdit()) {
      p.setDomainEdit(false);
    }
  } 
//copy and paste date
  const daily = sh.getSheetByName(date);
  daily.getRange('B1').activate();
  daily.getCurrentCell().setFormula('=today()');
  SpreadsheetApp.flush();  
  daily.getRange('B1').copyTo(daily.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

}
优化后的代码实现

添加日期检查逻辑,仅在今日属于目标范围时执行工作表复制操作:

//=================================================================================
// Creates a copy template and renames the new sheet between 0200-0300 every day
// 仅当今日日期在Calendar!A2:A范围内时执行
//=================================================================================
function createNewSheet(){
  const sh = SpreadsheetApp.getActiveSpreadsheet();
  // 先检查今日是否在目标日期范围内,不在则直接退出
  if (!isTodayInCalendarRange(sh)) return;

  const ss = sh.getSheetByName("Template");
  const prot = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
  const date = Utilities.formatDate(new Date(),"America/New_York","dMMMyy")

  let nSheet = ss.copyTo(sh).setName(date);
  nSheet.showSheet()
  
  let p;
  for (let i in prot){
    p = nSheet.getRange(prot[i].getRange().getA1Notation()).protect();
    p.removeEditors(p.getEditors());
    if (p.canDomainEdit()) p.setDomainEdit(false);
  } 

  // 直接设置日期值,替代原公式转值逻辑,更高效
  const daily = sh.getSheetByName(date);
  daily.getRange('B1').setValue(new Date());
}

// 辅助函数:检查今日日期是否存在于Calendar!A2:A范围内
function isTodayInCalendarRange(spreadsheet) {
  const calendarSheet = spreadsheet.getSheetByName("Calendar");
  if (!calendarSheet) {
    console.log("未找到Calendar工作表");
    return false;
  }

  // 获取A列非空日期数据
  const dateList = calendarSheet.getRange("A2:A").getValues().flat().filter(item => item instanceof Date);
  const today = new Date();
  // 统一日期格式(仅保留年月日,消除时分秒差异)
  const todayNormalized = new Date(today.getFullYear(), today.getMonth(), today.getDate());

  // 遍历匹配日期
  for (const targetDate of dateList) {
    const targetNormalized = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate());
    if (targetNormalized.getTime() === todayNormalized.getTime()) {
      return true;
    }
  }
  return false;
}
关键优化点说明
  • 新增isTodayInCalendarRange辅助函数,专门处理日期匹配逻辑,代码职责更清晰
  • 日期对比时统一格式化(去掉时分秒),避免因时间部分差异导致的匹配失败
  • 简化日期设置逻辑:直接通过setValue写入日期值,替代原公式转值的冗余步骤
  • 主函数开头优先执行检查,不符合条件时直接终止,减少不必要的资源消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:15:51