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

如何在Google Sheets脚本编辑器中设置全局变量实现单元格触发秒表

Google Sheets无按钮秒表实现方案

核心问题说明

  • 你当前的代码存在两个核心问题:
    1. Google Apps Script每次触发onEdit函数都是独立的运行实例,哪怕把sec定义为函数外的全局变量,两次编辑触发之间的变量值也会被清空,无法留存。
    2. 代码中的while死循环会直接触发脚本执行超时限制,无法实现持续计时的效果。
  • 无需维护秒、分、时的全局累加变量,只需要持久化存储计时开始的时间戳,停止时用当前时间戳减去开始时间戳即可算出完整时长。

调整后完整代码

// 全局配置,可根据需求修改
const SHEET_NAME = 'timer'
const START_CELL = 'A2'
const TIME_DISPLAY_CELL = 'B2'
const RESULT_CELL = 'C2'
// 用PropertiesService实现跨触发的持久化存储
const props = PropertiesService.getUserProperties()

function onEdit(e) {
  const range = e.range
  const sheet = range.getSheet()
  if (sheet.getName() !== SHEET_NAME || range.getA1Notation() !== START_CELL) return
  const inputValue = e.value?.toLowerCase()

  if (inputValue === 'start') {
    // 存储开始时间戳(毫秒级)
    props.setProperty('start_time', Date.now().toString())
    // 初始化显示
    sheet.getRange(TIME_DISPLAY_CELL).setValue('00:00:00')
    // 启动时间更新触发器(每分钟运行一次,可自行调整频率)
    deleteExistingTrigger()
    ScriptApp.newTrigger('updateTime')
      .timeBased()
      .everyMinutes(1)
      .create()
  } else if (inputValue === 'stop') {
    // 删除更新触发器
    deleteExistingTrigger()
    const startTime = Number(props.getProperty('start_time'))
    if (!startTime) return
    // 计算总秒数
    const totalSec = Math.floor((Date.now() - startTime) / 1000)
    // 把总秒数写入C2
    sheet.getRange(RESULT_CELL).setValue(totalSec)
    // 清除存储的开始时间
    props.deleteProperty('start_time')
  }
}

// 定时更新显示的时长
function updateTime() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME)
  const startTime = Number(props.getProperty('start_time'))
  if (!startTime) return
  const totalSec = Math.floor((Date.now() - startTime) / 1000)
  const hr = String(Math.floor(totalSec / 3600)).padStart(2, '0')
  const min = String(Math.floor((totalSec % 3600) / 60)).padStart(2, '0')
  const sec = String(totalSec % 60).padStart(2, '0')
  sheet.getRange(TIME_DISPLAY_CELL).setValue(`${hr}:${min}:${sec}`)
}

// 清理已存在的触发器,避免重复触发
function deleteExistingTrigger() {
  const triggers = ScriptApp.getProjectTriggers()
  triggers.forEach(trigger => {
    if (trigger.getHandlerFunction() === 'updateTime') {
      ScriptApp.deleteTrigger(trigger)
    }
  })
}

使用注意事项

  1. 首次使用时,保存代码后需要任意编辑一次A2单元格触发权限授权,按照指引完成授权即可正常使用。
  2. 如需更高的时间更新频率,可将everyMinutes(1)修改为everySeconds(10)等,最短支持1秒间隔,但高频触发会消耗更多的脚本配额。
  3. 全程仅需要操作A2单元格输入start/stop即可,无需添加任何按钮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:15:03