如何将数据附加到Google Apps脚本中的行尾

时间:2017-02-27 15:30:53

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

我们的一所高中正在尝试为目前未通过一门或多门课程的学生创建每周报告。报告的格式如下。

如果学生多班失败,则信息在不同的行上。需要将这些信息组合在一起,每个学生都在一列中 - 第1列是名称,后续列是等级/班级/教师信息。

目前,我有删除空白工作表的代码,创建一个标题为“输出”的新工作表,写入标题行,并在第1列中写入唯一的名称(注释掉的部分因此不会创建重复的“输出”工作表每一次):

function copyRows() {
  //Initialize variables
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Sheet1");

/*  
  //Create output Sheet
  ss.insertSheet("Output");
  */
  var writeSheet = ss.getSheetByName("Output");
  /*

  //Delete unwanted columns (1, 3, 4, 7, 9)
  dataSheet.deleteColumn(1); //Deletes first column
  dataSheet.deleteColumn(2); // Deletes third column (because it shifts after every deletion)
  dataSheet.deleteColumn(2); //Deletes fourth column
  dataSheet.deleteColumn(4); //Deletes 7th column
  dataSheet.deleteColumn(5);//Deletes 9th column


  //Delete unwanted Sheets
  var deleteSheet2 = ss.getSheetByName("Sheet2");
  var deleteSheet3 = ss.getSheetByName("Sheet3");
  ss.deleteSheet(deleteSheet2);
  ss.deleteSheet(deleteSheet3);  

  //Write data to header row
  var headerRange = writeSheet.getRange("A1:V1");
  var headerValues = [
    ["name", "class1", "grade1", "teacher1","class2", "grade2", "teacher2","class3", "grade3", "teacher3","class4", "grade4", "teacher4","class5", "grade5", "teacher5","class6", "grade6", "teacher6","class7", "grade7", "teacher7"]
    ]
  headerRange.setValues(headerValues);
  */

  var lastRow = dataSheet.getLastRow();
  var mainArray = dataSheet.getRange(1, 1, lastRow, 4).getValues();

  var allNames = []; //List of all names, including duplicates
  var uniqueNames = []; //List of all unique names

  for (i = 0; i < mainArray.length; i++) { //Sets allNames
    allNames.push(mainArray[i][0]);
  }

  for (i = 0; i < allNames.length; i++) { //Sets uniqueNames
    if (allNames[i+1] != allNames[i]) {
      uniqueNames.push(allNames[i]);
    }
  }
  var uniqueNamesArray = uniqueNames;


  //New method that converts 1d array to 2d array

  Array.prototype.reshape = function(rows, cols) {
    var copy = this.slice(0); // Copy all elements.
    this.length = 0; // Clear out existing array.

    for (var r = 0; r < rows; r++) {
        var row = [];
        for (var c = 0; c < cols; c++) {
            var i = r * cols + c;
            if (i < copy.length) {
                row.push(copy[i]);
            } 
        }
      this.push(row);
    }
  };
  var uniqueNamesRow = uniqueNames;
  uniqueNames.reshape(uniqueNames.length, 1); //Changing uniqueNames from row to column


  var writeNamesRange = writeSheet.getRange(2,1,uniqueNames.length,1); //writeSheet column 1
  writeNamesRange.setValues(uniqueNames);

示例数据:

  1. John Doe 50乐队Dean先生
  2. Mary Smith 60美国历史琼斯女士
  3. Mary Smith 25 Chemistry Dyar女士
  4. Mary Smith 40 Algebra 2 Harris女士
  5. Bob Miller 55乐队Dean先生
  6. 拉里·琼斯22代数2哈里斯女士
  7. 输出:

    1. John Doe 50乐队Dean先生

    2. Mary Smith 60美国历史琼斯女士25化学女士Dyar 40代数2 Harris女士

    3. Bob Miller 55乐队Dean先生

    4. 拉里·琼斯22代数2哈里斯女士
    5. 请注意,Mary Smith的数据已合并为一行。

      我无法弄清楚如何遍历行并将数据附加到相应行的末尾。

      对于之前缺乏详细信息感到抱歉,并感谢您的反馈。

2 个答案:

答案 0 :(得分:0)

我根据您的输入和输出(而不是您的代码)编写了一些代码。由于学生的名字是主键,我认为词典数据结构在这里是合适的。下面的代码并不那么优雅,许多文字都是硬编码的,但我想你能掌握这个想法。样本表为here

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('input');
  var rows = 6;
  var cols = 4;
  var input = ss.getRange(1,1, rows,cols).getValues();

  var students = [];
  for(var i = 0; i < input.length; i++) {
    var name = input[i][0];
    var class = {
      score: input[i][1],
      class: input[i][2],
      teacher: input[i][3]
    };

    var j;
    for(j = 0; j < students.length; j++) {
      if(students[j].name == name) {
        students[j].classes.push(class);
        break;
      }
    }
    if(j == students.length) {
      students.push({
        name: name,
        classes: [class]
      });
    }
  }

  var ts = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('output');

  var output = [];
  for(var i = 0; i < students.length; i++) {
    output[i] = [students[i].name];
    for(var j = 0; j < students[i].classes.length; j++) {
      output[i].push(students[i].classes[j].score,
                     students[i].classes[j].class,
                     students[i].classes[j].teacher);
    }
    ts.getRange(i+1,1, 1,output[i].length).setValues([output[i]]);
  }
}

答案 1 :(得分:0)

我尝试了一段时间,然后想出了另一种方法。下面以防有人觉得有用,我还添加了一些评论

function appendToRecords2() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetWithNewData = ss.getSheetByName("New");
  var sheetWithExistingData = ss.getSheetByName("Existing")
  // Defines the range where the NEW DATA is located
  var newData = sheetWithNewData.getRange("a2:b25") 
                              .getValues();
  var lastRow = sheetWithExistingData.getLastRow();
  sheetWithExistingData.getRange(lastRow + 1, 1, 24, 2)
              .setValues(newData);

/* 
Parameters for the last to one row
   1st = +1, this is always the same. This indicates that it's last row + 1
   2nd = The column where to copy the data, normally 1
   3rd = The number of rows that contains the new data. This is pretty much the same as the rage defined in getRange
   4th = The number of columns that contains the data, same as above
*/

}

重要提示:@jvdh的全部功劳归功于他在Script to append range of data in Google Sheets的回答。我只做了一些小改动,并添加了注释说明