如何检测共享Google Sheets的同时打开用户数 避免表单内容被覆盖
你需要的在线用户检测、自动管控编辑权限的功能可以通过Google Apps Script实现,全程无需手动查看右上角在线用户列表,具体方案如下:
前置说明
- 所有逻辑都在当前Google Sheets文件内运行,无需接入第三方工具
- 仅文件所有者可完成脚本部署与权限配置,普通编辑者无感知
实现步骤
步骤1:添加检测脚本
打开你的Google Sheets文件,点击顶部菜单栏「扩展程序」→「Apps Script」进入脚本编辑器,删除默认的示例代码,替换为以下代码:
// 配置项:无操作多久视为用户已退出(单位:分钟) const IDLE_TIMEOUT = 5; // 存储用户状态的辅助表名称 const STATUS_SHEET_NAME = "用户状态辅助表(自动生成,请勿修改)"; // 用户打开文件时自动触发 function onOpen(e) { const currentUser = e.user.getEmail(); const statusSheet = _getOrCreateStatusSheet(); // 先清理超时的无效用户记录 _cleanIdleUsers(); // 检查是否已有其他活跃用户 const activeUsers = statusSheet.getRange("A:A").getValues() .filter(row => row[0] && row[0] !== currentUser) .flat(); if (activeUsers.length > 0) { // 有其他用户在线,将当前用户设为只读并提示 const file = DriveApp.getFileById(SpreadsheetApp.getActive().getId()); file.setViewer(currentUser); SpreadsheetApp.getUi().alert("当前有其他用户正在编辑表单,已临时为你开通只读权限,请稍后重试。"); return; } // 无其他用户,记录当前用户活跃状态,开通编辑权限 const existingUserRow = statusSheet.createTextFinder(currentUser).findNext(); const now = new Date(); if (existingUserRow) { statusSheet.getRange(existingUserRow.getRow(), 2).setValue(now); } else { statusSheet.appendRow([currentUser, now]); } const file = DriveApp.getFileById(SpreadsheetApp.getActive().getId()); file.addEditor(currentUser); } // 绑定到表单提交按钮,提交时更新用户活跃时间 function onFormSubmit() { const currentUser = Session.getActiveUser().getEmail(); const statusSheet = _getOrCreateStatusSheet(); _cleanIdleUsers(); const existingUserRow = statusSheet.createTextFinder(currentUser).findNext(); if (existingUserRow) { statusSheet.getRange(existingUserRow.getRow(), 2).setValue(new Date()); } } // 内部方法:获取或创建状态辅助表 function _getOrCreateStatusSheet() { const ss = SpreadsheetApp.getActive(); let sheet = ss.getSheetByName(STATUS_SHEET_NAME); if (!sheet) { sheet = ss.insertSheet(STATUS_SHEET_NAME); sheet.hideSheet(); sheet.appendRow(["用户邮箱", "最后活跃时间"]); } return sheet; } // 内部方法:清理超时用户,回收编辑权限 function _cleanIdleUsers() { const statusSheet = _getOrCreateStatusSheet(); const data = statusSheet.getDataRange().getValues(); const now = new Date(); const validRows = [data[0]]; for (let i = 1; i < data.length; i++) { const [email, timestamp] = data[i]; if (!email || !timestamp) continue; const diffMinutes = (now.getTime() - timestamp.getTime()) / (1000 * 60); if (diffMinutes < IDLE_TIMEOUT) { validRows.push(data[i]); } else { try { const file = DriveApp.getFileById(SpreadsheetApp.getActive().getId()); file.removeEditor(email); file.addViewer(email); } catch (err) {} } } statusSheet.clearContents(); statusSheet.getRange(1, 1, validRows.length, validRows[0].length).setValues(validRows); }
步骤2:配置触发器
- 在Apps Script编辑器左侧点击「触发器」图标,点击「添加触发器」
- 选择要运行的函数:
onOpen - 选择事件来源:
电子表格 - 选择事件类型:
打开时 - 保存触发器,按照页面提示完成Google账号的权限授权
- 可选:新增一个定时触发器,选择运行函数
_cleanIdleUsers,设置每5分钟运行一次,自动清理超时用户记录
注意事项
- 你可以修改代码顶部的
IDLE_TIMEOUT常量,自定义无操作判定超时的时长 - 首次部署完成后建议用多个测试账号验证权限切换逻辑,避免影响正常业务使用
- 自动生成的辅助表默认会隐藏,不要手动修改或删除该表,否则会导致状态检测失效
内容的提问来源于stack exchange,提问作者John Kirkwood
相关产品推荐
相关产品推荐

