Google apps script 访问正确的范围时;论编辑;触发函数修改Google工作表';s结构
如果输入了特定值,我需要将一行移动到另一个工作表,例如存档数据 我已经编写了下面的代码,只要用户在第一次触发完成之前没有再次触发它,它就可以完美地工作。第一个事件将移动相应的行,但第二个“编辑”事件将移动不同的行,因为行数已被上一个Google apps script 访问正确的范围时;论编辑;触发函数修改Google工作表';s结构,google-apps-script,google-sheets,triggers,eventtrigger,Google Apps Script,Google Sheets,Triggers,Eventtrigger,如果输入了特定值,我需要将一行移动到另一个工作表,例如存档数据 我已经编写了下面的代码,只要用户在第一次触发完成之前没有再次触发它,它就可以完美地工作。第一个事件将移动相应的行,但第二个“编辑”事件将移动不同的行,因为行数已被上一个onEdit()调用更改。例如: 客户编辑第[1]行和第[3]行,并将其标记为存档 第一个onEdit将删除行[1],因此行[3]将成为行[2],但在第二个onEdit调用中,范围。getRow()仍返回3,因此行[3]将被删除,而不是行[2] function on
onEdit()
调用更改。例如:
客户编辑第[1]行和第[3]行,并将其标记为存档
第一个onEdit
将删除行[1]
,因此行[3]
将成为行[2]
,但在第二个onEdit
调用中,范围。getRow()
仍返回3,因此行[3]
将被删除,而不是行[2]
function onEdit(event)
{
moveArchived(event);
}
function moveArchived(event)
{
var sheetNameToWatch = "Queue";
var columnNumberToWatch = 15; // column A = 1, B = 2, O = 15, etc.
var valueToWatch = "ARCHIVE";
var sheetNameToMoveTheRowTo = "Archive";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = event.source.getActiveSheet();
var range = event.source.getActiveCell();
if (sheet.getName() == sheetNameToWatch && range.getColumn() == columnNumberToWatch && range.getValue() == valueToWatch)
{
var ui = SpreadsheetApp.getUi();
var response = ui.alert('Do you want to move this row to Archive sheet?', ui.ButtonSet.YES_NO);
if (response == ui.Button.NO)
return;
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(), 1, 1, sheet.getLastColumn()).moveTo(targetRange);
sheet.deleteRow(range.getRow());
}
}
如何修改代码来防止这种情况,即确保移动实际范围?我认为使用将是此用例的理想解决方案,因为它的目的是防止两个或多个函数执行之间的并发,但我对得到的结果有点失望
也许有人会找到更好的方法来实现它,或者提出另一种解决方案;-)
同时,您可以尝试下面的代码。我做了一些更改,其中之一是能够同时处理多个单元格(如果用户粘贴了多个包含“存档”的单元格)
我还使用来自事件本身的范围更改了范围定义,最后,我使用了一个可安装的OneEdit,而不是简单的OneEdit,因为我觉得它工作起来更可靠(尽管没有客观原因……可能是我梦到的;-))
并更改了onEdit函数名以避免双重触发
因此,您必须从脚本编辑器的Resources菜单添加一个新的OneEdit触发器
在所有这些警告之后,我唯一能说的是它是有效的。。。但并非总是如此!这是使用脚本时最烦人的情况。。。所以,正如我已经说过的,在买之前先试试,然后祈祷有人能很快改进
代码如下:
function moveArchived(event){
var lock = LockService.getPublicLock();
// Wait for up to 30 seconds for other processes to finish.
lock.waitLock(30000);
var sheetNameToWatch = "Queue";
var columnNumberToWatch = 15; // column A = 1, B = 2, O = 15, etc.
var valueToWatch = "ARCHIVE";
var sheetNameToMoveTheRowTo = "Archive";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = event.source.getActiveSheet();
var range = event.range;
if (sheet.getName() == sheetNameToWatch && range.getColumn() == columnNumberToWatch && range.getValue().indexOf(valueToWatch)>-1)
{
var ui = SpreadsheetApp.getUi();
var response = ui.alert('Do you want to move this/these row(s) to Archive sheet?', ui.ButtonSet.YES_NO);
if (response == ui.Button.NO)
{
lock.releaseLock();
return
}
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
range.moveTo(targetRange);
for(var n = event.range.rowStart ; n < event.range.rowEnd ; n++){
sheet.deleteRow(n);
}
}
lock.releaseLock();
}
function installOnEdit(event){
Logger.log(JSON.stringify(event));
moveArchived(event);
}
函数(事件){
var lock=LockService.getPublicLock();
//等待30秒,等待其他进程完成。
lock.waitLock(30000);
var sheetnametwatch=“队列”;
var columnNumberToWatch=15;//列A=1、B=2、O=15等。
var valueToWatch=“存档”;
var sheetnametomovetherowt=“存档”;
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheet=event.source.getActiveSheet();
var范围=事件范围;
如果(sheet.getName()==sheetNameToWatch&&range.getColumn()==columnNumberToWatch&&range.getValue().indexOf(valueToWatch)>-1)
{
var ui=SpreadsheetApp.getUi();
var response=ui.alert('是否要将此/这些行移动到存档工作表?',ui.ButtonSet.YES\u NO);
如果(响应==ui.Button.NO)
{
锁。释放锁();
返回
}
var targetSheet=ss.getSheetByName(sheetnametomovetherowt);
var targetRange=targetSheet.getRange(targetSheet.getLastRow()+1,1);
范围。移动到(目标范围);
对于(var n=event.range.rowStart;n