0

这应该很简单,但我被困在这个脚本上......它有一个手动运行并在时间触发器上运行的函数(createnewsheet),所以我不得不选择openById()访问电子表格,但是当我查看工作表并运行时手动功能我想将新创建的工作表设置为活动状态,这就是给我带来麻烦的原因。

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

这是显示问题的简化代码,此处提供共享副本

  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
}
4

3 回答 3

1

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

它是这样的:

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);
}
于 2012-12-29T15:08:18.923 回答
0

这里有一个问题

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

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

ss.setActiveSheet(ss.getSheets()[2]);
ss.setActiveSheet(newsheet);
于 2012-12-29T02:52:11.107 回答
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() 作为快捷方式,但这似乎是从脚本刷新工作表的一种方式,而不是相反的方式。

于 2012-12-30T17:14:50.500 回答