3


学校用のコンテナーにバインドされた Google Apps スクリプトを作成しています。学校では、すべての書面に「学校の見出し」を付ける必要があります。学校はピリオドとしてブロック AG を使用します。私の目標は、「学校の見出し」というメニューがあり、開くと「A ブロック」、「B ブロック」、「C ブロック」というサブメニューがあり、各サブメニューには各クラスのオプションがあることです。そのクラスの見出しをドキュメントの見出しに挿入します

これが私のコードです:

var BLOCKS = "abcdefg";
var CLASSES = ["English", "History", "Science", "Writing", "Latin", "Math", "Study Skills"];
var FUNCTION_NAMES;
var global = {};

init();

/**
 * The onOpen function runs automatically when the Google Docs document is
 * opened. Use it to add custom menus to Google Docs that allow the user to run
 * custom scripts. For more information, please consult the following two
 * resources.
 *
 * Extending Google Docs developer guide:
 *     https://developers.google.com/apps-script/guides/docs
 *
 * Document service reference documentation:
 *     https://developers.google.com/apps-script/reference/document/
 */
function onOpen() {
  init();
  // Add a menu with some items, some separators, and a sub-menu.
  var menu = DocumentApp.getUi().createMenu('School Heading')
  for(var i = 0; i < BLOCKS.length; i++){
    block = BLOCKS[i];
    Logger.log("Block: " + block)
    menu = menu.addSubMenu(DocumentApp.getUi().createMenu(block + " Block")
                           .addItem('English', 'eng' + block)
                           .addItem('History', 'his' + block)
                           .addItem('Science', 'sci' + block)
                           .addItem('Writing', 'wri' + block)
                           .addItem('Latin', 'lat' + block)
                           .addItem('Math', 'mat'  + block) 
                           .addItem('Study Skills', 'stu' + block));
    defineFunctions(block, this);
  }
  menu.addToUi();
}

function getFunc(class,block){
  return function(){
    createHeading(class,block);
  }
}

function defineFunctions(block, global){
  Logger.log(FUNCTION_NAMES)
  for(var i = 0; i < FUNCTION_NAMES.length; i++){
    var funcName = FUNCTION_NAMES[i] + block;
    eval("function " + funcName + " () { createHeading('"+ CLASSES[i] + "', '" + block + "'); }");
  }
}

function createHeading(class, block){
  var header = DocumentApp.getActiveDocument().getHeader();
  if(!header){
    header = DocumentApp.getActiveDocument().addHeader();
  }
  header.insertParagraph(0, "Name\n{class}, Block {block}".replace("{class}", class).replace("{block}", block)).setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
}

function init(){
  if(!Array.isArray(BLOCKS)){
    BLOCKS = BLOCKS.toUpperCase().split("");
  }
  if(!Array.isArray(CLASSES)){
    CLASSES = CLASSES.split("\n");
  }
  if(!Array.isArray(FUNCTION_NAMES) || FUNCTION_NAMES.length !== CLASSES.length){
    FUNCTION_NAMES = [];
    for(var i = 0; i < CLASSES.length; i++){
      FUNCTION_NAMES.push(CLASSES[i].toLowerCase().substring(0,3));
    }
  }
}

School Heading > A Block > Englishを選択すると、「Script function not found engA」と表示されます

私の質問は、なぜ eval が機能しないのですか?匿名関数を Menu.addItem に渡すことは可能ですか?

4

2 に答える 2

3

関数eval()のループ内で関数を定義forしているため、スコープ規則は、そのスコープ外では使用できないことを意味します。そのコードを他のすべての関数の外に移動することで、eval()実行中のスクリプトのすべてのインスタンスで 'd 関数を使用できるようになります。

これは機能します:

var BLOCKS = "abcdefg";
var CLASSES = ["English", "History", "Science", "Writing", "Latin", "Math", "Study Skills"];
var FUNCTION_NAMES;
var global = {};

init();
/// Moved
for(var _i = 0; _i < BLOCKS.length; _i++){
var _block = BLOCKS[_i];
  for(var _j = 0; _j < FUNCTION_NAMES.length; _j++){
    var _funcName = FUNCTION_NAMES[_j] + _block;
    eval("function " + _funcName + " () { createHeading('"+ CLASSES[_j] + "', '" + _block + "'); }");
  }
}
///
debugger;  // Pause in debugger (All the functions are there!)

/**
 * The onOpen function runs automatically when the Google Docs document is
 * opened. Use it to add custom menus to Google Docs that allow the user to run
 * custom scripts. For more information, please consult the following two
 * resources.
 *
 * Extending Google Docs developer guide:
 *     https://developers.google.com/apps-script/guides/docs
 *
 * Document service reference documentation:
 *     https://developers.google.com/apps-script/reference/document/
 */
function onOpen() {
  // Add a menu with some items, some separators, and a sub-menu.
  var menu = DocumentApp.getUi().createMenu('School Heading')
  for(var i = 0; i < BLOCKS.length; i++){
    block = BLOCKS[i];
    Logger.log("Block: " + block)
    menu = menu.addSubMenu(DocumentApp.getUi().createMenu(block + " Block")
                           .addItem('English', 'eng' + block)
                           .addItem('History', 'his' + block)
                           .addItem('Science', 'sci' + block)
                           .addItem('Writing', 'wri' + block)
                           .addItem('Latin', 'lat' + block)
                           .addItem('Math', 'mat'  + block) 
                           .addItem('Study Skills', 'stu' + block));
    //defineFunctions(block, this);
  }
  menu.addToUi();
}

function getFunc(class,block){
  return function(){
    createHeading(class,block);
  }
}

function defineFunctions(block, global){
  Logger.log(FUNCTION_NAMES)
  for(var i = 0; i < FUNCTION_NAMES.length; i++){
    var funcName = FUNCTION_NAMES[i] + block;
    eval("this[" + funcName + "] = function () { createHeading('"+ CLASSES[i] + "', '" + block + "'); }");
  }
  debugger;
}

function createHeading(class, block){
  var header = DocumentApp.getActiveDocument().getHeader();
  if(!header){
    header = DocumentApp.getActiveDocument().addHeader();
  }
  header.insertParagraph(0, "Name\n{class}, Block {block}".replace("{class}", class).replace("{block}", block)).setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
}

function init(){
  if(!Array.isArray(BLOCKS)){
    BLOCKS = BLOCKS.toUpperCase().split("");
  }
  if(!Array.isArray(CLASSES)){
    CLASSES = CLASSES.split("\n");
  }
  if(!Array.isArray(FUNCTION_NAMES) || FUNCTION_NAMES.length !== CLASSES.length){
    FUNCTION_NAMES = [];
    for(var i = 0; i < CLASSES.length; i++){
      FUNCTION_NAMES.push(CLASSES[i].toLowerCase().substring(0,3));
    }
  }
}
于 2013-09-15T04:15:37.330 に答える