连接Google表格多个工作表中的大型数据集

时间:2018-04-09 15:48:28

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

我正在使用下面的代码将我文件中的某些工作表连接到名为“Master”的工作表中。

  1. 目前,我的脚本重复了标题行,但我想阻止它。所有工作表中的数据格式完全相同,标题相同。
  2. 每张纸有58列,其中一张纸有5000行。
  3. 理想情况下,我希望每次运行脚本时脚本都会覆盖“主”表。
  4. 如何修改我的脚本以实现这些目标?

    function concatAllSheets()
    {
      var includedSheet = ['Virtue data - Norway - NOK', 'Virtue data - Sweden - SKK', 'Virtue data - Denmark - DKK', 'Virtue Data - GBP', 'Virtue data - EUR markets', 'Virtue data - Arabia - USD'];
      var ss = SpreadsheetApp.getActive();
      var allSheets = ss.getSheets();
      var sheetName = 'Master'
      var mother = ss.insertSheet(sheetName);
      for(var i = 0; i < allSheets.length; i++)
      {
        var sht = allSheets[i];
        if(includedSheet.indexOf(sht.getName()) > -1)
        {
          var rng = sht.getDataRange();
          var rngA = rng.getValues();
          for(var j = 0; j < rngA.length; j++)
          {
            var row = rngA[j];
            mother.appendRow(row);
          }
        }
      }
    }
    

2 个答案:

答案 0 :(得分:0)

不是为每一行数据调用appendRow(),而是会减慢您的脚本速度,而是使用batch operation setValues()

为此,请创建一个allData数组来保存“主”表格的内容。在遍历工作表时,将其数据附加到allData,最后将其打印到工作表中。

在迭代时,您可以对allData的长度进行简单检查,以查看标题行是否已存在。如果allData为空,则显然没有标题行。

function concatAllSheets()
{
  var includedSheet=['Virtue data - Norway - NOK','Virtue data - Sweden - SKK','Virtue data - Denmark - DKK','Virtue Data - GBP','Virtue data - EUR markets','Virtue data - Arabia - USD'];
  var ss=SpreadsheetApp.getActive();
  var allSheets=ss.getSheets();
  var sheetName='Master'
  var mother=ss.insertSheet(sheetName);
  var allData = [];
  for(var i=0;i<allSheets.length;i++)
  {
    var sht=allSheets[i];
    if(includedSheet.indexOf(sht.getName())>-1)
    {
      var rng=sht.getDataRange();
      var rngA=rng.getValues();
      if (allData.length == 0) // This will only ever be true on the first sheet copied
      {
        allData = rngA;
      } else {
        rngA.shift(); // Remove the first row
        allData = allData.concat(rngA);
      }
    }
  }
  mother.getRange(1, 1, allData.length, allData[0].length).setValues(allData); // Use a batch operation to insert the data
}

答案 1 :(得分:0)

考虑到数据集的大小,您需要使用批处理方法Range#getValuesRange#setValues来最小化读取和写入。您还可以使用Array#forEach仅通过绑定名称数组中的那些来避免迭代不必要的工作表。此模式还可确保您收集所有您想要的数据 - 如果您的名称数组中存在拼写错误,或者表单的名称无意中更改,则会抛出异常,而不是静默地不包括数据。

function concatenateSheets() {
  var sheetNames = ["name1", "name2", ...];
  var ss = SpreadsheetApp.getActive();
  var dest = ss.getSheetByName("someName");
  var output = [], header = [];
  // Assemble a single paste output from all the sheets.
  sheetNames.forEach(function (name) {
    var sheet = ss.getSheetByName(name);
    if(!sheet)
      throw new Error("Incorrect sheet name '" + name + "'");
    var vals = sheet.getDataRange().getValues();
    // Remove the header row. 
    header = vals.splice(0, 1);
    // Append to existing output array.
    output = [].concat(output, vals);
  });
  // Serialize output data array.
  if(dest && output.length && output[0].length) {
    // Remove all existing data values on the destination sheet.
    // (Only necessary if the number of rows or columns can decrease.)
    dest.getDataRange().clearContent();

    // Prepend the header on the output data array.
    output.unshift(header);

    dest.getRange(1, 1, output.length, output[0].length).setValues(output);
  }
}