嵌套调用的onEdit函数中onEdit3无法正常工作的问题排查
排查Google Sheets onEdit触发器中onEdit3函数失效问题
我编写了一个主onEdit(event)函数,在其中调用onEdit1、onEdit2、onEdit3三个子函数。参考相关方案实现后,onEdit1和onEdit2可正常运行,但onEdit3无法工作,怀疑是event.range相关问题,无法自行解决,以下是我的脚本:
function onEdit(event) { onEdit1(event); onEdit2(event); onEdit3(event); } //ADD COLOR MPR MASTER TAB function onEdit1(event) { var sss = event.source; var sourceSheet = sss.getActiveSheet(); var shName = sourceSheet.getName(); var crange = event.range; var crow = crange.getRow(); var ccol = crange.getColumn(); if ((shName == "MASTER" ) && (ccol >= 38)){ var cvalue = crange.getValue(); var validationSheet = sss.getSheetByName("CALCULS"); var optionColor = validationSheet.createTextFinder(cvalue).findNext().getBackground(); crange.setBackground(optionColor); var sourceOptionColor = sourceSheet.getRange(crow, 38).getBackground(); destSheet.getRange(destRow,38).setBackground(sourceOptionColor); } } //MERGE BANQUE TAB function onEdit2(event) { let sh = event.source.getActiveSheet() let onglets = ['BANQUE'] let shCol = event.range.getColumn() let shRow = event.range.getRow() let upRows = [25] let upCols = [14] console.log(shCol) console.log(shRow) if (onglets.indexOf(sh.getName()!=-1) && upRows.includes(shRow) && upCols.includes(shCol)){ mergeBanque() } } //LOCK ROWS MASTER TAB function onEdit3(event) { let range = event.range; //get the range of edited cell let row = range.getRow(); //get the row let col = range.getColumn(); //get the column let value = event.value; //get the new value of edited cell let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MASTER'); //get the sheet where edit is made if(col == 69 && row >= 6 && value == 'TRUE'){ //check if the edited cell is BM and row is equal or greater than 5 and value is X let lock_range = `B${row}:BQ${row}`; //set lock range using row let protection = sheet.getRange(lock_range).protect() //set protection .setDescription(`Ligne ${row}`) //add description protection.addEditor(kamaramamedia); protection.removeEditors(protection.getEditors()); //remove editors }else if(col == 69 && row >= 6 && value == 'FALSE'){ //check if the edited cell is BL and row is equal or greater than 5 and value is O var protectedRange = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE); //get all protection with type range for (var i = 0; i < protectedRange.length; i++) { //loop if (protectedRange[i].getDescription() == `Ligne ${row}`) { //row matching protectedRange[i].remove(); //remove protection } } } }
问题排查与修复方案
onEdit3的核心问题:
缺少工作表校验:
代码直接获取了MASTER工作表,但没判断当前编辑的是否是这个表。如果用户编辑其他工作表,col == 69的条件永远不成立,函数不会执行。需要先校验编辑操作所在工作表是否为MASTER。布尔值判断错误:
当编辑的是复选框时,event.value返回的是布尔类型的true/false(小写),但代码里判断的是字符串'TRUE'/'FALSE',条件完全不匹配,导致分支无法触发。未定义变量
kamaramamedia:
代码中直接使用kamaramamedia作为添加的编辑器,但这个变量没有定义(应该是邮箱地址字符串),会导致保护设置失败,甚至报错中断函数。保护范围获取范围错误:
sheet.getProtections(...)应该指定从当前MASTER工作表获取保护,否则会获取整个文档的所有保护,可能无法精准匹配目标行的保护。
修复后的onEdit3代码:
//LOCK ROWS MASTER TAB function onEdit3(event) { let range = event.range; let row = range.getRow(); let col = range.getColumn(); let value = event.value; // 获取当前编辑的工作表,而非直接指定MASTER let activeSheet = event.source.getActiveSheet(); let sheet = event.source.getSheetByName('MASTER'); // 先校验是否在MASTER表编辑,且列是69、行≥6 if (activeSheet.getName() !== 'MASTER' || col !== 69 || row < 6) return; // 正确判断布尔值(复选框的value是布尔类型) if (value === true) { let lock_range = `B${row}:BQ${row}`; let protection = sheet.getRange(lock_range).protect() .setDescription(`Ligne ${row}`); // 替换成实际的邮箱地址字符串 const editorEmail = 'kamaramamedia@example.com'; protection.addEditor(editorEmail); // 保留所有者权限,避免自己也被移除编辑权限 protection.removeEditors(protection.getEditors().filter(email => email !== editorEmail)); } else if (value === false) { // 从MASTER工作表获取保护,而非整个文档 let protectedRanges = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE); for (let i = 0; i < protectedRanges.length; i++) { if (protectedRanges[i].getDescription() === `Ligne ${row}`) { protectedRanges[i].remove(); break; // 找到匹配项后直接跳出循环,提升效率 } } } }
其他函数的潜在问题提示:
- onEdit1:代码中使用了
destSheet和destRow变量,但这两个变量未定义,会导致报错,需要补充定义或删除无关代码。 - onEdit2:
onglets.indexOf(sh.getName()!=-1)括号位置错误,应该是onglets.indexOf(sh.getName()) !== -1,否则判断逻辑完全错误,导致mergeBanque()永远不会触发。
内容的提问来源于stack exchange,提问作者Savoir Apprendre
相关产品推荐
相关产品推荐

