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

Posted

技术标签:

【中文标题】如何将脚本创建的工作表的名称写入该工作表中的单元格?【英文标题】:How to write the name of script-created sheet to a cell in that sheet? 【发布时间】:2016-09-02 22:38:01 【问题描述】:

我是一名教师,我经常需要抄写空白评分标准,班级中每个学生一份。量规是谷歌表格。我拼凑了一个脚本,它将 (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】:

您的脚本确实成功地设置了单元格 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]);
  

【讨论】:

太棒了! 'Spreadsheetapp.flush()' 成功了。此外,您的代码比我的更精简、更优雅(这是我第二次或第三次尝试编写脚本;我有很多东西要学)。非常感谢您的帮助。 @murph - 很高兴能够提供帮助 :)

以上是关于如何将脚本创建的工作表的名称写入该工作表中的单元格?的主要内容,如果未能解决你的问题,请参考以下文章

将工作表的选项卡名称链接到 Excel 中的单元格

VBA中如何引用另一工作表中的单元格区域

将超链接放在单元格中以转到同一工作表的另一张表的脚本

(Excel) 引用另一个工作表中的单元格时,我可以将工作表名称作为单元格值传递吗?

匹配多个工作表中的单元格

Excel:如何创建快捷方式/浮动按钮以从工作表中的任何位置填充特定单元格?