【问题标题】:App Script not updating Doc to include existing data on Form editsApp Script 未更新 Doc 以包含有关表单编辑的现有数据
【发布时间】:2020-05-13 12:44:05
【问题描述】:

我一直在研究基于 Google 表单提交自动填充表单的过程。迄今为止,我所有的进步都是我在这个网站上学到的。感谢大家的帮助!

假设表单已完整填写,我让所有内容都按照运行所需的方式运行。技术人员填写谷歌表格并提交。他/她提交后,脚本会自动生成包含所有数据的自定义文档。

运行一段时间后,技术人员要求我们在提交后使 Google 表单可编辑。我做了一些研究,发现您可以使表单可编辑并编写一些脚本来自动为每个表单生成自定义 URL。

现在我在提交部分表单时遇到了自动文档的问题。如果技术人员填写表格的前半部分并提交,则会自动生成一个文档,其中只有前半部分数据,这是我预期的。现在,如果他们返回并填写表格的第二部分,则只填写 Doc 的第二部分。我以为它会从工作表中提取整行数据,但事实并非如此。

经过一番思考,我觉得我需要重写代码,在提交表单时自动生成Doc,因为越来越多的表单会被分块填写,并在一个以后的日期。

这是我想做的。任何见解或有用的链接将不胜感激!非常感谢!

当前所有表单数据都进入工作表选项卡 A。我将在工作表上添加第二个选项卡 B,名为“Data to Doc”。我会手动梳理选项卡 A,然后将数据复制并粘贴到我想为其创建 Doc 的选项卡 B。在工作表 B 上,我可以单击一个按钮,该按钮将运行脚本以将工作表数据转换为 Doc 文件。

我找到了一段我认为我想做的视频,但我似乎无法让我的代码像他们那样工作。 https://www.youtube.com/watch?v=r9uU_KwGgzQ

以下是我当前的代码。

var docTemplate = "fdgfdg"; 
var docName = "Technician Report";
var folder = DriveApp.getFolderById('hjhjghhgjgh');

