Google Sheets带保护工作表复制脚本:功能移除与提取需求
Google Apps Script 工作表复制功能拆分与修改
一、移除「跨表复制到首位」功能后的脚本
原脚本移除了跨电子表格复制、以及将新表置于标签栏首位的相关逻辑,仅保留当前电子表格内复制带保护工作表的功能,默认将新表放在标签栏末尾,也可自定义名称和位置。
修改后的代码
/** * 复制工作表并保留保护设置 * 仅支持在当前电子表格内复制 * 如果指定的新表名已存在,将自动命名为「副本 + 原表名」格式 * * 使用示例: const ss = SpreadsheetApp.getActive(); const sheetToCopy = ss.getSheetByName('模板'); let newSheet; // 复制模板表,命名为带日期的新表,放在标签栏最后 const newSheetName = '数据 ' + Utilities.formatDate(new Date(), ss.getSpreadsheetTimeZone(), 'yyyy-MM-dd'); newSheet = copySheetWithProtections_(sheetToCopy, newSheetName); // 复制多个表到当前电子表格末尾 const sheetsToCopy = ['表1', '表2', '表3']; const newSheets = []; sheetsToCopy.forEach(sheetName => { const sheet = ss.getSheetByName(sheetName); newSheets.push(copySheetWithProtections_(sheet, sheetName)); }); console.log(`已复制 ${newSheets.length} 个工作表到当前文件。`); * @param {Sheet} sheet 要复制的工作表对象 * @param {String} optNewSheetName 可选:新工作表名称,默认使用原表名 * @param {Number} optSheetIndex 可选:新表在标签栏的位置(从0开始),默认放在最后 * @return {Sheet} 复制后的新工作表对象 */ function copySheetWithProtections_(sheet, optNewSheetName, optSheetIndex) { // 版本 1.2 修改版,移除跨表复制功能 // 原作者:Hyde,修改适配需求 const ss = sheet.getParent(); const newSheetName = optNewSheetName || sheet.getName(); const sheetIndex = optSheetIndex ?? ss.getNumSheets(); // 默认放在最后位置 const me = Session.getEffectiveUser(); if (!me.getEmail()) { throw new Error('无法获取当前有效用户身份,请检查权限设置。'); } const newSheet = sheet.copyTo(ss); newSheet.activate(); ss.moveActiveSheet(sheetIndex); try { newSheet.setName(newSheetName); } catch (error) { // 表名已存在,保留默认的「副本」命名 } // 复制工作表级保护 const sheetProt = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0]; if (sheetProt) { const newSheetProt = newSheet .protect() .setDescription(sheetProt.getDescription()) .setWarningOnly(sheetProt.isWarningOnly()); if (!sheetProt.isWarningOnly()) { newSheetProt .addEditor(me) .removeEditors(newSheetProt.getEditors().filter(user => user.getEmail() !== me)) .addEditors(sheetProt.getEditors()); try { newSheetProt.setDomainEdit(sheetProt.canDomainEdit()); } catch (error) { // 非Google Workspace域名环境,忽略该设置 } } const unprotectedRanges = sheetProt.getUnprotectedRanges() .map(range => newSheet.getRange(range.getA1Notation())); newSheetProt.setUnprotectedRanges(unprotectedRanges); } else { // 复制单元格区域级保护 sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE) .forEach(rangeProt => { const rangeA1 = rangeProt.getRange().getA1Notation(); const newRangeProt = newSheet.getRange(rangeA1) .protect() .setDescription(rangeProt.getDescription()) .setWarningOnly(rangeProt.isWarningOnly()); if (!rangeProt.isWarningOnly()) { newRangeProt .addEditor(me) .removeEditors(newRangeProt.getEditors().filter(user => user.getEmail() !== me)) .addEditors(rangeProt.getEditors()); try { newRangeProt.setDomainEdit(rangeProt.canDomainEdit()); } catch (error) { // 非Google Workspace域名环境,忽略该设置 } } }); } return newSheet; }
二、独立实现「跨表复制同名工作表到标签栏首位」的脚本
该脚本仅专注于将指定工作表复制到目标电子表格,使用原表名,并自动放在标签栏最左侧,同时完整保留原表的所有保护设置。
独立脚本代码
/** * 将工作表复制到目标电子表格,使用原表名并置于标签栏首位,同时保留保护设置 * 如果目标表中已存在同名工作表,将自动命名为「副本 + 原表名」格式 * * 使用示例: const ss = SpreadsheetApp.getActive(); const sheetToCopy = ss.getSheetByName('模板'); // 替换为目标电子表格的ID const targetSpreadsheetId = '123abc...cba321'; const targetSs = SpreadsheetApp.openById(targetSpreadsheetId); const newSheet = copySheetToTargetFirst_(sheetToCopy, targetSs); console.log(`已将工作表 ${sheetToCopy.getName()} 复制到 ${targetSs.getName()} 的标签栏首位。`); * @param {Sheet} sheet 要复制的源工作表对象 * @param {Spreadsheet} targetSs 目标电子表格对象 * @return {Sheet} 复制后的新工作表对象 */ function copySheetToTargetFirst_(sheet, targetSs) { // 提取自Hyde原脚本,专注实现跨表复制到首位功能 const me = Session.getEffectiveUser(); if (!me.getEmail()) { throw new Error('无法获取当前有效用户身份,请检查权限设置。'); } // 复制工作表到目标表并置于首位(索引0) const newSheet = sheet.copyTo(targetSs); newSheet.activate(); targetSs.moveActiveSheet(0); // 使用原表名命名 try { newSheet.setName(sheet.getName()); } catch (error) { // 表名已存在,保留默认的「副本」命名 } // 复制工作表级保护 const sheetProt = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0]; if (sheetProt) { const newSheetProt = newSheet .protect() .setDescription(sheetProt.getDescription()) .setWarningOnly(sheetProt.isWarningOnly()); if (!sheetProt.isWarningOnly()) { newSheetProt .addEditor(me) .removeEditors(newSheetProt.getEditors().filter(user => user.getEmail() !== me)) .addEditors(sheetProt.getEditors()); try { newSheetProt.setDomainEdit(sheetProt.canDomainEdit()); } catch (error) { // 非Google Workspace域名环境,忽略该设置 } } const unprotectedRanges = sheetProt.getUnprotectedRanges() .map(range => newSheet.getRange(range.getA1Notation())); newSheetProt.setUnprotectedRanges(unprotectedRanges); } else { // 复制单元格区域级保护 sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE) .forEach(rangeProt => { const rangeA1 = rangeProt.getRange().getA1Notation(); const newRangeProt = newSheet.getRange(rangeA1) .protect() .setDescription(rangeProt.getDescription()) .setWarningOnly(rangeProt.isWarningOnly()); if (!rangeProt.isWarningOnly()) { newRangeProt .addEditor(me) .removeEditors(newRangeProt.getEditors().filter(user => user.getEmail() !== me)) .addEditors(rangeProt.getEditors()); try { newRangeProt.setDomainEdit(rangeProt.canDomainEdit()); } catch (error) { // 非Google Workspace域名环境,忽略该设置 } } }); } return newSheet; }
内容的提问来源于stack exchange,提问作者Badyr
相关产品推荐
相关产品推荐

