当前位置: 首页 > 知识库问答 >
问题:

将已完成的行移动到新工作表的Google工作表脚本

东方修谨
2023-03-14

我有一个脚本,当数据被添加到列“我”时,它将数据从一个工作表移动到另一个工作表。

我想调整脚本,以执行将所有行(值)从未支付的工作表(其中列I不是空的)通过按钮按钮移动到已支付的工作表,而不是在编辑时。这将允许一次从多行移动数据,而不是使用一次只移动一行的当前脚本。

有人能帮忙吗?

function onEdit(event) {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = event.source.getActiveSheet();
  var r = event.source.getActiveRange();


  if(s.getName() == "Unpaid" && r.getColumn() == 9 && r.getValue() != "") {
    var row = r.getRow();
    var numColumns = 11;
    var targetSheet = ss.getSheetByName("Paid");
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
    s.getRange(row, 1, 1, numColumns).copyTo((target),{contentsOnly:true});
    s.deleteRow(row);
  } 
  else if(s.getName() == "Paid" && r.getColumn() == 14 && r.getValue() == false) {
    var row = r.getRow();
    var numColumns = s.getLastColumn();
    var targetSheet = ss.getSheetByName("Unpaid");
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
    s.getRange(row, 1, 1, numColumns).moveTo(target);
    s.deleteRow(row);
  }
}

附带说明,脚本的“如果”部分旨在将代码移回原始工作表。这是不需要的,但我无法删除这部分代码并保持功能。

共有1个答案

金兴朝
2023-03-14

>

  • 第一步是在未付费表中查找列I不为空的行。为了实现这一点,您可以对列I的每个元素应用三元运算符。更详细地说,您可以使用map()函数来检查元素是否为空,然后应用filter()来仅选择具有非空值的行第一栏中的值:

    const movRows =  iVals.map((c,i)=>c!=''?i:null).filter(f=>f!=null);
    

    movRows包含列I不为空的索引。要获得实际的行,您需要在movRows的元素中添加2,因为我们从第二行开始I2:I

    下一步是迭代movRows数组,对于每个元素,删除Unpaid工作表中的行,并将其移动到Paid工作表中。我们不是直接移动它,而是将数据推送到movData数组中,然后使用此数组传输数据以提高效率。

    迭代需要向后进行,否则每次删除一行时,实际数据和工作表结构之间都会不匹配。

    要在UI中创建按钮,可以使用onOpen()触发器。您只需将以下脚本保存到脚本编辑器中,然后UI(电子表格)中将显示一个自定义菜单按钮。您可以单击该按钮执行transfer()函数。

    function transfer() {
    
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const pSh = ss.getSheetByName('Paid');
    const upSh = ss.getSheetByName('Unpaid');
    const numColumns = 11;
    const iVals = upSh.getRange('I2:I'+upSh.getLastRow()).getValues().flat();  
    const movData = [];
    const movRows =  iVals.map((c,i)=>c!=''?i:null).filter(f=>f!=null);
    movRows.reverse().forEach(row=>{ 
        movData.push(upSh.getRange(row+2,1,1,numColumns).getValues()[0]);
        upSh.deleteRow(row+2);                                    
      });   
    pSh.getRange(pSh.getLastRow()+1,1,movData.length,movData[0].length).setValues(movData);   
    }
    

    使用onOpen触发器创建自定义菜单按钮:

    function onOpen() {
      SpreadsheetApp.getUi()
      .createMenu('Macros')
      .addItem('Transfer Rows', 'transfer')
      .addToUi();
    }
    

  •  类似资料:
    • 我正在使用谷歌表单来触发这个脚本。 当我用播放按钮运行脚本时,它工作得很好。 当我让提交触发器运行它时,复选框填充正常,但setValue日期没有。 我也试过了但是我得到了相同的结果。 最终目标是让J列在每次提交表单时填充A列中的快照格式日期 我需要此格式在另一张工作表上运行countIfs。 另一种选择是以某种方式将格式标记嵌入到CountIfs命令中,以便它们匹配。

    • 有人能帮我把脚本布局转换成实际的功能代码吗?我有一般的编码知识,但我不知道正确的语法。 基本上,我需要的是一个脚本,当提交表单条目时,它会在所有工作表/选项卡之间循环。表单包含提交表单的人的姓名(字符串)、开始日期、结束日期,最后是注释字段(字符串)。 我需要脚本来遍历每个工作表的第5行,并查找在第一个表单字段中输入的字符串(提交表单的人的姓名)。如果它找到了该名称,它应该将与该名称对应的列保存到

    • 我试图将活动工作表和2个指定工作表复制到一个新工作簿,然后让宏继续在新工作簿上运行,以便在保存它之前更改一些内容 null

    • 是否有一种方法可以扫描多个Google工作表,从键上的主工作表中找到匹配项,并在适用的情况下更新Google工作表中的单元格? 例如,下面我有4张。第一个是主人,其他的是孩子。如果来自Master的任何工作表的A列(倡议名称)上有匹配,则更新C列(金额)和D列(日期)中的单元格,否则保持工作表不变。在本例中,船长的倡议名称为“G”,金额为“50”,日期为“2020年1月4日”。儿童1的倡议名称为“

    • 我有两个工作表,我将经常在它们之间移动数据。在Sheet1上,我有我所有的数据,复选框用于将相同的数据发送到Sheet2。当数据发送过来时,会留下空行,这样我就知道在一天结束时重建工作表时有哪些位置可用。 Sheet2上的数据将被修改,在一天结束时,我想将所有内容移回Sheet1,以获得第一个可用的空行。我的第一部分工作正常,但我似乎无法将数据移回Sheet1中的第一个可用单元格(空单元格)。 当

    • 我有一个多标签谷歌表。第一个是主表,我有一些基本的位置信息。在其他页面中,我通过“导入”传输这些基本信息,因此我有一些列动态更改,一些是静态的,用户可以更新。尽管如此,如果我在主工作表的数据之间添加一行,它只会更改动态列(从importrange更新),而其余列不会更改-这会影响更新。在主工作表中添加行时,是否有任何方法/脚本可以自动在其他工作表中添加行?