根据Google工作表中的缺失数据创建表单

时间:2019-08-14 00:57:49

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

我在Google表格中有一个数据集,该数据集在某些字段中缺少一些信息。在某些标题下,所有数据都是统一的,并且都具有唯一的ID值。我创建了一个验证表,该表提取了缺失字段的相应唯一ID值及其列标题,以了解缺少哪些项目,但是我想创建一个基于这些缺失值创建的Google表单。

缺少的单元格数量将是验证表中产生的唯一ID的数量。

Google-sheet 工作表说明:

原始数据就是这样。

ValidationSheet 清除所有填写的单元格,并在A列中提供相应的ID

非空白(查询)非空白(公式)都压缩ValidationSheet数据(两者都做同样的事情,只是一个拥有一个公式,而另一个使用了查询)

取消枢纽是“非空白”工作表的取消枢纽。

目的是基于Unpivoted值创建一个表单,该表单具有唯一ID,该ID缺少字段供他们填写空白。

我尝试的代码只完成了一半,因为我不确定以下步骤

function createForm() {

  var item = "Missing Data"

  var form = FormApp.Create(item)
  .setTitle(item);

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(ResponseSheet);
  var data = sheet.getDataRange().getValues();
  var responses = form.getResponses();


  item = (Define item to be the missing value)
  form.addTextItem()
     .setTitle(<insert missing value here & add more text saying "missing value">)
     .setRequired(true);

2 个答案:

答案 0 :(得分:0)

提供的验证表如下:

enter image description here

您可以根据以下数据来创建表单:

protected override IQueryable<Product> CreateFilteredQuery(PagedProductResultRequestDto input)
{
    return base.CreateFilteredQuery(input).
        WhereIf(input.Keyword.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Keyword));
}
  

此方法基于以下假设:   缺少数据的提交,因此将使用新的“缺少数据”表格   为响应每个提交的数据丢失而创建的

想法:

您遍历一行的所有单元格,如果发现至少一个空单元格,则为该行创建一个表单,并将与空单元格相对应的列标题作为表单项追加到表单中。

结果:

enter image description here enter image description here

答案 1 :(得分:0)

在Google脚本中通常有很多处理方法-这种情况也不例外。请认为这只是实现结果的一种方法。

此代码是在电子表格所附的脚本编辑器中编写的。

概述
一种Google表单,可从电子表格中的数据中更新ListItem的下拉选项。
下拉选项位于问题1中,并且每个项目都会基于电子表格数据自动链接到相关的页面/问题。 该设计假定每个下拉菜单仅包含一个后续问题(尽管可以构建更复杂的系统)。

该代码由几个功能组成,但它可以作为系统工作。 因此,启动和管理表单需要采取许多具体步骤。

这些是:
A-创建电子表格和表格-手动操作。

  • 创建电子表格,或使用现有的电子表格包含有关丢失的信息。
  • 在所选的Drive文件夹中创建一个具有适当文件名的表单(以后可以根据需要更改它们)。最好创建一个新表单,以便所有更改都由代码驱动。

B-将代码复制到电子表格-手动过程。

  • 打开电子表格摘要编辑器。
  • 如果尚不存在,请创建一个合适的项目名称。
  • 创建一个新的脚本文件(使用适当的名称)。
  • 将下面包含的所有代码复制到脚本文件中。
  • 保存脚本文件。

C-更新全局变量-手动过程。
在电子表格脚本编辑器中,更新脚本文件顶部的全局变量。

  • 输入电子表格ID =“插入电子表格ID”
  • 输入表单ID =“插入表单ID”
  • 输入将记录缺少字段信息的工作表(标签)名称(而不是文件/电子表格的名称)
  • 保存脚本文件。

D-更新电子表格。

  • 如果工作表尚不存在,请创建它。
  • 输入/确认工作表的列标题
    //标头应位于第1行;从第2行开始的数据
    //列标题为:
    //列A-唯一ID
    // B列-标记号
    // C列-缺少数据字段
    //仅供参考:“可能”字段的当前列表为:房间号,类型标记,描述,标记,制造商,型号,保修终止日期,安装日期,维护。
    //如果创建了新字段,或者删除/更改了现有字段,则还需要手动更新信息。

E-安装可触发的触发器

在电子表格脚本编辑器中,单击“时钟”图标以安装“可安装”触发器。

  • 添加触发器。
  • 要运行的函数=“ sheetOpen”
  • 在部署时运行=“ Head”(默认)
  • 选择事件源=电子表格(默认)
  • 选择事件类型=打开时
  • 单击“保存”。 可能会要求您确认权限,照常完成此操作。
  • 关闭电子表格,然后再次打开-现在有一个自定义菜单“缺少字段表单”

自定义菜单(“缺少字段表单”)
1-初始设置(可重复)
2-添加缺少的字段部分和问题(仅一次)
3-创建表单目标(可重复)
4-构建特定ID和缺失字段的内容(可重复)

初始设置
在自定义菜单中,选择“初始设置”
这将更新以下值:

  • 标题
  • 说明
  • 确认消息
  • 允许用户编辑他们的回复:否
  • 启用表单以接受响应:True

