如何使用onChange触发器确定工作表中插入的行数?

时间:2019-03-28 20:08:15

标签: google-apps-script google-sheets google-apps-script-editor

我想将一些数据从电子表格复制到另一个电子表格。第一列通常在大小上有所变化,第二列从第一列开始有几列,然后其他列都有自己的数据。

我想根据第二行中插入或删除的行在第二行中插入/删除行。它们必须匹配先前的数据。

我尝试使用onChange触发器来检测何时检测到INSERT_ROW或REMOVE_ROW changeType。当仅插入一行时,它工作正常,但当它们插入多个时,效果不佳。同样,当他们插入一行并且撤消之后,动作changeType是EDIT而不是REMOVE_ROW。失败。

然后,我决定在每行中添加一个带有索引编号的隐藏列,因此,如果第5行和第6行之间的数字之间存在空格,这意味着我必须在第5行之后的第二张表中插入3行,然后我重建索引以检查进一步的更改...如果删除了几行,它也可以工作。

在我意识到用户可以复制行或复制/粘贴整行然后使用新信息修改数据之后,该方法似乎工作正常,但是索引也会被复制,并且当我检查差异以检查是否存在任何差异时行已被删除,然后失败。

第一次尝试:

  if (event.changeType == 'INSERT_ROW' && tab =='Hoja 1') {
    for (var i = 0 ; i < indexes.length ; i++) {
      if (indexes[i] =='') {
        destSheet.insertRowAfter(i+1);
      }
    }
  }
  if (event.changeType == 'REMOVE_ROW' && tab =='Hoja 1') {
    for (var i = 0 ; i < indexes.length ; i++) {
      if (indexes[i]-indexes[i+1] < -1 && indexes[i] != 0) {
        if (indexes[i] != lastRow) {
          destSheet.deleteRows(i+3,(indexes[i]-indexes[i+1])*-1-1)
        }
      }
    }
  }
  for (var j = 0; j < lastRow-1; j++) {
    indexs.getCell(j+1, 1).setValue(j+1);
  }
}

第二次尝试:

function checkLines (sheet, destSheet)  {
  for (var i = 0 ; i < indexes.length ; i++) {
    if (indexes[i] =='') {
      destSheet.insertRowAfter(i+1);
    }
    if (indexes[i]-indexes[i+1] < -1 && indexes[i] != 0) {
      if (indexes[i] != lastRow) {
        destSheet.deleteRows(i+3,(indexes[i]-indexes[i+1])*-1-1)
      }
    }
  }
}

我想在目标工作表中复制源工作表中选定列的副本,如果第一个更改了它的行,则第二个中应该发生同样的事情。

在某些情况下,目的地并没有被确定,因此,下栏中写的信息与前几栏中的信息不匹配。

以下是到源工作表示例的链接: https://docs.google.com/spreadsheets/d/19OnwKIEm2OFymjsjqeoQYWcA9BNAJTM0ap2rdpQlZoQ/edit?usp=sharing

这里是目的地: https://docs.google.com/spreadsheets/d/10vbMIqQE1miNfuJXQ1f_MSJnVs9MJrAOcg5_ZrAPWP8/edit?usp=sharing

我将不胜感激任何建议... 并且,如果您需要进一步的说明,请告诉我...英语不是我的母语,并且我不确定您是否理解我的问题。

非常感谢您。

V。

2 个答案:

答案 0 :(得分:0)

您可以使用以下内容:

function initRows() {//run once before first use
  var lastrow=SpreadsheetApp.getActiveSheet().getLastRow();
  PropertiesService.getScriptProperties().setProperty('ROWS',lastrow);
  return lastrow;
}

function getRows() {
  return PropertiesService.getScriptProperties().getProperty('ROWS');
}

function setRows(value) {
  PropertiesService.getScriptProperties().setProperty('ROWS',value);
}

function detectRowChange(e) {//attach to onChange installable trigger
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getActiveSheet();
  var number=Math.abs(getRows()-sh.getLastRow());
  var html=Utilities.formatString('Change Type: %s Number: %s', e.changeType,number);
  var ui=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(ui, 'Change');
  setRows(sh.getLastRow());
}

这利用对话框来识别更改的类型和生效的行数。您可能会想要针对您的特定需求对其进行自定义。设置触发器之前,请不要忘记运行initRows()。

PropertiesService

答案 1 :(得分:0)

活动范围1具有插入的行数。

摘要:

function onChange(e){
  if (e.changeType === 'INSERT_ROW'){
    const rng = SpreadsheetApp.getActiveRange();
    const row = rng.getRow();//Row where insert row is done
    const lrow = rng.getLastRow();//Last row in the newly active range
    const numRows = 1+lrow-row;//number of rows inserted
  }
}

还要查看将开发人员元数据2添加到行中,以便在移动行时,您可能能够识别出来。

  

我想在目标工作表中复制源工作表中选定列的副本,如果第一个更改了它的行,则第二个中应该发生同样的事情。

最简单的方法是获取所有数据并将其粘贴到目标表(getValuessetValues)中。