【问题标题】:Single Google Form for multiple Sheets [duplicate]多个工作表的单个 Google 表单 [重复]
【发布时间】:2013-06-17 16:12:57
【问题描述】:

由于正在进行的开发版本控制,以及实施用户权限变通办法看似无法克服的问题,我需要捕获链接到不向用户公开的工作表的表单数据。相反,我想使用自定义菜单从单独的电子表格应用程序启动表单。然而,尽管进行了彻底的 Google 搜索,并且使用了令人着迷的“FormApp.openById”方法,我还是找不到实现此目的的方法。

我知道我在这里偏离了轨道;谁能指点我回来的路?

【问题讨论】:

    标签: google-apps-script google-sheets google-forms


    【解决方案1】:

    第 1 步:创建表单

    正常操作过程 - 通过脚本或使用表单 UI 创建表单。捕获表单的 ID。例如,在编辑器中时从 URL:

    https://docs.google.com/forms/d/1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ/edit
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    附加电子表格以获取回复。 (我们不会在这里做更多的事情。)

    第 2 步:客户端脚本

    在用户可访问的电子表格中,创建一个容器绑定脚本(以便它可以访问电子表格 UI)。以下脚本生成一个自定义菜单,其中包含一个在 Ui 弹出窗口中启动表单的选项。

    /**
     * Uses the Forms service to get a handle on an existing form, then retrieve its published URL.
     * Uses the UrlFetch Service to get a copy of the HTML for the form.
     * Uses the HtmlService to embed the form's HTML in a Spreadsheet UI.
     * ... which is finally shown using Spreadsheet.show().
     */
    function launchForm() {
      var formID = '1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ';
      var form = FormApp.openById(formID);
      var formUrl = form.getPublishedUrl();
    
      var response = UrlFetchApp.fetch(formUrl);
      var formHtml = response.getContentText();
    
      var htmlApp = HtmlService
          .createHtmlOutput(formHtml)
          .setSandboxMode(HtmlService.SandboxMode.IFRAME)
          .setTitle('Ta Daaa!')
          .setWidth(500) 
          .setHeight(450);
    
      SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
    }
    
    function onOpen() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      var entries = [{
        name : "Launch Form",
        functionName : "launchForm"
      }];
      sheet.addMenu("Custom Menu", entries);
    };
    

    演示

    当您从“自定义菜单”中选择“启动表单”时,您会看到以下内容。 不过,有点烦人——当提交表单时,用户会被带到另一个浏览器窗口或选项卡。在电子表格中,UI 保持打开状态,需要手动关闭。 IFRAME 沙盒解决了这个问题!


    编辑:最近引入了 ECMA 沙箱默认值的更改,这要求沙箱模式明确设置为 NATIVE 才能使该技术正常工作。代码已更新。

    再次编辑:较新的 IFRAME 沙盒模式将整个表单体验保留在对话框中。

    【讨论】:

    • 嗨 Mogsdad,我刚刚开始使用这种方法,而且效果很好 - 再次感谢!然而,一个问题是加载需要相当长的时间。表单本身并不是特别复杂,由 17 个字段组成,只有 2 个字段的列表少于 30 个项目。从承载表单的工作表中的“表单”菜单启动时,它会像往常一样快速加载到新选项卡中。我想我需要编辑 css 以去除谷歌创建的一些默认标签,但想知道是否还有其他我可能忽略的东西 - 有什么想法吗?
    • 如果多次调用服务,这种技术肯定会很慢——我猜是服务调用成本最高。 (检查执行记录以了解时间都花在了哪里。)可以通过使用缓存服务来存储已发布的 URL 和 activeSpreadsheet、删除 4 次以上的服务调用并节省几秒钟来帮助。
    • 提交表单的按钮在弹出窗口中不起作用。为什么?
    【解决方案2】:

    Mogsdad 让我走上了正轨,但为了让提交按钮起作用,我必须将它直接嵌入到代码中。

    1) 创建表单并在表单菜单中选择“在网页中嵌入表单”

    2) 复制出现的整个代码块。它应该看起来像这样:

    <iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>
    

    3) 将此函数添加到您的脚本页面

    function launchForm() {
      var embeddedHtml = '<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>'
      var htmlApp = HtmlService.createHtmlOutput(embeddedHtml)
      SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Title');
    }
    

    如果您希望保留表单的格式和横幅,请从嵌入式链接 https://docs.google.com/forms/d/e/&lt;YOUR_ID_NUMBER_HERE/viewform?embedded=true 中删除 ?embedded=true

    【讨论】:

      猜你喜欢
      • 2013-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多