您可以根据需要修改初始设置设置并运行此功能。它还会创建一个新的下拉问题。如果下拉列表存在,则不会创建第二个副本;如果该下拉列表不存在,则将创建它。

添加的缺少的字段和问题(仅一次)
这将为每个领域的可能性添加一个新的部分和问题。

创建表单目的地
从自定义菜单中,选择“创建新表单目标” 这将在电子表格中为表单响应创建一个新的目标表。

为特定ID和缺少字段构建内容
这将从电子表格中获取唯一ID及其缺失字段,并将其添加到下拉列表中。 每个项目都会自动链接到相关页面。 该过程可以完全重复,并且可以按照用户希望的次数进行多次。 表单中的所有ID和字段都将被电子表格中的数据覆盖。


// This code is designed to manage a form for collecting information about missing fields in a Plant Register.
// This version of the code is designed for the scenario where there is only ONE missing data field per equipment item record

// Global variables

// Record the ID of the spreadsheet
var ssID = "1-DDTt_dEV2LLtGwhZ6qBtGHrz07EJ4Ef4yxxuZKaEF8";
// Record the ID of the form
var formID = "1MJYof24YrUubpdFBlxT63LSVpvshh4eFKaUQGITlBms";
// Record the sheet (tab) name where the missing data will be recorded (starting in cell A1
// column headings for that sheet are:
// Column A - Unique ID
// Column B - Tag Number
// Column C - MIssing data field
var sheetname = "form_input_single";
// open the spreadsheet
var wsData = SpreadsheetApp.openById(ssID).getSheetByName(sheetname);
// open the form
var form = FormApp.openById(formID);


