此代码通过将数据与帮助程序表进行比较并在已填充的单元格上进行更改后返回已存储在帮助程序表中的数据,从而防止数据在首次输入后被修改。
问题:此代码的问题是,如果您选择多个单元格并单击键盘上的删除,则所有单元格都将被删除,代码将无法正常工作,如何解决此问题?
代码:
function onEdit() {
var masterSheetName = "sheet1" // sheet where the cells are protected from updates
var helperSheetName = "Helper" // sheet where the values are copied for later checking
var firstDataRow = 1; // only take into account edits on or below this row
var firstDataColumn = 1; // only take into account edits on or to the right of this column
var ss = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = ss.getActiveSheet();
if (masterSheet.getName() != masterSheetName) return;
var masterCell = masterSheet.getActiveCell();
if (masterCell.getRow() < firstDataRow || masterCell.getColumn() < firstDataColumn) return;
var helperSheet = ss.getSheetByName(helperSheetName);
var helperCell = helperSheet.getRange(masterCell.getA1Notation());
var newValue = masterCell.getValue();
var oldValue = helperCell.getValue();
if (oldValue == "") {
helperCell.setValue(newValue);
} else {
masterCell.setValue(oldValue);
}
}
看看这是否适合你。它检查所选范围的大小,如果大于一个单元格,则将范围重置为辅助工作表值。
function onEdit() {
var masterSheetName = "sheet1" // sheet where the cells are protected from updates
var helperSheetName = "Helper" // sheet where the values are copied for later checking
var firstDataRow = 1; // only take into account edits on or below this row
var firstDataColumn = 1; // only take into account edits on or to the right of this column
var ss = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = ss.getActiveSheet();
if (masterSheet.getName() != masterSheetName) return;
var masterCell = masterSheet.getActiveCell();
if (masterCell.getRow() < firstDataRow || masterCell.getColumn() < firstDataColumn) return;
var helperSheet = ss.getSheetByName(helperSheetName);
var helperCell = helperSheet.getRange(masterCell.getA1Notation());
var newValue = masterCell.getValue();
var oldValue = helperCell.getValue();
if (oldValue == "") {
helperCell.setValue(newValue);
} else {
masterCell.setValue(oldValue);
}
var test=masterSheet.getActiveRange().getA1Notation()//get the selected range
var testsize=masterSheet.getActiveRange().getValues()//create an array of selected values
var size=testsize.length// array length
if(size>1){//if length of selected range is greater than one cell
Browser.msgBox("Select only one cell")
var helperSheet1 = ss.getSheetByName(helperSheetName).getRange(test).getValues();
var masterSheet1= ss.getSheetByName(masterSheetName).getRange(test).getValues();
var masterSheet1= ss.getSheetByName(masterSheetName).getRange(test).setValues(helperSheet1);//reset range
}
}
听起来我需要添加一个事件监听器来显式监听选择多个单元格并按下删除键的实例,然后只需添加一个回调来从帮助表重新填充数据集
范围保护是一种内置功能,可防止输入的数据被修改,使用它而不是覆盖旧值。您可以使用protect()更改保护设置。
关于OP代码,它错过了编辑事件对象,而是使用“getActiveSomething”方法。这是低效的。另一方面,代码使用返回活动单元格的getActiveCell,而edit事件对象的range属性返回正在编辑的范围。
如果由于任何原因无法使用范围保护,则以下是OP代码的替代方案,该代码适用于同时编辑多个单元格,例如将值粘贴到多个单元格或删除多个单元格。
注1:为简化代码,省略了对OP代码的一些验证。
注2:它不考虑粘贴包含一些空单元格的范围而不包括其他单元格的情况。
function onEdit(e) {
// If the edit is made on an invalid sheet, exit.
if(e.range.getSheet().getName() != 'Sheet1') return;
// Count the number of cells being edited
var cellsNumber = [].concat.apply([],e.range.getValues()).length;
if(cellsNumber == 1 ){
var helper = e.source.getSheetByName('Helper').getRange(e.range.getA1Notation());
if(e.range.getValue() != ''){
helper.setValue(e.value);
} else {
e.range.setValue(helper.getValue());
}
} else {
var helper = e.source.getSheetByName('Helper').getRange(e.range.getA1Notation());
// Count the number of characters on the edited range
var charsNumber = [].concat.apply([],e.range.getValues()).join('').length;
if(charsNumber > 0) {
helper.setValues(e.range.getValues());
} else {
e.range.setValues(helper.getValues());
}
}
}