Nat*_*ver 6 google-sheets google-apps-script
我正在Google表格中创建一个菜单项,该菜单项将列出工作目录并提取该用户的电子邮件地址,以供以后在Google表格中处理员工记录。我正在尝试使其像这样工作:
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
var myapp = ui.createMenu('MyApp');
var pullemp = myapp.addSubMenu(ui.createMenu('Pull Employee')
.addItem('Nathaniel MacIver', menuItem2('nm@emailaddress.com')));
myap.addToUi();
}
function menuItem2(email) {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.alert('That email address is '+email);
}
Run Code Online (Sandbox Code Playgroud)
现在,当我打开电子表格时,该项目立即触发,并在下面得到我想要的结果:
但是我希望当我单击菜单中的按钮时触发它。照原样,当我单击菜单按钮时出现错误:
我知道该链接提到功能名称必须是一个字符串值,但是为什么它会按需要在加载时工作,然后在按下按钮时失败?
小智 5
当您创建菜单项时
.addItem('Nathaniel MacIver', menuItem2('nm@emailaddress.com'))
Run Code Online (Sandbox Code Playgroud)
使用参数“nm@emailaddress.com”调用函数 menuItem2。这会导致您看到警报。函数的返回值是未定义的(因为你没有从中返回任何东西)。所以你最终得到了相同的菜单项,就好像它是
.addItem('Nathaniel MacIver', undefined)
Run Code Online (Sandbox Code Playgroud)
这显然不会做任何事情。
该AddItem方法只需要一个函数的名称,它不允许传递参数给这个函数。要执行您想要的操作,您需要为每个人设置单独的功能,每个功能都在该功能内硬编码了一封电子邮件。
尽管您无法直接通过 .addItem() 方法传递使用变量调用的函数,因为它只接受字符串,但您可以采取几个额外的步骤(与您尝试执行的操作相关的额外步骤)来动态创建使用动态变量预设的函数。如果您有所有电子邮件地址的全局数组,如下所示:
var emails = ["email_2@email.com",
"email_2@email.com",
"email_2@email.com",
"email_2@email.com"]
Run Code Online (Sandbox Code Playgroud)
您可以使用“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);
}
});
Run Code Online (Sandbox Code Playgroud)
此代码将在服务器端的 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');
}
Run Code Online (Sandbox Code Playgroud)
尽管您实际上不会看到这一点,但当函数运行时,这将是代码编译时后端发生的情况。话虽这么说,然后您可以将这些相同的电子邮件名称作为字符串动态传递给 .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();
Run Code Online (Sandbox Code Playgroud)
单击其中任何一项时,代码将尝试运行名为 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"
Run Code Online (Sandbox Code Playgroud)
现在您可以使用 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])
}
});
Run Code Online (Sandbox Code Playgroud)
电子邮件之所以为 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();
Run Code Online (Sandbox Code Playgroud)
这将产生与第一个代码示例完全相同的结果,但提供人员的姓名作为菜单项而不是他们的电子邮件地址。
请原谅我这么长的回答!我刚刚发现这个是为了解决我自己的 Google Sheets 自定义菜单问题。我希望这有帮助!如果您对此有任何疑问,请随时与我联系!
| 归档时间: |
|
| 查看次数: |
1426 次 |
| 最近记录: |