Javascript Google Sheets在单独的电子表格之间移动行不起作用,但在表格之间移动行起作用

Javascript Google Sheets在单独的电子表格之间移动行不起作用,但在表格之间移动行起作用,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我有一个简短的功能,我使用其他问题的答案在这里,但它不是完美的工作,我不明白为什么 function onEdit(e) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = e.source.getActiveSheet(); var r = e.source.getActiveRange(); if(s.getName() == "Input Expenses" && r.getColumn(

我有一个简短的功能,我使用其他问题的答案在这里,但它不是完美的工作,我不明白为什么

function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = e.source.getActiveSheet();
  var r = e.source.getActiveRange();

    if(s.getName() == "Input Expenses" && r.getColumn() == 14 && r.getValue() == "Verified") {
        var row = r.getRow();
        var numColumns = s.getLastColumn(); 
        var targetSheet = ss.getSheetByName("Verified Expenses");
        var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
        s.getRange(row, 1, 1, numColumns).moveTo(target);
        s.deleteRow(row);
    }

}
这样做的目的是检查是否有“已验证”,如果是,则将其移至“已验证费用”表。我希望这是一个完全独立的电子表格,这样我的数据输入表可以快速加载。我还尝试了
openByID
,以防您感到奇怪

这是我所做的改变,尝试让它工作:

function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = e.source.getActiveSheet();
  var r = e.source.getActiveRange();
  var t = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1R6YQAjV5G8JVzr2ecw6IZQFzC8J5KbzLImXOb6KGDIw/edit#gid=0");

  if(s.getName() == "Input Expenses" && r.getColumn() == 14 && r.getValue() == "Verified") {
    var row = r.getRow();
    var numColumns = s.getLastColumn();
    var targetSheet = t.getSheetByName("Verified Expenses");
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
    s.getRange(row, 1, 1, numColumns).moveTo(target);
    s.deleteRow(row);
  }

}
我觉得这是一件我忽略了的非常简单的事情,因为我盯着它看得太久了

--编辑--

这是作为手动函数而不是onEdit()运行时的执行记录


我相信我能够在模拟环境中解决这个问题

首先,当您访问其他电子表格时,onEdit方法显然不起作用,因为它只适用于简单的脚本。因此,您需要使用另一个名称创建一个函数,并将其作为触发器运行,正如SpiderPig在您的问题的注释中指出的那样

除此之外,我相信moveTo函数应该只在同一个电子表格中工作,因此您必须使用另一种方法来实现这一点,我使用了appendRow方法

获取有关谷歌应用程序脚本所需一切信息的一个非常有用的地方是:

下面是我用来让它工作的脚本:

function Test(e) {
  //Oficial
  var s = e.source.getActiveSheet();
  var r = e.range;
  //Test
  //var s =  SpreadsheetApp.getActiveSheet(); //Gets active Sheet.
  //var r = s.getRange(2, 1, 1, 2); //Gets first line after header.

  var targetSheet = SpreadsheetApp.openById("15V0AvU84OBmN0nQweNyYczh5UfOTX77eECzu_1Um6Ug").getSheetByName("Verified Expenses");

  //To View Logs, enter no View, Logs after the execution of the script
  Logger.log(s.getName()); 
  Logger.log(r.getColumn());
  Logger.log(r.getValue());

  if(s.getName() == "Input Expenses" && r.getColumn() == 1 && r.getValue() == "Verified") {
    var row = r.getRow();
    var numColumns = s.getLastColumn();
    var rangeToAdd = s.getRange(row, 1, 1, numColumns).getValues(); //Creates an Array[][], being the first dimension the rows and the second one the columns. 
    var rangeToAddFiltered = rangeToAdd[0]; //Get the first row of the array (as we will only check one by one).
    targetSheet.appendRow(rangeToAddFiltered); //Append the Row to the new SpreadSheet (moveTo appears to work only inside the same SpreadSheet).
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
    s.deleteRow(row); //Profit!
  }
}
别忘了在参考资料中当前项目的触发器中的onEdit触发器上添加测试(e)

我希望它能帮助你

更新:


