开发者问题收集

Google App Script:根据单元格值将一行复制并删除到 Google 表格的另一个选项卡中

2022-12-02
474

我尝试自己编写一个脚本,做了大量研究并尝试了很多代码。 此处提出的问题 中的方法似乎很有希望,但我收到了一个无法解决的错误。

问题: 我想将 工作表“Wunschliste” 中某一行的所有数据复制到 工作表“Bestellt”,其中 工作表“Wunschliste” 中的列 A2:A 标记为“2 bestellt”(通过下拉列表填写)。应删除 工作表“Wunschliste” 中标记为“2 bestellt”的所有数据。

由于此工作表不断填充数据,我想将其用作存档,因此所有新条目满足条件的,需要放在最后一个条目下。

工作表“Wusnchliste”有一个标题行,日期填写在 A:M 列中。这就是为什么我不需要复制整个工作表的原因。

我尝试的代码:

function copyRowsWithCopyTo3() {
  let spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  let sourceSheet = spreadSheet.getSheetByName('Wunschliste');
  let sourceRange = sourceSheet.getRange("A2:L" + sourceSheet.getLastRow());
  let targetSheet = spreadSheet.getSheetByName('Bestellt');
  const values = sourceRange.getValues().flatMap(([, b, c, d, , , , , i, j, k, l]) => l == "2 bestellt" ? [[b, c, d, i, j, k]] : []);
  console.log(values)
  targetSheet.getRange(targetSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
}

我得到的错误:

TypeError: Cannot read property 'length' of undefined copyRowsWithCopyTo3 @ Code.gs:8

有人可以在这里帮我吗?

我也阅读了这些文章(并对其进行了修改以进行测试): Google 脚本:根据值将行从一张工作表复制到另一张工作表

根据单元格的值复制并粘贴一行

Google Script 匹配单元格值并将相关数据复制粘贴到不同的选项卡中

2个回答

据我测试,它运行正常,只有当 L 列中没有任何匹配值时,它才会返回此错误。您可以将函数的最后一部分包装在 if 语句中:

    if(values.length>0){
        targetSheet.getRange(targetSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
    }

您还可以在末尾添加一个选项来删除源行:

function copyRowsWithCopyTo3() {
  let spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  let sourceSheet = spreadSheet.getSheetByName('Wunschliste');
  let sourceRange = sourceSheet.getRange("A2:L" + sourceSheet.getLastRow());
  let targetSheet = spreadSheet.getSheetByName('Bestellt');
  let origvalues = sourceRange.getValues()

  const values = origvalues.flatMap(([, b, c, d, , , , , i, j, k, l]) => l == "2 bestellt" ? [[b, c, d, i, j, k]] : []);
  console.log(values)
  if(values.length>0){
  targetSheet.getRange(targetSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
  }
  for (i=origvalues.length-1;i>=0;i--){
    if (origvalues[i][11]=="2 bestellt"){sourceSheet.deleteRow(i+2)}
  }

}
Martín
2022-12-02

我按照我们的讨论更新了脚本,它成功了!我还能够在菜单栏中添加此脚本。

有一件事我仍在努力:

在我将所有数据从“Wunschliste”放入“Bestellt”选项卡后,我需要能够对“Bestellt”选项卡中的数据执行相同的操作,因此,如果我将状态标记为 “Ist angekommen” ,我希望能够通过菜单触发脚本以将这些数据复制并删除到“Angekommen”选项卡。每个脚本都在为其自身工作。但是当我将它们放在一起时,它总是说找不到脚本“function copyRowsWithCopyT05”。

    function onOpen() {
  var ui = SpreadsheetApp.getUi();
  // Or DocumentApp or FormApp.
  ui.createMenu('WUNSCHLISTE BEREINIGEN')
      .addItem('Bestellte Artikel übertragen', 'copyRowsWithCopyTo3')
      .addItem('Gelieferte Artikel archivieren', 'copyRowsWithCopyTo5')
      .addToUi();}

function copyRowsWithCopyTo3() {
  let spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  let sourceSheet = spreadSheet.getSheetByName('Wunschliste');
  let sourceRange = sourceSheet.getRange("A2:N" + sourceSheet.getLastRow());
  let targetSheet = spreadSheet.getSheetByName('Bestellt');
  let origvalues = sourceRange.getValues()
 
  const values = origvalues.flatMap(([a, b, c, d, e, f, g, h , i, j, k, l, m, n]) => n == "Ja - ist bestellt" ? [[b, c, d, e, f, g, h, i, j, k, l,m]] : []);
  console.log(values)
  if(values.length>0){
  targetSheet.getRange(targetSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
  }
  for (i=origvalues.length-1;i>=0;i--){
    if (origvalues[i][13]=="Ja - ist bestellt"){sourceSheet.deleteRow(i+2)}
}
function copyRowsWithCopyTo5() {
  let spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  let sourceSheet = spreadSheet.getSheetByName('Bestellt');
  let sourceRange = sourceSheet.getRange("A2:M" + sourceSheet.getLastRow());
  let targetSheet = spreadSheet.getSheetByName('Angekommen');
  let origvalues = sourceRange.getValues()

    const values = origvalues.flatMap(([ a, b, c, d, e, f, g, h , i,j, k, l, m, n]) => l == "Ist angekommen" ? [[a, b, c, d, e, f, g, h, i, j]] : []);
  console.log(values)
  if(values.length>0){
  targetSheet.getRange(targetSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
  }
  for (i=origvalues.length-1;i>=0;i--){
    if (origvalues[i][12]=="Ist angekommen"){sourceSheet.deleteRow(i+2)} 
  }
}
}
Sarah
2022-12-05