使用触发器和手动运行的电子表格脚本

时间:2012-12-29 00:16:46

标签: google-apps-script

这应该很简单,但我坚持这个脚本...... 它有一个在时间触发器上手动运行 AND 的功能(createnewsheet),因此我必须选择openById()来访问电子表格,但是当我查看工作表并手动运行该功能时我想将新创建的工作表设置为活动状态,这就是造成我麻烦的原因。

当我从脚本编辑器运行函数(createnewsheet)时,一切都很好但是当我从电子表格菜单中调用它时,由于最后一行代码,我收到此错误消息:Specified sheet must be part of the spreadsheet。 AFAIK我没有在我的电子表格外面写一张表... 我知道在这种情况下我做错了什么吗?

以下是显示问题的简化代码,shared copy is available here

  var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dGVtYk5hWUZVUFNZMzAteE9DOUZwaVE');
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheetByName('master')
  var logsheet = ss.getSheetByName('logger')
  var FUS1=new Date().toString().substr(25,6)+":00";

function onOpen() {
    var menuEntries = [ {name: "Manual test", functionName: "createnewsheet"},
                       ];
    sheet.addMenu("Utilities",menuEntries);
    SpreadsheetApp.setActiveSheet(logsheet);// this is working fine
    }

function createnewsheet(){

    var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy")
      try{ 
    var newsheet = ss.insertSheet(sheetName,2);// creates the new sheet in 3rd position
      }catch(error){
        FUS1=new Date().toString().substr(25,6)+":00";
        var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);// creates the new sheet with a different name if already there
        }
    newsheet.getRange(1,1).setValue(sheetName);
    SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);// should make 3 rd sheet active but works only when run from script editor
//    SpreadsheetApp.setActiveSheet(newsheet);// should have same result but works only when run from script editor
}

3 个答案:

答案 0 :(得分:1)

我找到了一个实用的解决方法来解决我的用例:我在菜单中使用了一个不同的函数(我想要的setActive())并从这个函数中调用main函数。 从触发器调用时,没有必要设置任何活动工作表,所以我从主函数中删除了这部分。

它是这样的:

function manualTest(){ // from the ss menu
    createnewsheet();
    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    SpreadsheetApp.setActiveSheet(sheet.getSheets()[2]);// this works from the menu when ss is open
}

function createnewsheet(){ // from the trigger and from function manualTest()
    var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy");
      try{ 
    var newsheet = ss.insertSheet(sheetName,2);
      }catch(error){
        FUS1=new Date().toString().substr(25,6)+":00";
        var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);
        }
    newsheet.getRange(1,1).setValue(sheetName);
}

答案 1 :(得分:0)

这里有一个问题

SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);

当您从脚本编辑器运行它时,它会自动获取容器电子表格并使所述工作表处于活动状态,但从自定义菜单或触发器运行它时则不是这种情况。 将此语句修改为:

ss.setActiveSheet(ss.getSheets()[2]);
ss.setActiveSheet(newsheet);

答案 2 :(得分:0)

我找到的最佳解决方案是重新设置sheetgetActiveSpreadsheet()识别当前正在使用的电子表格,因此无需再次使用openById,但

//  SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);
//  SpreadsheetApp.setActiveSheet(newsheet);
sheet = SpreadsheetApp.getActiveSpreadsheet(); // reloads the active sheet (including changes to the Sheets array)
sheet.setActiveSheet(sheet.getSheets()[2]); // works as expected from editor and custom menu

我认为这表明原始sssheet已将电子表格缓存到内存中,并且不会刷新其指针以反映结构更改。我尝试使用.flush()作为快捷方式,但这似乎是从脚本中单页刷新,而不是相反。