【问题标题】:How to prefill Google form checkboxes?如何预先填写 Google 表单复选框?
【发布时间】:2014-12-11 04:19:03
【问题描述】:

我查看了问题“Is it possible to 'prefill' a google form using data from a google spreadsheet?”,并且答案中提供的代码(感谢 Mogsdad)适用于文本类型的 Google 表单问题。我的问题是: 是否可以预先填写复选框类型的 Google 表单问题?

例如,如果我有一个包含“姓名”条目的现有电子表格,并且其中一个条目是“Fred, Barney”,那么是否可以通过编码预先填写一个带有“Fred”复选框的表单”和“姓名”复选框下的“Barney”键入 Google 表单问题?

谢谢, 格雷格

【问题讨论】:

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


    【解决方案1】:

    当您编辑表单时,填写您想要预先填写的值。

    然后获取pre-filled URL

    【讨论】:

      【解决方案2】:

      对于大多数其他类型,可以重复每个响应的基本模式。例如,这适用于多项选择:

                  item = items[i].asMultipleChoiceItem();
                  var respItem = item.createResponse(resp);
      

      但是,复选框可能很棘手,因为它可能有一个项目、多个项目,甚至是“其他”响应。当响应记录到您的电子表格中时,它将显示为逗号分隔的字符串;当在表单提交事件中收到时(例如在触发函数中),我们得到一个数组(...其中所有响应都在数组的第一项中,以逗号分隔的字符串形式)。 checkboxItem 的 createResponse() 方法需要一组有效的选择......所以我们可以用一点 javascript 魔法来提供它:

                  item = items[i].asCheckboxItem();
                  // Response is a CSV string, need array
                  var respArray = resp.split(/ *, */);
                  var respItem = item.createResponse(respArray);
      

      编辑:当启用“其他”选项时,Google 存在 CheckboxItems 和 MultipleChoiceItems 错误。这些“其他”选项是允许的,但在预填充的 URL 中呈现不正确,因此它们不会出现在显示的表单中。请查看并加注星标Issue 4454。

      这是来自Is it possible to 'prefill' a google form using data from a google spreadsheet? 的函数的更新版本,已更新以处理列表、多项选择和复选框响应。这个版本更通用,它可以适应电子表格中的标题。 奖励:如果您添加标有“预填充 URL”的列,脚本将在那里写入其生成的 URL。

      /**
       * Use Form API to generate pre-filled form URLs
       * 
       * https://stackoverflow.com/a/26395487/1677912
       */
      function evenBetterBuildUrls() {
        var ss = SpreadsheetApp.getActive();
        var sheet = ss.getSheetByName("Form Responses 1");
        var data = ss.getDataRange().getValues();  // Data for pre-fill
        var headers = data[0];                     // Sheet headers == form titles (questions)
      
        var formUrl = ss.getFormUrl();             // Use form attached to sheet
        var form = FormApp.openByUrl(formUrl);
        var items = form.getItems();
        var urlCol = headers.indexOf("Prefilled URL");   // If there is a column labeled this way, we'll update it
      
        // Skip headers, then build URLs for each row in Sheet1.
        for (var row = 1; row < data.length; row++ ) {
          Logger.log("Generating pre-filled URL from spreadsheet for row="+row);
          // build a response from spreadsheet info.
          var response = form.createResponse();
          for (var i=0; i<items.length; i++) {
            var ques = items[i].getTitle();           // Get text of question for item
            var quesCol = headers.indexOf(ques);      // Get col index that contains this question
            var resp = ques ? data[row][quesCol] : "";
            var type = items[i].getType().toString();
            Logger.log("Question='"+ques+"', resp='"+resp+"' type:"+type);
            // Need to treat every type of answer as its specific type.
            switch (items[i].getType()) {
              case FormApp.ItemType.TEXT:
                var item = items[i].asTextItem();
                break;
              case FormApp.ItemType.PARAGRAPH_TEXT: 
                item = items[i].asParagraphTextItem();
                break;
              case FormApp.ItemType.LIST:
                item = items[i].asListItem();
                break;
              case FormApp.ItemType.MULTIPLE_CHOICE:
                item = items[i].asMultipleChoiceItem();
                break;
              case FormApp.ItemType.CHECKBOX:
                item = items[i].asCheckboxItem();
                // In a form submission event, resp is an array, containing CSV strings. Join into 1 string.
                // In spreadsheet, just CSV string. Convert to array of separate choices, ready for createResponse().
                if (typeof resp !== 'string')
                  resp = resp.join(',');      // Convert array to CSV
                resp = resp.split(/ *, */);   // Convert CSV to array
                break;
              case FormApp.ItemType.DATE:
                item = items[i].asDateItem();
                resp = new Date( resp );
                resp.setDate(resp.getDate()+1);
                break;
              case FormApp.ItemType.DATETIME:
                item = items[i].asDateTimeItem();
                resp = new Date( resp );
                break;
              default:
                item = null;  // Not handling DURATION, GRID, IMAGE, PAGE_BREAK, SCALE, SECTION_HEADER, TIME
                break;
            }
            // Add this answer to our pre-filled URL
            if (item) {
            // Checking if there is any value
              if(resp[0].length != 0){
                var respItem = item.createResponse(resp);
                response.withItemResponse(respItem);
              }
            }
            // else if we have any other type of response, we'll skip it
            else Logger.log("Skipping i="+i+", question="+ques+" type:"+type);
          }
          // Generate the pre-filled URL for this row
          var editResponseUrl = response.toPrefilledUrl();
          // If there is a "Prefilled URL" column, update it
          if (urlCol >= 0) {
            var urlRange = sheet.getRange(row+1,urlCol+1).setValue(editResponseUrl);
          }
        }
      };
      

      【讨论】:

      • 感谢您的回复。我已经通过在电子表格上将其作为脚本运行来尝试该代码并得到一个错误:“提交给项目的响应无效”适用于第 64 行(var respItem = item.createResponse(resp);),它位于注释下方的两行“ // 将此答案添加到我们预先填写的 URL"。有什么想法吗?
      • 我已经在类似于 Mogsdad 给出的示例的较小电子表格上进行了尝试,并且效果很好。看来问题出在我现有的表格和电子表格中。我在 csv 单元格中有一个与复选框匹配的条目,但在进入表单时没有相应的复选框可供选择。
      • @Greig - CheckboxItem.createResponse() 的文档解释了这种行为;它“如果任何值与此项目的有效选择不匹配,则抛出异常”,除非您的问题包含“其他”选项。
      • 添加了关于 CheckboxItem 和 MultipleChoiceItem 的 google 错误的注释,与“其他”相关。
      • 有没有跳过空白条目的方法?
      【解决方案3】:

      这是我开发的最后一个脚本,它非常适合我。

      Google 表单的更新和预字段链接。

      此脚本不会关闭,因为我们知道运行时间为 6 分钟,我已将此脚本与 google 表单提交触发器和函数中的手动触发器一起使用以获取 lastrow。

      注意:

      1. 您必须使用特定单元格更改所有数字
      2. 特别是您必须用自己的方式更改脚本最后一行中的表单条目(看看 pic evry 输入有一个固定的唯一条目)

      【讨论】:

      • 您能在答案中包含您的脚本吗?这会让你的答案变得更好。
      【解决方案4】:

      作为答案提供的脚本中有一个小问题。

      var ss = SpreadsheetApp.getActive();
      var sheet = ss.getSheetByName("Form Responses 1");
      var data = ss.getDataRange().getValues();  // Data for pre-fill
      

      变量数据引用活动工作表 (ss),而不是“表单响应 1”工作表 (工作表)。这可能是故意的,但我认为如果其他人使用同一张表进行预填和回复,我应该突出显示它。

      【讨论】:

        猜你喜欢
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-08
        • 1970-01-01
        • 2017-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多