虽然您不能通过 .addItem() 方法直接传递使用变量调用的函数,因为它只接受字符串,但您可以采取一些额外的步骤(相对于您尝试做的额外步骤)动态创建预先设置有动态变量的函数。如果您有一个包含所有电子邮件地址的全局数组,例如:
var emails = ["email_2@email.com",
"email_2@email.com",
"email_2@email.com",
"email_2@email.com"]
您可以使用“this”关键字创建一个完全以该电子邮件命名的自定义函数。
“this”关键字非常重要。 'this' 是一个对象。这个对象(不是双关语)包含的键是您 GAS 项目中的每个功能。例如,如果您的项目中有三个名为 function1、function2 和 function3 的函数,则“this”对象将具有三个键,每个键分别命名为 function1、function2 和 function3,每个键都是函数本身。所以:
遍历您的数组并使用括号表示法为每封电子邮件创建一个函数。括号表示法允许您使用包含点表示法不允许的字符的字符串调用对象键。我不能通过说 this.email_1@email.com 来创建对象,但我可以创建一个对象,例如 this["email_1@email.com"]:
emails.forEach(function (email) {
this[email] = function () {
SpreadsheetApp.getUi().alert('That email address is '+email);
}
});
此代码将在您的 GAS 项目中为每封电子邮件在服务器端创建一个新函数,该函数本身仅命名为电子邮件。对于视觉表示,理论上您的项目中应该有:
function email_1@email.com () {
SpreadsheetApp.getUi().alert('That email address is email_1@email.com');
}
function email_2@email.com () {
SpreadsheetApp.getUi().alert('That email address is email_2@email.com');
}
function email_3@email.com () {
SpreadsheetApp.getUi().alert('That email address is email_3@email.com');
}
function email_4@email.com () {
SpreadsheetApp.getUi().alert('That email address is email_4@email.com');
}
虽然您实际上不会看到这一点,但在运行函数时,这将是您的代码编译时在后端发生的情况。话虽如此,然后您可以将这些相同的电子邮件名称作为字符串动态传递给 .addItem() 方法(在同一全局“电子邮件”数组上使用 forEach 循环),这是您可以传递的唯一变量类型进入这个方法。
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
var myapp = ui.createMenu('MyApp');
var pullemp = myapp.addSubMenu(ui.createMenu('Pull Employee'))
emails.forEach(function (email) {
pullemp.addItem(email,email)
});
myapp.addToUi();
当点击其中任何一项时,代码将尝试运行名为 email_1@email.com 的函数(或第二、第三或第四封电子邮件,以点击者为准)。因为您遍历了 'this' 对象并创建了四个以每封电子邮件命名的函数,所以您的项目将成功地通过其名称找到该函数并运行它。
编辑:我知道您最初想使用人员的姓名而不是他们的电子邮件来创建菜单。上面的菜单将在菜单本身中显示他们的电子邮件。因此,要创建一个以他们的名字和各自的电子邮件作为功能的菜单,您需要一个对象。我的建议是创建一个对象,将人名作为键,并将他们的电子邮件分配给该键:
var emails = {};
emails["Nathaniel MacIver"] = "nm@emailaddress.com"
emails["John Doe"] = "jd@emailaddress.com"
emails["Jane Smith"] = "js@emailaddress.com"
现在您可以使用 Object.keys(\\object name) 方法来循环访问该对象。请注意,Object.keys() 方法返回对象键的数组。这就是为什么下面的 forEach() 方法起作用的原因:
Object.keys(emails).forEach(function (name) {
this[emails[name]] = function () {
SpreadsheetApp.getUi().alert('That email address is: '+emails[name])
}
});
email 之所以是 emails[name] 是因为 'name' 本身就是键的实际名称,而 emails[name] 是存储在该键中的值。所以 'name' = "Nathaniel MacIver" 和 emails[name] = emails["Nathaniel MacIver"],正如你在上面看到的,被分配给他的电子邮件地址。
现在您应用与上述相同的概念来创建菜单,但您循环遍历对象而不是数组,并在 addItem() 方法中分配菜单项,如下所示:
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
var myapp = ui.createMenu('MyApp');
var pullemp = myapp.addSubMenu(ui.createMenu('Pull Employee'))
Object.keys(emails).forEach(function (name) {
pullemp.addItem(name,emails[name])
});
myapp.addToUi();
这将产生与第一个代码示例完全相同的结果,但提供人员的姓名作为菜单项,而不是他们的电子邮件地址。
请原谅我很长的回答!我刚刚发现这个是为了解决我自己的 Google 表格自定义菜单问题。我希望这有帮助!如果您对此有任何疑问,请随时与我联系!