如何将脚本创建的工作表的名称写入该工作表中的单元格?

时间:2016-09-02 22:38:02

标签: google-apps-script google-sheets

我是老师,我经常需要复制空白评分标准,每班学生一份。标题是Google表格。我拼凑了一个脚本,该脚本将(1)访问包含课程名单的另一张表,(2)阅读学生'名单上的名字,以及(3)为每个学生创建一个新的电子表格,并以学生的名字作为文件名保存。所有这些都有效(由于某些原因,它的速度非常慢,但它确实有效)。

现在,我试图将学生的名字写在该学生的专栏副本上。我的想法是将学生的姓名写在原始标题上的相关单元格中,然后以学生的名义保存该副本。但那部分不起作用;单元格中的名称与文件名不匹配。相反,单元格中的名称与之前学生的姓名相匹配。这是代码:

function onerubricperstudent(){

//"roster" is the roster spreadsheet. Change the value in quotation marks to whatever your roster's ID is.  
  var roster = SpreadsheetApp.openById("1SN2x6bKzga6bRwwvt5diuaETBiXeHqY7bLJMY5If9js");

//"sheet" is sheet to be copied  
  var sheet = SpreadsheetApp.getActiveSpreadsheet();

//range is the range on the roster sheet containing the student names  
  var range = roster.getRange('Sheet1!A1:A17'); 

//do this as many times as there are students in the class
  for (var i = 1; i < 18; i++) {

//get the next student name    
    var studentname = range.getCell(i, 1);



//log the name (for troubleshooting if the script fails)
    Logger.log(studentname.getValue());


//Write the student's name to the name cell on the sheet

    sheet.getRange('B2').setValue(studentname.getValue());


//Make a copy of the sheet and save it with the student's name    
    DriveApp.getFileById(sheet.getId()).makeCopy(studentname.getValue());
  }
}

无法正常工作的行是:

sheet.getRange('B2').setValue(studentname.getValue());

我做错了什么?

注意:作为一种解决方法,我添加了这个OnOpen脚本,当我打开标题来评估学生的工作时,它会将工作表名称复制到学生姓名单元格:

function onOpen() {
  var sheetname = SpreadsheetApp.getActive().getName();
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  sheet.getRange('B2').setValue(sheetname);

}

这可以完成工作,但我仍然想知道原始代码有什么问题。

谢谢!

1 个答案:

答案 0 :(得分:2)

您的脚本确实成功设置了单元格B2的值,但电子表格的副本不包含待处理的更改。为了在for循环中复制挂起的更改,您似乎必须调用SpreadsheetApp.flush()。这将应用所有待处理的电子表格更改(see docs on flush())。

以下是一些代码:

function onerubricperstudent(){

  var roster = SpreadsheetApp.openById("YOUR-ROSTER-SHEET-ID-HERE");
  var rubricSheet = SpreadsheetApp.getActiveSpreadsheet();
  var rubricFile = DriveApp.getFileById(rubricSheet.getId());

  // replace the worksheet name and desired range with your name/range below
  var range = roster.getRange('Roster Master!A2:A21'); 
  var studentNames = range.getValues();

  for (var i = 0; i < studentNames.length; i++) {
    rubricSheet.getRange('B2').setValue(studentNames[i]);

    // SpreadsheetApp.flush() "forcefully" applies all pending Spreadsheet changes.
    SpreadsheetApp.flush();

    rubricFile.makeCopy(studentNames[i]);
  }
}

您还注意到使用DriveApp创建副本似乎很慢。这也是我的经历。不幸的是,我不认为这可以被优化(如果有人有提示 - 看到它们会很棒)。这里有另一个问题:Google Apps Script : copying spreadsheet is very slow(但答案并非超级有用)。

以下是一个选项:如果您不需要单独的电子表格文件,则可能需要考虑在同一电子表格中制​​作新工作表。这将显着更快。

以下是一些代码:

function onerubricperstudent(){

  var roster = SpreadsheetApp.openById("YOUR-ROSTER-SHEET-ID-HERE");
  var rubricSpreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  var rubricFile = DriveApp.getFileById(rubricSpreadSheet.getId());

  // replace the sheet name with the name of the sheet you want to use as a template
  var templateSheet = rubricSpreadSheet.getSheetByName("Rubric Master");

  var range = roster.getRange('Roster Master!A2:A4'); 
  var studentNames = range.getValues();

  for (var i = 0; i < studentNames.length; i++) {
    var newSheet = rubricSpreadSheet.insertSheet(studentNames[i], i+1, {template: templateSheet})
    newSheet.getRange('B2').setValue(studentNames[i]);
  }
}