/*
///////////////////////////////////////////////////////////////////////////////
*/


    // The onOpen function is executed automatically every time a Spreadsheet is loaded    
    // Add a custom menu to the active spreadsheet, including a separator and a sub-menu.    
    // Adds the custom menu to the active spreadsheet.
    function sheetOpen() {

      SpreadsheetApp.getUi()
        .createMenu('Missing Fields Form')
        .addSubMenu(SpreadsheetApp.getUi().createMenu('Setup')
          .addItem('1: Inital Setup (repeatable)', 'formsetup')
          .addItem(
            '2: Add Missing Field Sections and Questions (once only)',
            'addMissingfieldsandPagebreaks')
          .addItem('3. Create new Form Destination (repeatable)',
            'setFormdestination'))
        .addSeparator()
        .addSubMenu(SpreadsheetApp.getUi().createMenu(
            'Update Missing Fields')
          .addItem(
            '4. Build the content for specific PLANT IDs and respective missing fields (repeatable)',
            'UpdateDropDownItems'))
        .addToUi();
    }


    /*
    ///////////////////////////////////////////////////////////////////////////////
    */

    //Step#1
    function formsetup() {
      // Update form properties via chaining.
      form.setTitle('Equipment Register Update')
        .setDescription(
          'This form is used to complete missing fields in the Equipment Register'
          )
        .setConfirmationMessage('Thanks for responding!')
        .setAllowResponseEdits(false)
        .setAcceptingResponses(true);

      // Build the initial Drop-down question
      buildInitialDropdownQuestion();

      // Add the Missing field drop-downs items ands links
      //addDropDownItems();
    }

    function buildInitialDropdownQuestion() {

      // Build
      // list ListItems
      var listitems = form.getItems(FormApp.ItemType.LIST);
      if (listitems.length != 0) {
        Logger.log("DEBUG: These are the list items");
        for (var i = 0; i < listitems.length; i++) {
          Logger.log("DEBUG:" + listitems[i].getTitle() + ", ID= " +
            listitems[i].getId());
        }
      } else {
        Logger.log("DEBUG: there are no list items");
        // add opening list item and Title
        var item = form.addListItem();
        item.setTitle('Tag/Equipment Number');
        item.setRequired(true);
      }
    }

    /*
    ///////////////////////////////////////////////////////////////////////////////
    */
    // Step#2  
    function addMissingfieldsandPagebreaks() {

      // add all the potential missing fields and relevant questions
      // as built, this is intended to run once only. 
      // If this function is run more than once, it will duplicate the existing pages and questions

      // Equipment - Mark
      var mark = form.addPageBreakItem().setTitle(
        "The Mark on the equipment?").setHelpText(
        'Updating identifying marks on equipment').setGoToPage(FormApp
        .PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Mark").setHelpText(
        '(an identifying mark on the equipment)').setRequired(true);

      // Room Number
      var roomnumber = form.addPageBreakItem().setTitle(
        "The Rooom number?").setHelpText(
        'Updating the room number for this equipment').setGoToPage(
        FormApp.PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Room Number").setHelpText(
        '(format XX-ZZZZ)').setRequired(true);

      // Maintenance
      var maintenance = form.addPageBreakItem().setTitle(
        "Maintenance Schedule").setHelpText(
        'Updating the maintenance schedule').setGoToPage(FormApp
        .PageNavigationType.SUBMIT);;
      form.addMultipleChoiceItem()
        .setTitle('Maintenance')
        .setChoiceValues(['6 monthly', '12 Monthly', 'As required',
          'N/A'])
        .showOtherOption(false)
        .setRequired(true);

      // Equipment - Type Mark
      var typemark = form.addPageBreakItem().setTitle(
        "The Type Mark on the equipment?").setHelpText(
        'Updating equipment type marks').setGoToPage(FormApp
        .PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Type Mark").setHelpText(
        '(an identifying Type Mark on the equipment)').setRequired(true);

      // Equipment - Description
      var description = form.addPageBreakItem().setTitle(
        "Describe the equipment").setHelpText(
        'Updating the description of an item of equipment').setGoToPage(
        FormApp.PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Description").setHelpText(
        '(Equipment type and specification)').setRequired(true);

      // Equipment - Manufacturer
      var manufacturer = form.addPageBreakItem().setTitle(
          "Name of the Manufacturer").setHelpText(
          'Updating the manufacturer name for an item of equipment')
        .setGoToPage(FormApp.PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Manufacturer").setHelpText('(Name)')
        .setRequired(true);

      // Equipment - Model
      var model = form.addPageBreakItem().setTitle("Model Name")
        .setHelpText('Updating the Model Number for an item of equipment')
        .setGoToPage(FormApp.PageNavigationType.SUBMIT);;
      form.addTextItem().setTitle("Model").setHelpText('(Name)')
        .setRequired(true);

      // Equipment - Warranty End Date
      var warrantyenddate = form.addPageBreakItem().setTitle(
          "Warranty End Date").setHelpText(
          'Updating the Warranty End-Date for an item of equipment')
        .setGoToPage(FormApp.PageNavigationType.SUBMIT);;
      form.addDateItem().setTitle("Warranty End Date").setHelpText(
        '(dd/mm/yyyy)').setRequired(true);

      // Equipment - Date Installed
      var dateinstalled = form.addPageBreakItem().setTitle(
          "Installation date").setHelpText(
          'Updating the Installation date for an item of equipment')
        .setGoToPage(FormApp.PageNavigationType.SUBMIT);;
      form.addDateItem().setTitle("Date Installed").setHelpText(
        '(dd/mm/yyyy)').setRequired(true);

    }

    /*
    ///////////////////////////////////////////////////////////////////////////////
    */
    // Step#3
    function setFormdestination() {

      // Update the form's response destination.
      form.setDestination(FormApp.DestinationType.SPREADSHEET, ssID);
    }
    /*
    ///////////////////////////////////////////////////////////////////////////////
    */

    // Step#4
    function UpdateDropDownItems() {

      // build the content of the Drop-down item, together with links to relevant questions/pages
      // This can be run as many times as neccessary.

      var ddid = getdropdownid(); // as an integer
      var plantList = form.getItemById(ddid).asListItem();

      var pagebreaks = form.getItems(FormApp.ItemType.PAGE_BREAK);

      var LR = wsData.getLastRow();
      var dataRange = wsData.getRange(2, 1, LR - 1, 3);
      var values = dataRange.getValues();
      var valLen = values.length;


      var newchoices = [];;

      for (var v = 0; v < valLen; v++) {
        //Logger.log("DEBUG: v:"+v+", field: "+values[v][2]);
        var pb = getpbid(values[v][2]); //as an integer
        // Logger.log(values[v][2]+" = "+pb);

        var pbitem = form.getItemById(pb).asPageBreakItem();

        var dropdown = values[v][0] + " - " + values[v][
        1]; //Concatenate the Unique ID and the Equipment Number
        newchoices.push(plantList.createChoice(dropdown,
        pbitem)); // push create choice onto array

      }
      plantList.setChoices(newchoices);

    }

    function getdropdownid() {
      // Utility
      // get the ID for the Listitem 
      // called by UpdateDropDownItems()

      // list List Items
      var listitems = form.getItems(FormApp.ItemType.LIST);
      var item = listitems[0];
      var listitemid = item.getId().toString();
      //Logger.log(listitemid)
      //Logger.log(item.getId().toString());
      return listitemid;

    }

    function getpbid(title) {

      // Utility
      // get the page break ID; called by UpdateDropDownItems()
      //Logger.log("DEBUG: getpbid - title attribute:"+title) 
      var pagebreaks = form.getItems(FormApp.ItemType.PAGE_BREAK);
      var titles = pagebreaks.map(function(pagebreak) {
        return pagebreak.getTitle();
      });
      //Logger.log("DEBUG: titles = "+titles)
      var pos = titles.indexOf(title);
      //Logger.log("DEBUG: posn = "+pos);
      var pagebreak = pagebreaks[pos];
      //Logger.log("DEBUG: pagebreak:"+pagebreak);
      var pagebreakID = pagebreak.getId();
      //Logger.log("DEBUG: pagebreakID:"+pagebreakID);
      return pagebreakID;

    }

电子表格布局
Spreadsheet Screenshot


显示页面链接的下拉列表
Dropdowns showing page link