首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Google根据列的值将行复制到动态创建的选项卡中

Google根据列的值将行复制到动态创建的选项卡中
EN

Stack Overflow用户
提问于 2020-01-22 21:12:27
回答 2查看 1K关注 0票数 0

首先,我是一名教师和自学自己的应用程序脚本,所以请原谅我的草率代码。我所在地区经常进行的标准化测试的结果通常都与所有的测试合并在一起。如果每个测试都在各自的试卷中,那么管理起来就容易多了。

我修改了在这个站点上找到的函数,为测试列(M)中的每个唯一值创建一个新选项卡。它负责将行复制到选项卡中。它使用数组,老实说,我并不完全理解它。

代码语言:javascript
运行
复制
function createNewSheets() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var masterSheet = spreadsheet.getSheetByName('Sheet1');
  var source_range = masterSheet.getRange("A1:AD1"); //header row

  // Retrieve 2d array for column M
  var colA = masterSheet.getRange('M2:M').getValues();

  // Create a 1d array of unique values
  var uniqueValues = {};
  colA.forEach(function(row) {
    row[0] ? uniqueValues[row[0]] = true : null;
  });
  var newSheetNames = Object.keys(uniqueValues);

  newSheetNames.forEach(function(sheetName) {
    // Check to see whether the sheet already exists
    var sheet = spreadsheet.getSheetByName(sheetName);
    if (!sheet) {
      spreadsheet.insertSheet(sheetName); //inserts new sheet
      source_range.copyTo(spreadsheet.getSheetByName(sheetName).getRange("A1:AD1")); //writes header row to newly created sheet
    }
  });
}

为了将正确的行放入相应的选项卡,我最终使用了else语句。然而,这意味着我必须预测第一个函数将要创建的所有不同的选项卡,然后在运行它之前修改我的代码。这也是相当缓慢,但可以容忍。虽然这是可行的,但必须有更好的办法。如果有人有什么建议的话,我会很感激的。

代码语言:javascript
运行
复制
function copyRows() {
  var sSheet = SpreadsheetApp.getActiveSpreadsheet();
  var srcSheet = sSheet.getSheetByName("Sheet1"); 
  var lastRow = srcSheet.getLastRow();

  for (var i = 2; i <= lastRow; i++) {
    var srcRange = srcSheet.getRange("A" + i + ":AD" + i);
    var cell = srcSheet.getRange("M" + i);
    var val = cell.getValue();

  //sets the target sheet depending on the exam in column M

    if (val == "Growth: Language 2-12 KS 2017") {
      var tarSheet = sSheet.getSheetByName("Growth: Language 2-12 KS 2017");
    }

    else if (val == "Growth: Math 2-5 KS 2017") {
      var tarSheet = sSheet.getSheetByName("Growth: Math 2-5 KS 2017");
    }  

    else if (val == "Growth: Reading 2-5 KS 2017") {
      var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
    } 

    else if (val == "Growth: Reading K-2 KS 2017") {
      var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
    } 

    else if (val == "Growth: Math K-2 KS 2017") {
      var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
    } 

    else {
    }
  //insets the row in the correct target worksheet  
      var tarRow = tarSheet.getLastRow()+1;
      tarSheet.insertRows(tarRow);
      var tarRange = tarSheet.getRange("A" + (tarRow) + ":AD" + (tarRow));
      srcRange.copyTo(tarRange);    
  }
};

这里有一个链接到带有虚拟数据的工作表。我的实际工作表可以有1500到2000行以上的8或更多的测试。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-23 10:13:48

如果我对你的理解是正确的,你想要一个函数:

  • 为每个不同的Assessment Name (来自Sheet1M列)创建一个新的工作表。
  • 将每个Assessment Name对应的行追加到相应的已创建工作表中。

如果是这样的话,那么您可以迭代Sheet1中的所有数据,对于每一行,检查电子表格中是否有一个表的名称等于相应的评估名称。

