0

これは単純なはずですが、私はこのスクリプトに行き詰まっています...手動でタイムトリガーで実行される関数(createnewsheet)があるため、スプレッドシートにアクセスすることを選択するopenById()必要がありましたが、シートを見て実行したとき機能を手動で新しく作成したシートをアクティブに設定したいのですが、それが問題の原因です。

スクリプト エディターから関数 (createnewsheet) を実行するとすべて問題ありませんが、スプレッドシート メニューから関数を呼び出すとSpecified sheet must be part of the spreadsheet、コードの最後の行が原因で次のエラー メッセージが表示されます。私の知る限り、スプレッドシート以外のシートに対処していません... このコンテキストで何が間違っているのか分かりますか?

問題を示す簡略化されたコードを次に示します。共有コピーはこちらから入手できます

  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

私が見つけた最善の解決策は、再シードすることsheetです。getActiveSpreadsheet()現在使用中のスプレッドシートを認識するため、もう一度 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

ssこれは、元のスプレッドシートがメモリにキャッシュされsheetていて、構造の変更を反映するためにポインターが更新されていないことを示唆していると思います。ショートカットとして .flush() を試しましたが、それはスクリプトからシートへの一方向の更新であり、その逆ではないようです。

于 2012-12-30T17:14:50.500 に答える
0

ここに落とし穴があります

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

スクリプトエディタから実行すると、自動的にコンテナスプレッドシートを取得して当該シートをアクティブにしますが、カスタムメニューやトリガーから実行する場合はそうではありません。このステートメントを次のように変更します。

ss.setActiveSheet(ss.getSheets()[2]);
ss.setActiveSheet(newsheet);
于 2012-12-29T02:52:11.107 に答える