function onFormSubmit(e) {
var replaceTextToImage = function(body, searchText, fileId) {
 var width = 300; // Please set this.
 var blob = DriveApp.getFileById(fileId).getBlob();
 var r = body.findText(searchText).getElement();
 r.asText().setText("");
 var img = r.getParent().asParagraph().insertInlineImage(0, blob);
 var w = img.getWidth();
 var h = img.getHeight();
 img.setWidth(width);
 img.setHeight(width * h / w);
}

//Get information from form and set as variables
var Technician = e.values[1];
var Customer_Name = e.values[2];
var Date = e.values[3];
var Facility_Location = e.values[4];
var WO_Project_No = e.values[5];
var PO_No = e.values[6];
var Tag_No = e.values[7];
var Site_Contact = e.values[8];
var Repair_Scope = e.values[9];
var Valve_Serial_No = e.values[10];
var Valve_Model = e.values[11];
var Valve_Condition = e.values[12];
var Valve_Action = e.values[13];
var Act_Serial_No = e.values[14];
var Act_Model = e.values[15];
var Act_Condition = e.values[16];
var Act_Action = e.values[17];
var Cont_Serial_No = e.values[18];
var Cont_Model = e.values[19];
var Cont_Condition = e.values[20];
var Cont_Action = e.values[21];
var Recommended_Actions = e.values[30];
var Call_Notes = e.values[32];
var Picture1_Notes = e.values[23];
var Picture2_Notes = e.values[25];
var Picture3_Notes = e.values[27];
var Picture1_Image = e.values[22].split("=")[1];
var Picture2_Image = e.values[24].split("=")[1];
var Picture3_Image = e.values[26].split("=")[1];



// Get document template, copy it as a new temp doc, and save the Doc’s id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName+' for '+Customer_Name+' '+Tag_No, folder)
.getId();  
 // Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getBody();


copyBody.replaceText('A1', Technician);
copyBody.replaceText('A2', Customer_Name);
copyBody.replaceText('A3', Date);
copyBody.replaceText('A4', Facility_Location);
copyBody.replaceText('A5', WO_Project_No);
copyBody.replaceText('A6', PO_No);
copyBody.replaceText('A7', Tag_No);
copyBody.replaceText('A8', Site_Contact);
copyBody.replaceText('A9', Repair_Scope);
copyBody.replaceText('B1', Valve_Serial_No);
copyBody.replaceText('B2', Valve_Model);
copyBody.replaceText('B3', Valve_Condition);
copyBody.replaceText('B4', Valve_Action);
copyBody.replaceText('B5', Act_Serial_No);
copyBody.replaceText('B6', Act_Model);
copyBody.replaceText('B7', Act_Condition);
copyBody.replaceText('B8', Act_Action);
copyBody.replaceText('B9', Cont_Serial_No);
copyBody.replaceText('C1', Cont_Model);
copyBody.replaceText('C2', Cont_Condition);
copyBody.replaceText('C3', Cont_Action);
copyBody.replaceText('C4', Recommended_Actions);
copyBody.replaceText('C5', Call_Notes);
copyBody.replaceText('C8', Picture1_Notes);
copyBody.replaceText('D1', Picture2_Notes);
copyBody.replaceText('D3', Picture3_Notes);
replaceTextToImage(copyBody, 'C7', Picture1_Image);
replaceTextToImage(copyBody, 'C9', Picture2_Image);
replaceTextToImage(copyBody, 'D2', Picture3_Image);


copyDoc.saveAndClose();

【问题讨论】:

  • 您认为只有在表单已经完成,即所有问题都已回答的情况下才生成文档?
  • @ziganotschka 我认为这也可以!
  • 感谢@ziganotschka 的回复。我应该把这个放在一个特定的地方吗?我还需要添加什么吗?我试图添加它,但它没有工作。再次道歉,我真的不知道自己在做什么,努力学习!
  • 您需要将其余代码合并到 if 语句中。所以if(e.response.getItemResponses().length == length){var replaceTextToImage = function(body, searchText, fileId) {...copyDoc.saveAndClose();}else{ Logger.log("Form is not complete"); } - 提供你的代码有效 - 我没有测试。
  • 我唯一注意到的是您使用了e.values,这让我相信您的脚本绑定到电子表格,而不是表单 - 电子表格和表单onSubmit 触发器具有不同的事件对象。我给你的脚本示例需要绑定到表单,所以它不会识别。 e.values。相反,将e.values[1] 替换为e.response.getItemResponses()[0].getResponse() 等。

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


【解决方案1】:

假设您有一个脚本绑定到带有onSubmit 触发器的表单,您可以检索最新响应的长度并将其与问题总数进行比较:

function myFunction(e) {
  var length = FormApp.getActiveForm().getItems().length;
    if(e.response.getItemResponses().length == length){
    //proceed to generate custom document
  }else{   
    Logger.log("Form is not complete");
  }
}

更新:如果已选中复选框,则替代解决方案创建文档

  • 在这种情况下,您不想在提交表单时运行该函数,而是在对复选框进行编辑时运行。

  • 因此,将onSubmit 触发器替换为onEdit 触发器。

  • 这将允许您访问事件对象e.rangee.oldValuee.value

  • 您可以实现 if 语句,该语句仅在复选框列中进行了编辑并且旧值为 false (unchecked) and the new one istrue`(选中)时运行代码。
  • 很遗憾,您无法使用e.values 检索表单响应onEdit,相反,您可以验证复选框已选中的行并使用sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues(); 检索该行的值
  • 要实施更改,请创建一个带有复选框的列(假设在第 29 列,因为之前的列被响应占用)并修改您的代码,如下所示:
function onEdit(e){
  if(e.range.getColumn() == 29 || e.oldValue == false && e.value == true){
    var row = e.range.getRow();
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    var values = sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues()[0];
    var replaceTextToImage = function(body, searchText, fileId) {
      var width = 300; // Please set this.
      var blob = DriveApp.getFileById(fileId).getBlob();
      var r = body.findText(searchText).getElement();
      r.asText().setText("");
      var img = r.getParent().asParagraph().insertInlineImage(0, blob);
      var w = img.getWidth();
      var h = img.getHeight();
      img.setWidth(width);
      img.setHeight(width * h / w);
    }

    //Get information from form and set as variables
    var Technician = values[1];
    var Customer_Name = values[2];
   ...
   ... 
    copyDoc.saveAndClose();
  }
}

【讨论】:

  • 很高兴帮助您@KevinCehelsky!如果可以的话,出于文档目的,请接受对您有帮助的答案 (✓) - 它可以帮助将来遇到相同问题的其他人也找到解决方案:)
猜你喜欢
  • 2016-03-14
  • 2019-12-02
  • 2021-05-30
  • 1970-01-01
  • 2021-03-11
  • 2021-02-04
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
相关资源
最近更新 更多