是否可以通过 google 应用程序脚本中的 onFormSubmit 调用 SpreadsheetApp.getUi()?
Is it possible to invoke SpreadsheetApp.getUi() via onFormSubmit in google app script?
使用我的电子表格绑定脚本,此代码在从 onOpen
调用时工作正常。从 onFormSubmit
调用时出现此错误:"Cannot call SpreadsheetApp.getUi() from this context."
function showSidebar(issue,row) {
var html = HtmlService
.createTemplateFromFile('MySidebar');
html.issue = issue;
html.row = row;
SpreadsheetApp.getUi()
.showSidebar(html.evaluate().setTitle('Alert'));
}
它不会起作用,因为从技术上讲,电子表格不是“用户界面”的“当前实例”。
Google Documentation - Custom Sidebars
即使您的脚本已绑定到电子表格,并且 getUi
可以与它绑定到的任何文件一起使用,但它是从另一个文件调用的。
您甚至可以 运行 从脚本编辑器“手动”编写该代码,它会添加一个自定义对话框,但如果您从提交的表单中调用它,它将不起作用。
您不能通过 SpreadsheetApp 从像 onFormSubmit()
这样的触发器直接访问价差 sheet,因为在调用 onFormSubmit()
时,价差sheet 脱离上下文 - onFormSubmit()
超出了它所针对的形式和脚本链接到的传播 sheet(如果有)。不幸的是,没有真正简单的解决方法。
此外,如果调用 getUi()
的函数不是从传播 sheet 本身的用户界面执行的,则不能调用 getUi()
- 因为触发 运行 在后台,不一定会有 UI 可以这么说。
在尝试以下解决方案之前,请考虑以下事项:如果您使用的是您自己制作的表单,而不是您编写代码创建的表单,请考虑使用 高级设置[下的数据验证选项] =57=] 在表单编辑器中。例如,对于文本问题,您可以要求回答是一个范围内的整数,或者您可以要求回答与正则表达式相匹配。如果这不起作用,请尝试以下操作:
首先,我们需要打开传播sheet(以编程方式),然后才能使用它。我发现最简单的方法是将 spreadsheet ID 或 URL 存储在 spreadsheet 及其服务器端函数可以访问的某个地方。有多种方法可以做到这一点。例如,您可以使用属性服务(通过另一个服务器端函数,因为此时 onFormSubmit()
仍然没有 "know" 任何传播 sheets)。我发现访问 spreadsheet 的其他服务器端函数即使从像 onFormSubmit
这样由触发器调用的函数调用时也能正常工作。
您可以在 onInstall
函数中保存传播 sheet ID 或 URL 以确保它被保存。 (这适用于未来的用户,但如果您此时通过触发器测试调用 onFormSubmit()
,它将不起作用,因为 ID 尚未保存在任何地方。要解决此问题,请添加与您相同的代码用于将onInstall
函数中的ID或URL保存到onOpen
函数中,然后refresh/open你的spreadsheet。然后你可以删除ID-或 URL - 从 onOpen
函数中保存代码(但将其保留在 onInstall
函数中!)。然后,在 Code.gs 文件(或任何文件)中使用不同的函数有你的服务器端功能)来检索那个传播sheet ID或URL并调用SpreadsheetApp.openByID(id)
或SpreadsheetApp.openByUrl(url)
打开传播sheet.
之后,如果需要,您应该可以使用 getActiveSheet
或类似的。
不幸的是,我们仍然不能从这个上下文中调用 getUi()
。当您考虑它时,这是有道理的,因为没有办法知道用户是否打开了 spreadsheet,并且您不希望您的触发代码达到执行时间限制,因为没有响应 alert/prompt.
我会做的是:
- 当您收到新的表单提交时,您的
onFormSubmit
(或等效)函数将被调用。
- 从那里,您可以检查表单回复的有效性。但是,与其向用户显示警报,不如向他们发送电子邮件(只要确保您发送的邮件不要太多)。这样,用户可以收到问题通知并自行处理,如果他们没有打开 spreadsheet,他们就不会错过无效的提交。您还可以包含一个 URL,让用户可以使用下一个要点中的说明编辑他们的回复。
- 您可以获得 URL 来编辑回复
- 通过 ID 或 URL 使用类似于我上面描述的方法获取表单(例如
FormApp.openByUrl(url)
)[onFormSubmit 不在表单的文档中,因此您必须 "open"表格]
- 获取表单中调用
getResponses()
的所有响应的数组
- 要么按时间戳查找最新响应,要么仅通过获取响应数组的最后一个元素来获取最新响应。第二种方法有一个警告,例如,当您正在处理一个提交时,在提交和代码完成提交处理之间的时间内,收到另一个提交,数组中的最后一个响应来自
getResponses
变化。我不能说这对你来说是否是个问题,因为我不知道你期望回复的频率有多高,但这是需要考虑的事情。如果您正在查看时间戳(第一种方法),可以想象在极少数情况下两个响应可能具有相同的时间戳。 (或者,与其只关注 onFormSubmit
中的最新响应,您还可以检查表单响应 sheet 中没有添加特定值的行(在处理一行之后),然后处理所有不具有该值的行(因此尚未处理)。但是您不需要这样做,除非非常接近连续的响应是一个问题。)
使用我的电子表格绑定脚本,此代码在从 onOpen
调用时工作正常。从 onFormSubmit
调用时出现此错误:"Cannot call SpreadsheetApp.getUi() from this context."
function showSidebar(issue,row) {
var html = HtmlService
.createTemplateFromFile('MySidebar');
html.issue = issue;
html.row = row;
SpreadsheetApp.getUi()
.showSidebar(html.evaluate().setTitle('Alert'));
}
它不会起作用,因为从技术上讲,电子表格不是“用户界面”的“当前实例”。
Google Documentation - Custom Sidebars
即使您的脚本已绑定到电子表格,并且 getUi
可以与它绑定到的任何文件一起使用,但它是从另一个文件调用的。
您甚至可以 运行 从脚本编辑器“手动”编写该代码,它会添加一个自定义对话框,但如果您从提交的表单中调用它,它将不起作用。
您不能通过 SpreadsheetApp 从像 onFormSubmit()
这样的触发器直接访问价差 sheet,因为在调用 onFormSubmit()
时,价差sheet 脱离上下文 - onFormSubmit()
超出了它所针对的形式和脚本链接到的传播 sheet(如果有)。不幸的是,没有真正简单的解决方法。
此外,如果调用 getUi()
的函数不是从传播 sheet 本身的用户界面执行的,则不能调用 getUi()
- 因为触发 运行 在后台,不一定会有 UI 可以这么说。
在尝试以下解决方案之前,请考虑以下事项:如果您使用的是您自己制作的表单,而不是您编写代码创建的表单,请考虑使用 高级设置[下的数据验证选项] =57=] 在表单编辑器中。例如,对于文本问题,您可以要求回答是一个范围内的整数,或者您可以要求回答与正则表达式相匹配。如果这不起作用,请尝试以下操作:
首先,我们需要打开传播sheet(以编程方式),然后才能使用它。我发现最简单的方法是将 spreadsheet ID 或 URL 存储在 spreadsheet 及其服务器端函数可以访问的某个地方。有多种方法可以做到这一点。例如,您可以使用属性服务(通过另一个服务器端函数,因为此时 onFormSubmit()
仍然没有 "know" 任何传播 sheets)。我发现访问 spreadsheet 的其他服务器端函数即使从像 onFormSubmit
这样由触发器调用的函数调用时也能正常工作。
您可以在 onInstall
函数中保存传播 sheet ID 或 URL 以确保它被保存。 (这适用于未来的用户,但如果您此时通过触发器测试调用 onFormSubmit()
,它将不起作用,因为 ID 尚未保存在任何地方。要解决此问题,请添加与您相同的代码用于将onInstall
函数中的ID或URL保存到onOpen
函数中,然后refresh/open你的spreadsheet。然后你可以删除ID-或 URL - 从 onOpen
函数中保存代码(但将其保留在 onInstall
函数中!)。然后,在 Code.gs 文件(或任何文件)中使用不同的函数有你的服务器端功能)来检索那个传播sheet ID或URL并调用SpreadsheetApp.openByID(id)
或SpreadsheetApp.openByUrl(url)
打开传播sheet.
之后,如果需要,您应该可以使用 getActiveSheet
或类似的。
不幸的是,我们仍然不能从这个上下文中调用 getUi()
。当您考虑它时,这是有道理的,因为没有办法知道用户是否打开了 spreadsheet,并且您不希望您的触发代码达到执行时间限制,因为没有响应 alert/prompt.
我会做的是:
- 当您收到新的表单提交时,您的
onFormSubmit
(或等效)函数将被调用。 - 从那里,您可以检查表单回复的有效性。但是,与其向用户显示警报,不如向他们发送电子邮件(只要确保您发送的邮件不要太多)。这样,用户可以收到问题通知并自行处理,如果他们没有打开 spreadsheet,他们就不会错过无效的提交。您还可以包含一个 URL,让用户可以使用下一个要点中的说明编辑他们的回复。
- 您可以获得 URL 来编辑回复
- 通过 ID 或 URL 使用类似于我上面描述的方法获取表单(例如
FormApp.openByUrl(url)
)[onFormSubmit 不在表单的文档中,因此您必须 "open"表格] - 获取表单中调用
getResponses()
的所有响应的数组 - 要么按时间戳查找最新响应,要么仅通过获取响应数组的最后一个元素来获取最新响应。第二种方法有一个警告,例如,当您正在处理一个提交时,在提交和代码完成提交处理之间的时间内,收到另一个提交,数组中的最后一个响应来自
getResponses
变化。我不能说这对你来说是否是个问题,因为我不知道你期望回复的频率有多高,但这是需要考虑的事情。如果您正在查看时间戳(第一种方法),可以想象在极少数情况下两个响应可能具有相同的时间戳。 (或者,与其只关注onFormSubmit
中的最新响应,您还可以检查表单响应 sheet 中没有添加特定值的行(在处理一行之后),然后处理所有不具有该值的行(因此尚未处理)。但是您不需要这样做,除非非常接近连续的响应是一个问题。)
- 通过 ID 或 URL 使用类似于我上面描述的方法获取表单(例如