Google apps script 是否可以通过google应用程序脚本中的onFormSubmit调用SpreadsheetApp.getUi()?

Google apps script 是否可以通过google应用程序脚本中的onFormSubmit调用SpreadsheetApp.getUi()?,google-apps-script,google-sheets,Google Apps Script,Google Sheets,在我的电子表格绑定脚本中,当从onOpen调用时,该代码可以正常工作。从onFormSubmit调用时,我收到以下错误:无法从此上下文调用SpreadsheetApp.getUi 这是行不通的,因为从技术上讲,电子表格不是用户界面的当前实例 即使您的脚本已绑定到电子表格,并且getUi可以处理它绑定到的任何文件,但它是从另一个文件调用的 您甚至可以从脚本编辑器手动运行该代码,它将添加一个自定义对话框,但如果您从正在提交的表单调用它,它将无法工作。您无法通过诸如onFormSubmit之类的触发器

在我的电子表格绑定脚本中,当从onOpen调用时,该代码可以正常工作。从onFormSubmit调用时,我收到以下错误:无法从此上下文调用SpreadsheetApp.getUi


这是行不通的,因为从技术上讲,电子表格不是用户界面的当前实例

即使您的脚本已绑定到电子表格,并且getUi可以处理它绑定到的任何文件,但它是从另一个文件调用的


您甚至可以从脚本编辑器手动运行该代码,它将添加一个自定义对话框,但如果您从正在提交的表单调用它,它将无法工作。

您无法通过诸如onFormSubmit之类的触发器通过电子表格应用程序直接访问电子表格,因为在调用onFormSubmit时,电子表格不在上下文中-onFormSubmit不在它所用于的表单和电子表格(如果脚本链接到任何表单)的范围内。不幸的是,没有一个简单的解决方法

此外,如果调用getUi的函数不是从用户界面(如电子表格本身)调用getUi,则不能调用getUi——因为触发器在后台运行,所以可以说不一定要获取UI

在尝试下面的解决方案之前,请考虑一下:如果使用的是自己创建的表单,而不是编写代码创建的窗体,请考虑在窗体编辑器中的高级设置下使用数据验证选项。例如,对于文本问题,您可以要求回答是范围内的整数,或者要求回答与正则表达式匹配。如果不起作用,请尝试以下操作:

首先,我们需要以编程方式打开电子表格,然后才能使用它。我发现最简单的方法是将电子表格ID或URL存储在电子表格及其服务器端功能可以访问的位置。有多种方法可以做到这一点。例如,您可以通过另一个服务器端功能使用Properties服务,因为onFormSubmit目前还不知道任何电子表格。我发现,即使从触发器调用的onFormSubmit这样的函数调用,访问电子表格的其他服务器端函数也可以正常工作

您可以在onInstall函数中保存电子表格ID或URL,以确保其已保存。这对未来的用户有效,但是如果此时通过触发器测试调用onFormSubmit,它将不起作用,因为ID还没有保存到任何地方。要解决此问题,请将用于在onInstall函数中保存ID或URL的代码添加到onOpen函数中,然后刷新/打开电子表格。然后可以从onOpen函数中删除ID或URL保存代码,但将其保留在onInstall函数中!。然后,在Code.gs文件中使用不同的函数或任何包含服务器端函数的文件检索该电子表格ID或URL,并调用SpreadsheetApp.openByIDid或SpreadsheetApp.openByUrlurl打开电子表格

之后,如果需要,您应该能够使用getActiveSheet或类似工具

不幸的是,我们仍然无法从这个上下文调用getUi。仔细想想,这是有道理的,因为无法知道用户是否打开了电子表格,而且您也不希望触发器代码达到执行时间限制,因为没有对警报/提示的响应

我要做的是:

当您获得新表单提交时,将调用onFormSubmit或等效函数。 从那里,您可以检查表单响应的有效性。但是,不要向用户显示警报,而是向他们发送电子邮件,确保不要发送太多。通过这种方式,用户可以得到问题通知,并在自己的时间内处理问题,如果他们没有打开电子表格,他们也不会错过无效的提交。您还可以包含一个URL,允许用户使用下一个要点中的说明编辑其响应。 您可以通过获取URL来编辑响应 通过ID或URL获取表单,例如FormApp.openByUrlurl,使用类似于我上面描述的方法[onFormSubmit不在表单的文档中,因此您必须打开表单] 获取窗体上调用getResponses的所有响应的数组 通过时间戳查找最新响应,或者通过获取响应数组的最后一个元素获取最新响应。第二种方法有一个警告,即当您处理一个提交时,在提交和代码完成提交处理之间的时间内,会收到另一个提交,并且getResponses数组中的最后一个响应会发生更改。我不能说这对你来说是个问题,因为我不知道你有多频繁地期待回应,但这是值得考虑的事情。如果你看着蒂姆 创建第一种方法,可以想象,在极少数情况下,两个响应具有相同的时间戳。或者,与只关注onFormSubmit中的最新响应不同,您可以在表单响应表中检查处理行后没有添加特定值的行,然后处理所有没有该值且尚未处理的行。但你不需要这样做,除非你担心接二连三的反应。
谢谢桑迪。我想投票,但我的代表太小了,不让我投票;。我正试图找到一种解决方法,如果用户打开电子表格,新表单出现错误,但到目前为止还没有骰子,那么它将启动侧边栏。
        function showSidebar(issue,row) {
        var html = HtmlService
            .createTemplateFromFile('MySidebar');
        html.issue = issue;
        html.row = row;        
        SpreadsheetApp.getUi()
            .showSidebar(html.evaluate().setTitle('Alert'));
}