如果存在这样的工作表,则脚本将当前行追加到目标工作表的末尾。

如果工作表不存在,它首先创建顶部有标题的工作表,然后追加当前行。

这是通过使用appendRow(rowContents)来实现的。

您的代码可以大致如下所示:

代码语言:javascript
运行
复制
function createNewSheets() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var masterSheet = spreadsheet.getSheetByName('Sheet1');
  // Get range with data from original sheet:
  var firstRow = 1;
  var firstCol = 1;
  var numRows = masterSheet.getLastRow();
  var numCols = masterSheet.getLastColumn();
  var data_range = masterSheet.getRange(firstRow, firstCol, numRows, numCols).getValues();
  // Get headers row (to be appended on top when new sheet is created):
  var headers = data_range[0];
  // Iterate through all rows of data from Sheet1:
  for (var i = 1; i < data_range.length; i++) {
    var row = data_range[i]; // Current row
    var assessmentName = row[12]; // Assessment name
    // Get sheet with current assessment name:
    var sheet = spreadsheet.getSheetByName(assessmentName);
    // Check if sheet with current assessment name exists. If it doesn't it creates it:
    if (!sheet) {
      sheet = spreadsheet.insertSheet(assessmentName);
      sheet.appendRow(headers);
    }
    // Appends current row of data to the new sheet:
    sheet.appendRow(row);
  }
}

此外,如果希望避免重复每次运行脚本时附加的行,则主表的最后一列中可以有一列,该列跟踪哪些行已复制到新工作表,如果已复制,则避免再次追加它们。例如,您可以在AC中有一个名为Copied的列标题。然后,当该行被追加时,该行将被填充,例如,字符串“已完成”。下一次运行脚本时,它可以检查相应的单元格是否具有“已完成”的值。

例如,您可以从以下内容更改函数的结尾:

代码语言:javascript
运行
复制
    // Appends current row of data to the new sheet:
    sheet.appendRow(row);
  }
}

对此:

代码语言:javascript
运行
复制
    // Appends current row of data to the new sheet if `AC` column value is not "Done":
    if (row[28] != "Done") {
      sheet.appendRow(row);
      masterSheet.getRange(i + 1, 29).setValue("Done");    
    }
  }
}

我希望这有什么帮助。

票数 0
EN

Stack Overflow用户

发布于 2020-01-23 00:51:54

此函数可以替换复制行脚本,并且它运行速度应该要快得多。

代码语言:javascript
运行
复制
function copySheets() {
  var keyA=["Growth: Language 2-12 KS 2017", "Growth: Math 2-5 KS 2017", "Growth: Reading 2-5 KS 2017", "Growth: Reading K-2 KS 2017", "Growth: Math K-2 KS 2017"];
  var shtA=["Growth: Language 2-12 KS 2017", "Growth: Math 2-5 KS 2017", "Growth: Reading 2-5 KS 2017", "Growth: Reading K-2 KS 2017", "Growth: Math K-2 KS 2017"];
/*
I made the above arrays to different one in the event that you ever wish to change the mapping.

The code below gets all of the data on the source sheet from column1 to column 30 and row 2 to the last row.  Whenever you have a startrow that is not 1 you need to subtracting off the rows above the start row from the sheet.getLastRow() because the third parameter for get range is not the last row but the number of rows.

This code get all of the data in one two dimensional array and sticks it into the target range all at one time.  In my experience you should see a 10x increase in performance.
*/
  var ss=SpreadsheetApp.getActive();
  var srcsh=ss.getSheetByName("Sheet1"); 
  var vA=srcsh.getRange(2,1,srcsh.getLastRow()-1,30).getValues();
  var keyToSheet={};
  keyA.forEach(function(key,i){keyToSheet[key]=shtA[i];})
  var tarsh=ss.getSheetByName(keyToSheet(val));
  var tarrg=tarsh.getRange(2,1,vA.length,vA[0].length).setValues(vA);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59868326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档