0

我创建了一个包含多个项目的自定义菜单,但是我很难确定用户单击了哪个项目。我想对该菜单中的每个项目使用相同的功能,但我不知道如何将哪个项目的信息传递到我的功能中。我有过但无法实现的多个想法是:尝试在按下按钮时传递参数(参数可以是按钮的名称或其索引),或尝试以某种方式确定单击了哪个项目按索引(即“单击第 3 项”)并将该信息传递给函数。

var ui = SpreadsheetApp.getUi(); //shortcut to access ui methods
var ps = PropertiesService.getScriptProperties(); //shortcut to access properties methods
var ss = SpreadsheetApp.getActiveSpreadsheet() //shortcut to access spreadsheet methods

function onOpen() {
  var menu = ui.createMenu('Scripts') //create a menu with this name
  var subMenu = ui.createMenu('Timestamps')
        for (var n = 0; n < ss.getNumSheets(); n++){
          var sheets = ss.getSheets();
          var sheetName = sheets[n].getName();
          Logger.log(sheetName)
          subMenu.addItem(sheetName, 'sheets')
        }
      menu.addSubMenu(subMenu).addToUi(); //add it to the UI
}

function sheets(sheet){
  var response = ui.alert(sheet, 'Add to timestamps?', ui.ButtonSet.YES_NO_CANCEL) //create a button and store the user value in response
  if(response == ui.Button.YES){ //if the user pressed YES (add this item to timestamp list)
    if(sheets.indexOf(sheet) != -1){ //check if item is already in the array. If it is, do nothing
      //item is aleady in array
    }else if(sheets.indexOf(sheet) == -1){ //check if it is NOT in the array. If it isn't, add it
      //item isn't in array, but needs to be added
      sheets.push(sheet) //add the item to the array
    }
  }else if(response == ui.Button.NO){ //if the user pressed NO (remove item from the list)
    if(sheets.indexOf(sheet) != -1){ //if the item already exists but needs to be removed)
      //item exists in array, but needs to be removed
      var index = sheets.indexOf(sheet); //find where the item is stored
      sheets.splice(index, 1); //splice that item out of the array
    }else if(sheets.indexOf(sheet) == -1){ //if the item already doesn't exist in the array, do nothing
      //item already isn't in array
    }
  }
  ps.setProperty('updatedSheets', JSON.stringify(sheets)) //storing the new value of sheets so that we can view it in the properties screen (only for debugging purposes)
}

此代码当前所做的是,当打开电子表格时,会创建Scripts一个名为的菜单,其中包含一个名为Timestamps. 在子菜单时间戳中,每张纸都有一个项目。目的是当用户单击其中一项时,会出现一个带有 3 个按钮的弹出窗口:是、否和取消。如果他们按是,则该项目应该被添加到数组工作表中。如果他们按否,则该项目应该被删除。如果他们按取消,则不会发生任何事情。到目前为止,如果它们在代码中指定了特定的工作表,我可以添加和删除项目,但是我怎么能得到它,以便我可以对每个项目使用相同的函数并传递参数表(取决于哪个项目是点击)进入功能表。

如果我在不将参数传递给函数的情况下对工作表名称进行硬编码,则代码的功能示例:

function sheets(){
  var response = ui.alert('Sheet1', 'Add to timestamps?', ui.ButtonSet.YES_NO_CANCEL) //create a button and store the user value in response
  if(response == ui.Button.YES){ //if the user pressed YES (add this item to timestamp list)
    if(sheets.indexOf('Sheet1') != -1){ //check if item is already in the array. If it is, do nothing
      //item is aleady in array
    }else if(sheets.indexOf('Sheet1') == -1){ //check if it is NOT in the array. If it isn't, add it
      //item isn't in array, but needs to be added
      sheets.push('Sheet1') //add the item to the array
    }
  }else if(response == ui.Button.NO){ //if the user pressed NO (remove item from the list)
    if(sheets.indexOf('Sheet1') != -1){ //if the item already exists but needs to be removed)
      //item exists in array, but needs to be removed
      var index = sheets.indexOf('Sheet1'); //find where the item is stored
      sheets.splice(index, 1); //splice that item out of the array
    }else if(sheets.indexOf('Sheet1') == -1){ //if the item already doesn't exist in the array, do nothing
      //item already isn't in array
    }
  }
  ps.setProperty('updatedSheets', JSON.stringify(sheets)) //storing the new value of sheets so that we can view it in the properties screen (only for debugging purposes)
}
4

1 回答 1

1

我知道eval是邪恶的,但我忍不住要使用它。是的,如果你通过动态创建一堆函数,eval那么剩下的就很简单了。

var FUNC_STR = 'sheets';  //the real function name (global constant)

function onOpen() {
  //...
  for(var n = 0; n < ss.getNumSheets(); n++){
    var sheets = ss.getSheets();
    var sheetName = sheets[n].getName();
    subMenu.addItem(sheetName, FUNC_STR + n);  //note here
  }
  menu.addSubMenu(subMenu).addToUi();
}


//dynamically make functions
var evalString = '';
for(var n = 0; n < ss.getNumSheets(); n++) {
  evalString += 'function ' + FUNC_STR + n + '() { ' + 
    FUNC_STR + '(' + n + ') }';
}
eval(evalString);


//now you can take a argument.
//function name should be the same as FUNC_STR.
function sheets(sheet) {
  SpreadsheetApp.getUi().alert(sheet);
  //...
}
于 2018-06-27T08:34:52.287 回答