如果这仍然对您没有帮助,可能是您遇到了一些权限问题(第一次运行脚本时,会弹出一个窗口,请求脚本更改电子表格的权限)。也许另一种方法是强制在固定范围内发生假事件,以便能够调试函数以查看发生了什么。我在上面的脚本中添加了一些注释行,如果没有注释,可以用于完全通过脚本接口运行脚本以进行测试/调试。

您需要使用
Logger.log()
语句,例如
Logger.log('row:'+row))
和/或使用来了解代码正在执行的操作。
s.getName()
等的值是多少。检查查看菜单下的执行记录,查看代码是否完成。如果没有,错误是什么?它在哪一行失败?单击“资源/当前项目的触发器”,并将onEdit函数添加到其中作为onEdit触发器。还可以手动运行该函数一次,以便获得权限弹出窗口,您可以在其中授予该函数更改电子表格的权限。是否选中正确的列?可能就这么简单谢谢Jonathon我刚查过。如果这么简单的话,我会打自己的。不幸的是,我正在检查正确的列。可能需要添加按名称搜索的内容。如果我编辑电子表格,会更安全一些。我将尝试调试,但我记得出现了一些问题,因为除非我实际编辑工作表,否则脚本不想运行,所以当我手动运行时,脚本总是提前终止。@SpiderPig我的函数不是已经在编辑时触发自己了吗?如果我只在一个电子表格中工作,而没有在参考资料中设置触发器,那么它可以工作,但在两个单独的电子表格之间失败。不管怎样,我都会尝试,但这似乎是另一个问题。您对权限的看法可能是对的,但如果未从undefined中获取“Cannot read property”source,我无法手动运行它。“undefined是我的事件!”!如果我没有实际编辑电子表格,那么就没有事件!谢谢拉斐尔回答得很好,我正在努力让它发挥作用。首先,我试着使用你的逻辑,修改了我的函数,使其看起来像你的函数,但有一些不同,得到了与以前相同的结果。然后我只是复制和粘贴你写的东西,我仍然有同样的问题?你测试过你写的代码吗?我想现在我处于故障排除模式。我有一些理论上应该有用的东西。谢谢嗨,我做了测试,它正在工作。看一看,这是你写“验证”的地方(登录谷歌账户时输入并复制一份以访问脚本):这是信息移动的地方:第二个电子表格没有脚本。别忘了将两者都复制一份,并将openById修改为您在副本上生成的新Id。谢谢Rafael,我已经在您的工作表上完成了。现在我想知道为什么我自己的不起作用。我看不出有什么不同!无论您采用哪种方式,都为您的帮助而欢呼。@Catu我已在脚本中添加了一些代码,以便允许完全通过脚本接口进行测试(特别是调试)(您必须取消注释某些行)。我希望有帮助。
function Test(e) {
  //Oficial
  var s = e.source.getActiveSheet();
  var r = e.range;
  //Test
  //var s =  SpreadsheetApp.getActiveSheet(); //Gets active Sheet.
  //var r = s.getRange(2, 1, 1, 2); //Gets first line after header.

  var targetSheet = SpreadsheetApp.openById("15V0AvU84OBmN0nQweNyYczh5UfOTX77eECzu_1Um6Ug").getSheetByName("Verified Expenses");

  //To View Logs, enter no View, Logs after the execution of the script
  Logger.log(s.getName()); 
  Logger.log(r.getColumn());
  Logger.log(r.getValue());

  if(s.getName() == "Input Expenses" && r.getColumn() == 1 && r.getValue() == "Verified") {
    var row = r.getRow();
    var numColumns = s.getLastColumn();
    var rangeToAdd = s.getRange(row, 1, 1, numColumns).getValues(); //Creates an Array[][], being the first dimension the rows and the second one the columns. 
    var rangeToAddFiltered = rangeToAdd[0]; //Get the first row of the array (as we will only check one by one).
    targetSheet.appendRow(rangeToAddFiltered); //Append the Row to the new SpreadSheet (moveTo appears to work only inside the same SpreadSheet).
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
    s.deleteRow(row); //Profit!
  }
}