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

如何配置Apps Script时间触发器以每月15日和月末成功执行?

问题分析

你遇到的触发器数量超限错误,根源是代码中每次运行都会调用ScriptApp.newTrigger(...).create()创建新的每日触发器,导致触发器不断累积,超出Google Apps Script的触发器限额。同时原有的触发逻辑也没实现「每月15日+月末执行」的需求。


解决方案

1. 清理现有重复触发器

先运行这个函数删除所有关联的旧触发器,解决当前的数量超限问题:

function deleteAllTriggers() {
  var triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < triggers.length; i++) {
    ScriptApp.deleteTrigger(triggers[i]);
  }
}

2. 创建单次的每日触发器(仅执行一次)

创建一个仅运行一次的函数,生成符合要求的每日触发器(23点触发),并且会检查是否已存在同名触发器,避免重复创建:

function createRequiredTriggers() {
  // 检查copyDatabase触发器是否已存在
  var hasCopyTrigger = ScriptApp.getProjectTriggers().some(trigger => 
    trigger.getHandlerFunction() === "copyDatabase"
  );
  if (!hasCopyTrigger) {
    ScriptApp.newTrigger("copyDatabase")
      .timeBased()
      .atHour(23)
      .everyDays(1)
      .create();
  }

  // 检查exportTriggerFunction触发器是否已存在
  var hasExportTrigger = ScriptApp.getProjectTriggers().some(trigger => 
    trigger.getHandlerFunction() === "exportTriggerFunction"
  );
  if (!hasExportTrigger) {
    ScriptApp.newTrigger("exportTriggerFunction")
      .timeBased()
      .atHour(23)
      .everyDays(1)
      .create();
  }
}

注意:仅需运行一次这个函数,之后不要重复执行,否则会再次创建重复触发器。

3. 修改目标函数,添加日期判断逻辑

修正copyDatabase函数

在函数开头添加日期判断,仅当当天是15号或月末时才执行后续逻辑,同时修正原代码中获取目标表空行的错误:

function copyDatabase() {
  var today = new Date();
  var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
  
  // 仅在15日或月末执行
  if (today.getDate() !== 15 && today.getDate() !== lastDayOfMonth.getDate()) {
    return; // 不符合日期条件,直接退出
  }

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Index");
  var desinationsheet = ss.getSheetByName("All Work Orders");

  var startRow = 2; 
  var numRows = sheet.getLastRow() - startRow + 1; 
  var startCol = 23;
  var numCols = 14;
  var startColTarget = 1;
  var dataRange = sheet.getRange(startRow, startCol, numRows, numCols); 
  var data = dataRange.getValues(); 
  var Copy = "Copy"; 
  // 修正:从目标表获取空行,而非源表
  var firstEmptyRow = desinationsheet.getLastRow() + 1;
  var dataToCopy = data.filter(row => row[2] !== Copy);

  if (dataToCopy.length > 0) {
    desinationsheet.getRange(firstEmptyRow, startColTarget, dataToCopy.length, dataToCopy[0].length).setValues(dataToCopy);
  }
}

修正exportTriggerFunction函数

添加15日的判断逻辑,将日期判断移到最开头,避免不必要的资源消耗:

function exportTriggerFunction() {
  var today = new Date();
  var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
  
  // 仅在15日或月末执行
  if (today.getDate() !== 15 && today.getDate() !== lastDayOfMonth.getDate()) {
    return; // 不符合日期条件,直接退出
  }

  var exportSheetIds = 
    ["560568812","1440952465","439649389","513481136",
     "1088500659","133657514","1618608630","802444630",
     "1834450484","657423004","682313931","1980296394","635144452"];

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  var name = ss.getRange('Reference!M2').getDisplayValue();
  var destination = DriveApp.getFolderById("1HRchNqQ5_0LYzfULw1hWN_ALNuijsy2q");

  // 1. 复制临时表格
  const spreadsheet = ss.copy('tmp');
  const sheets = spreadsheet.getSheets();
  const check = sheets.filter(s => exportSheetIds.includes(s.getSheetId().toString()));
  if (check.length == 0) {
    throw new Error("No export sheets.");
  }

  // 2. 公式转文本
  sheets.forEach(sheet => {
    if (exportSheetIds.includes(sheet.getSheetId().toString())) {
      const targetRange = sheet.getDataRange();
      targetRange.copyTo(targetRange, { contentsOnly: true });
    }
  });

  // 3. 删除不需要的表格
  sheets.forEach(sheet => {
    if (!exportSheetIds.includes(sheet.getSheetId().toString())) {
      spreadsheet.deleteSheet(sheet);
    }
  });
  SpreadsheetApp.flush();

  // 4. 获取Excel blob
  const id = spreadsheet.getId();
  const xlsxBlob = UrlFetchApp.fetch(`https://docs.google.com/spreadsheets/export?id=${id}&exportFormat=xlsx`, { 
    headers: { authorization: `Bearer ${ScriptApp.getOAuthToken()}` } 
  }).getBlob();

  // 5. 保存到Drive
  destination.createFile(xlsxBlob.setName(`${name}.xlsx`));

  // 6. 删除临时表格
  DriveApp.getFileById(id).setTrashed(true);
}

操作步骤
  1. 打开你的Google Apps Script编辑器;
  2. 粘贴deleteAllTriggers函数并运行,删除所有旧触发器;
  3. 粘贴createRequiredTriggers函数并运行,创建所需的两个每日触发器;
  4. 替换原有的copyDatabase和exportTriggerFunction函数为修改后的版本;
  5. 保存脚本,之后触发器会在每日23点运行,但仅在15日和月末时执行实际业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:50:09