简体   繁体   English

如何从Google Sheet脚本中的onEdit()获取旧公式(不是oldValue)

[英]How to get old Formula (not oldValue) from onEdit() in Google Sheet Script

Does anyone know if there's a way to access the old (ie, pre-edit) formula, as opposed to oldValue, of the edit event object? 有谁知道是否有一种方法可以访问编辑事件对象的旧(即预编辑)公式(与oldValue相反)? I thought e.oldFormula would work, but it's undefined and not even in the documentation. 我以为e.oldFormula可以工作,但是它是未定义的,甚至在文档中也没有。

I'm working on a script to require a password when editing certain ranges but, in order to undo the edit if the user fails to provide the correct password, I need to know what was in the cell before. 我正在编写一个脚本,在编辑某些范围时要求输入密码,但是,如果用户未能提供正确的密码,则要撤消编辑,我需要知道单元格中的内容。 For cells that contain numbers or strings, e.oldValue works great, but most of the cells I want to protect contain formulas (that's why I want to protect them) so e.oldValue stops the data from updating like it should. 对于包含数字或字符串的单元格,e.oldValue可以很好地工作,但是我要保护的大多数单元格都包含公式(这就是我要保护它们的原因),因此e.oldValue阻止数据像应有的那样进行更新。

Here's the code I've got that only works if the cell contains no formulas (other than that, it works great: 这是我得到的代码,仅当单元格不包含公式时才有效(除此之外,它很好用:

// Prompt for password before allowing edit of formula cells
function onEdit(e) {
   var ss = SpreadsheetApp.getActiveSpreadsheet();
   var sheet = ss.getActiveSheet();
   var cell = sheet.getActiveCell();
   var editRange = e.range;
   var editCol = editRange.getColumn();


  if (editCol != 4 ) {
    var password = "321"; // not actual password
    var passwordAttempt = Browser.inputBox('Enter Password to edit protected range, or hit cancel to cancel edit:', Browser.Buttons.OK_CANCEL);

    if(passwordAttempt == password) {
      Browser.msgBox('Edit Accepted');
    } else {
      if (passwordAttempt != 'cancel'){
        Browser.msgBox('Incorrect password. Contact James Atkins for password to edit protected ranges.');
      }
      if(e.oldValue){
         Browser.msgBox('old value is defined as ' + e.oldFormula);
         e.range.setValue(e.oldValue);
      } else {
         e.range.clear();
     }
  }

FYI, I'm doing this because the built-in protected ranges in Google Sheets don't distinguish between a user changing the contents of a cell by manually editing it and by activating a script that changes the contents. 仅供参考,我这样做是因为Google表格中的内置受保护范围无法区分用户是通过手动编辑单元格来更改单元格内容,还是通过激活用于更改单元格内容的脚本来进行区分。 I want to allow all users to activate scripts that sort and clear certain ranges, but not let them mess with the contents manually. 我想允许所有用户激活排序和清除某些范围的脚本,但不要让他们手动弄乱内容。

You can solve this problem by creating a clone of your sheet to keep track of your formula. 您可以通过创建工作表的副本来跟踪公式来解决此问题。 Make the clone sheet off limits to end users. 使克隆表不受最终用户的限制。 So they cannot edit it. 因此他们无法编辑它。

function onEdit(e) {
   var ss = SpreadsheetApp.getActiveSpreadsheet();
   var sheet = ss.getActiveSheet();  
   var cloneSheet = ss.getSheetByName("cloneSheet")
   var cell = sheet.getActiveCell();
   var editRange = e.range;
   var cloneRange = cloneSheet.getRange(editRange.getA1Notation())
   var editCol = editRange.getColumn();


  if (editCol != 4 && sheet.getName() != "cloneSheet") { 
    var password = "321"; // not actual password
    var passwordAttempt = Browser.inputBox('Enter Password to edit protected range, or hit cancel to cancel edit:', Browser.Buttons.OK_CANCEL);

    if(passwordAttempt == password) {
      Browser.msgBox('Edit Accepted');
      cloneRange.setValue(editRange.getFormula()) //modify the clone to match the new formula. 
    } else {
      if (passwordAttempt != 'cancel'){
        Browser.msgBox('Incorrect password. Contact James Atkins for password to edit protected ranges.');
      }
      if(e.oldValue){
         Browser.msgBox('old value is defined as ' + cloneRange.getFormula());
         e.range.setValue(cloneRange.getFormula());
      } else {
         e.range.clear();
     }
  }
  }
} 

However, end user can still see the password. 但是,最终用户仍然可以看到密码。 If you really what end user to make only limited changes the below solution is better. 如果您是真正的最终用户,只需进行有限的更改,则以下解决方案会更好。

Alternate Solution 替代解决方案

When an end user executes a script, even though you have written the script, it runs with scope/identity of the end user. 当最终用户执行脚本时,即使您已经编写了脚本,它也会以最终用户的范围/身份运行。 So if they don't have edit permission then the script that runs under their alias also does not have it either. 因此,如果他们没有编辑权限,则在其别名下运行的脚本也不会具有此权​​限。 This is in response to your comment: 这是对您的评论的回应:

google sheets don't distinguish between a user changing the contents of a cell by manually editing it and by activating a script that changes the contents. Google表格不会区分用户通过手动编辑单元格和激活更改内容的脚本来更改单元格的内容。

So how to get around this problem, you can use a google web app to run sort and clear scripts as you. 因此,如何解决此问题,您可以在使用Google Web应用时运行排序和清除脚本。 The end user uses a script that makes a call to this script using UrlFetch, this gets around the problem of scopes and prevents them from having a look at your code/password etc. 最终用户使用一个脚本,该脚本使用UrlFetch对该脚本进行调用,从而避免了范围问题,并阻止了它们查看您的代码/密码等。

Here is SO question that addressing a similar problem: Google Apps Script: Temporarily run script as another user 以下是解决类似问题的一个问题: Google Apps脚本:以其他用户身份临时运行脚本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM