从包含此函数调用的表单触发器中调用时,FormApp.getActiveForm()返回不正确的表单ID

时间:2019-02-09 19:41:56

标签: google-apps-script google-form

我正在尝试使用Google表单,php和mysql自动执行工作例程。我做了以下软件架构。

有一个名为S的表单,它是静态的,因为我是使用GUI手动创建的。 Form Sform具有表单提交触发器,该触发器将数据放入我的mysql数据库中。

之后,数据由php脚本处理,该脚本最终称为google脚本,该脚本作为网络应用程序发布。

此脚本获取参数并对其进行解析,从我的数据库中获取新处理的数据,并根据所选数据以编程方式构建表单,最后,它向动态(以编程方式)创建的一个或多个表单添加触发器(将其命名为Dform)

问题在于,以编程方式创建的表单的触发器中编码的函数FormApp.getActiveForm()返回了静态表单(手动创建)的表单ID。

以下是静态表单Sform提交触发器的代码:

function SaveData() {
  var form = FormApp.getActiveForm();
  var formResponses = form.getResponses();
  var formResponse = formResponses[formResponses.length-1];
  var email = formResponse.getRespondentEmail();
  var itemResponses = formResponse.getItemResponses();
  var workDay = null;
  var workFiles = null;
  for (var j = 0; j < itemResponses.length; j++) {
    var itemResponse = itemResponses[j];
    if (itemResponse.getItem().getTitle() == 'Pick the date of files you uploading') {
        workDay = itemResponse.getResponse().toString();
    }
    if (itemResponse.getItem().getTitle() == 'Choose log files to be uploaded') {
        workFilesIds = itemResponse.getResponse();
    }
  }

  var dbUrl = '...';
  var user = '...';
  var userPwd = '...';
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);

  var stmt = conn.prepareStatement('select worker_id from in_workers where worker_name = ?');
  stmt.setString(1, email);
  var results = stmt.executeQuery();
  var worker_id = -1;
  while (results.next()) {
    worker_id = results.getString(1);
  }
  results.close();

  if (worker_id == -1) {
    stmt = conn.prepareStatement('INSERT INTO in_workers '
                                   + '(worker_name) values (?)', 1);
    stmt.setString(1, email);
    stmt.executeUpdate();
    var res = stmt.getGeneratedKeys();
    res.beforeFirst();
    res.next();
    worker_id = res.getInt(1);
  }

  var fName = '';
  var fBlob = new Array(workFilesIds.length);
  for (var j = 0; j < workFilesIds.length; j++) {
    var file = DriveApp.getFileById(workFilesIds[j]);
    fName = fName + '\n\r' + file.getName();
    fBlob[j] = file;

    stmt = conn.prepareStatement('INSERT INTO test_dep_files '
                                   + '(worker_id, file_name, file_date, file_body) values (?, ?, ?, ?)');

    stmt.setString(1, worker_id);
    stmt.setString(2, file.getName());
    stmt.setDate(3, Jdbc.parseDate(workDay));
    stmt.setBytes(4, file.getBlob().getBytes());

    stmt.executeUpdate();
  }

  conn.close();

  GmailApp.sendEmail('...', 'Control workplace form completed'
                     , 'User ' + email + ' uploaded data on ' + workDay 
                     + ' file list: ' + fName, 
                     {attachments: fBlob, name: fName});
}

以下是作为Web应用程序发布的脚本代码:

function doGet(e) {
  var worker_id = e.parameter['worker_id'];
  var form_trig_func_name = e.parameter['form_trig_func_name'];

  var dbUrl = '...';
  var user = '...';
  var userPwd = '...';
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);

  stmt = conn.prepareStatement('select form_id from in_workers where worker_id = ?');
  stmt.setString(1, worker_id);
  var results = stmt.executeQuery();
  var form_id;
  results.beforeFirst();
  while (results.next()) {
    form_id = results.getString(1);
  }
  results.close();

  var form;
  try {
    form = FormApp.openById(form_id);
    var items = form.getItems();
    var l = items.length;
    for (var j = 0; j < l; j++) {
      form.deleteItem(0);
    }
  } catch (e) {
    form = FormApp.create('Enter additional products data');
  }

  stmt = conn.prepareStatement('select fc_id, fc_name_sys, fc_date from test_dep_fc t1' 
    + ', test_dep_files t2 where t1.file_id = t2.file_id and fc_name_real is null '
    + 'and worker_id = ?');
  stmt.setString(1, worker_id);
  var results = stmt.executeQuery();
  results.beforeFirst();
  while (results.next()) {
    form.addTextItem()
      .setTitle(results.getString(2) + ' от ' + results.getString(3))
      .setHelpText(results.getString(1));
  }
  results.close();

  form_id = form.getId();

  var allTriggers = ScriptApp.getUserTriggers(form);
  var l = allTriggers.length;
  for (var i = 0; i < l; i++) 
      ScriptApp.deleteTrigger(allTriggers[i]);
  allTriggers = ScriptApp.getProjectTriggers();
  l = allTriggers.length;
  for (var i = 0; i < l; i++) {
    if (allTriggers[i].getHandlerFunction() === 'saveData' + form_trig_func_name) {
      ScriptApp.deleteTrigger(allTriggers[i]);
    }
  }

  ScriptApp.newTrigger('saveData'+form_trig_func_name)
    .forForm(form)
    .onFormSubmit()
    .create();
  var form_url = form.getPublishedUrl();

  stmt = conn.prepareStatement('update in_workers set form_id = ?, form_url = ? where worker_id = ?');
  stmt.setString(1, form_id);
  stmt.setString(2, form_url);
  stmt.setString(3, worker_id);
  stmt.execute();
  conn.close();

  return HtmlService.createHtmlOutput(form_id + '\n\r' + form_trig_func_name);
}

