【问题标题】:Can a Google Spreadsheet Apps Script library contain a user dialog?Google 电子表格应用程序脚本库可以包含用户对话框吗?
【发布时间】:2014-12-28 04:05:55
【问题描述】:

对于 Google 电子表格使用的 Apps 脚本库中的内容是否有限制?具体来说,库可以包含 HTML 对话框吗?

我创建了一个电子表格脚本,它添加了一个菜单项以向用户展示一个对话框。它用 HtmlService.createHtmlOutputFromFile('mappingForm').setSandboxMode(HtmlService.SandboxMode.IFRAME)

https://developers.google.com/apps-script/guides/html/communication 中所述。 HTML 文件包括 HTML、CSS 和带有 jQ​​uery 的 JavaScript。它使用google.script.run 使用电子表格中的数据填充对话框并向其提交表单。

这在原始电子表格中一切正常。

但是,我需要多个电子表格来使用相同的代码,因此我尝试遵循Google Spreadsheet Scripts shared across spreadsheets (not libraries) 的一般想法,以拥有一个带有电子表格模板和多个副本的主脚本。

我按照https://developers.google.com/apps-script/guide_libraries 的指示从原始电子表格创建了一个库。当另一个电子表格使用该库时,我可以让对话框出现,但是所有对服务器的回调(填充对话框或提交表单)都会失败,并在浏览器端被google.script.run.withFailureHandler 捕获错误作为具有属性的Error 对象:

message: "We're sorry, a server error occurred. Please wait a bit and try again."
name: "ScriptError"

我在应用程序脚本中放置了 Logger 调用,以查看是否正在调用服务器端函数,但没有一个函数被命中。脚本编辑器的 Execution Transcript 显示:

[14-12-27 19:38:05:340 PST] 开始执行

[14-12-27 19:38:05:372 PST] 执行失败:很抱歉,发生服务器错误。请稍等,然后重试。 [0.0 秒总运行时间]

客户端正在拨打电话,但在到达电子表格脚本之前出现了故障。

这让我怀疑

  1. 我需要做一些不同的事情才能让代码像一个库一样工作。
  2. 库不能有对话框。
  3. 存在服务器错误。

提前感谢您的任何建议。

【问题讨论】:

  • 当服务器连接没有问题时,Google 经常返回该服务器错误。我猜这可能与权限和共享有关,但我不确定如何解决。
  • @Sandy 目前,两个电子表格都有相同的所有者,但目标是最终让其他人拥有的电子表格使用该库。使用电子表格的项目属性显示以下范围:2 脚本所需的 OAuth 范围:googleapis.com/auth/script.send_mailgoogleapis.com/auth/spreadsheets
  • 更新:自从我的原始帖子以来,我发现code.google.com/p/google-apps-script-issues/issues/… 其他人报告了同样的问题。
  • 感谢您的更新。我应该首先给你那个链接。

标签: google-apps-script google-sheets


【解决方案1】:

通过执行以下操作,我能够拥有一个包含 HTML 对话框的工作库。

  1. 将脚本和 HTML 文件从原始电子表格移至 standalone script 项目。记下 File > Project properties...Info 选项卡中库的 Project key。任何打算使用该库的电子表格都需要它。

  2. 如果独立脚本项目要被其他人使用,请单击其分享按钮,使其可以分享给任何有链接的人,否则他们会默默地失败。

  3. 如果 HTML 对话框需要回调库函数(以获取或提交数据),则库函数必须存在于使用该库的电子表格中,否则您将在浏览器的 JavaScript 控制台。

  4. 在使用库的电子表格中:工具 > 脚本编辑器... 点击 资源 > 库...。在“Included Libraries”对话框中,在Find a Library文本框中输入独立项目的key,点击Select,然后选择合适的Version,如有必要,更改标识符,然后保存Identifier 值创建一个同名对象,供电子表格的脚本用于调用库函数。就我而言,它是SignupFormResponsesSheet

  5. 在同一个脚本编辑器的代码编辑器中,添加调用库函数的包装函数,包括将从 HTML 对话框回调的任何函数。我的库有一个onOpen(),它创建了两个菜单项来显示 HTML 对话框,所以我添加了

function onOpen() {
    SignupFormResponsesSheet.onOpen();
}

function showMappingForm() {
    SignupFormResponsesSheet.showMappingForm();
}

function showSubmitForm() {
    SignupFormResponsesSheet.showSubmitForm();
}
  1. 我的 HTML 对话框有许多回调来获取和提交数据,所以我没有为每个回调编写一个包装函数,而是利用 Apps Script 将库视为对象的方式添加了一个函数来覆盖所有这些回调包含函数。第一个参数是一个字符串,命名要调用的库函数。任何其他参数都会传递给库函数。

function runSignupFormResponseFunction(funcName, varargs) {
  return SignupFormResponsesSheet[funcName].apply(this,
    Array.prototype.slice.call(arguments, 1));
}
  1. 由于上述步骤 3 中确定的限制,HTML 对话框中的 JavaScript 在需要获取或提交数据时使用google.script.run 调用runSignupFormResponseFunction。例如,它有两个列表,这些列表使用来自库的 getRangeLabelsgetColumnExamples 函数的服务器数据动态填充(并且必须在另一个之前填充一个),因此代码是

google.script.run
  .withFailureHandler(showError)
  .withSuccessHandler(function(ranges) {
    loadRanges(ranges);
    // once ranges are loaded, load columns
    google.script.run
      .withSuccessHandler(loadColumns)
      .withFailureHandler(showError)
      .runSignupFormResponseFunction("getColumnExamples");
  })
  .runSignupFormResponseFunction("getRangeLabels");

今天这对我有用。我希望它适用于可能发现此问题的其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 2017-12-29
    • 1970-01-01
    相关资源
    最近更新 更多