这是动态(以编程方式)创建的表单Dforms的代码:

function saveData2() {
  var form = FormApp.getActiveForm();
  var formResponses = form.getResponses();
  var formResponse = formResponses[formResponses.length-1];
  var itemResponses = formResponse.getItemResponses();

  var dbUrl = '...';
  var user = '...';
  var userPwd = '...';
  var conn = Jdbc.getConnection(dbUrl, user, userPwd);

  var fc_names_real = '';
  var fc_ids = '';
  var fc_names_sys = '';

  for (var j = 0; j < itemResponses.length; j++) {
    var itemResponse = itemResponses[j];
    var fc_id = itemResponse.getItem().getHelpText();
    var fc_name_sys = itemResponse.getItem().getTitle();
    var fc_name_real = itemResponse.getResponse().toString();

    fc_names_real = fc_names_real + ' ' + fc_name_real;
    fc_ids = fc_ids + ' ' + fc_id;
    fc_names_sys = fc_names_sys + ' ' + fc_name_sys;

    stmt = conn.prepareStatement('update test_dep_fc '
                                   + 'set fc_name_real = ? where '
                                   + 'fc_id = ?');
    stmt.setString(1, fc_name_real);
    stmt.setString(2, fc_id);
    stmt.executeUpdate();
  }

  conn.close();

  GmailApp.sendEmail('...', 'Control workplace form2 completed'
                     , 'Product serial nums: ' + fc_names_real
                     + '\n\rProducts sys nums: ' + fc_names_sys 
                     + '\n\rProducts ids: ' + fc_ids
                     );
}

function saveData3() {
  the same code as for saveData2
  }
function saveData4() {
  the same code as for saveData2
  }
function saveData5() {
  the same code as for saveData2
  }
...

所以问题是在saveData2中,第一个代码指令返回了错误的表单ID。它总是返回Sform的表单ID。

请对此提供帮助,我准备认为我已经找到了Google表单错误。

非常感谢,雅罗斯拉夫

编辑1 嗨@tehhowch,谢谢,我确实尝试过,但是很遗憾,遵循以下代码

function saveData2(e) {
    //var form_id = e.source.getId();
    ...

也会返回错误的表单ID,它还会返回Sform ID。

1 个答案:

答案 0 :(得分:0)

最后,这个问题在第二天就被解决了。解决方案很简单,只是愚蠢的。

  1. 在作为Web应用程序代码发布的脚本中,我在表单创建代码之后添加以下说明。我将触发器函数名称保存到其属性。
  PropertiesService.getDocumentProperties().setProperty(
    'saveData'+form_trig_func_name, form_id);
  1. 用于动态(以编程方式)创建表单Dforms的代码已被重写。当相应的触发器触发时,我只是在先前保存的属性值中使用formId。
function saveData2(e) {
  //var form_id = e.source.getId();
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData2');
  saveDataAll (form_id, 2);
}
function saveData3() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData3');
  saveDataAll (form_id, 3);
}
function saveData4() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData4');
  saveDataAll (form_id, 4);
}
function saveData5() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData5');
  saveDataAll (form_id, 5);
}
function saveData6() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData6');
  saveDataAll (form_id, 6);
}
function saveData7() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData7');
  saveDataAll (form_id, 7);
}
function saveData8() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData8');
  saveDataAll (form_id, 8);
}
function saveData9() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData9');
  saveDataAll (form_id, 9);
}
function saveData10() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData10');
  saveDataAll (form_id, 10);
}
function saveData11() {
  var form_id = PropertiesService.getDocumentProperties().getProperty('saveData11');
  saveDataAll (form_id, 11);
}


function saveDataAll (form_id, saveData)
{
  var form = FormApp.openById(form_id);
  ...

此功能的用户最多只有十个,而这种变通办法对我有效。因此,问题已解决。