Получить URL-адрес формы из связанной с таблицей формы

В сценарии электронных таблиц я хочу отправлять пользователям письма с указанием URL-адреса формы, которая позволит им вводить данные. Я пытался:

function test1(){

  var formID = FormApp.getActiveForm();
  var formUrl = DriveApp.getUrl(formID);
  sendMail(formUrl);
  return
}

Это терпит неудачу, потому что значение formID всегда NULL.

2 ответа

Решение

Поскольку вы работаете в электронной таблице, вам необходимо получить связанную форму из объекта электронной таблицы (например, SpreadsheetApp.getActiveSpreadsheet.getFormUrl()).

Вам также необходимо отправить почтовое сообщение с необязательным параметром htmlBody.

Вот фрагмент кода:

function sendNotice(recipient){
  try{

    // either hardcode the folder id below
    var formStorageFolderId = '';

    // or programmatically get the folder from the spreadsheet parent
    var ss = SpreadsheetApp.getActiveSpreadsheet();

    var ssFolder = DriveApp.getFileById(ss.getId()).getParents();
    if(ssFolder.hasNext()){
      // assume there is only one parent folder
      formStorageFolderId = ssFolder.next().getId();
    }

    var formFolder = DriveApp.getFolderById(formStorageFolderId);

    var files = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
    var formId = '';
    while(files.hasNext()){
      // search for the form (is it the same name as the spreadsheet?)
      var file = files.next();
      var fileName = file.getName();
      var sheetName = ss.getName();
      if(fileName == sheetName){
        // matched names

        formId = file.getId();
        break;
      }
    }
    if(formId){
      var actualForm = FormApp.openById(formId);
      var formName = actualForm.getTitle();
      var formURL = actualForm.getPublishedUrl();

      var subject = "Please fill out form";
      // html mail message (needed for the link
      var mailBody = '<div><p>Please fill out the attached form<p>';
      mailBody += '<p><a href="' + formURL +'">' + formName + '</a>';

      MailApp.sendEmail(recipient, subject, '',{htmlBody:mailBody});
    }

  }catch(err){
    Logger.log(err.lineNumber + ' - ' + err);
  }
}

Если есть одна форма, связанная с электронной таблицей

использование

var ss = SpreadsheetApp.getActiveSpreadsheet(); // or openById, etc
var formUrl = ss.getFormUrl();

чтобы получить его URL. Если нужно, FormApp.openByUrl(formUrl); возвращает указатель на форму, что позволяет использовать любые другие методы.

Несколько форм, связанных с электронной таблицей

Нет встроенного метода для возврата списка форм, связанных с данной электронной таблицей; Это открытая проблема в трекере Apps Script. Обходной путь - поиск во всех формах ( как это сделал Сайрус Лори), получение пункта назначения каждой из них и возврат списка тех, для которых пункт назначения представляет собой интересующую электронную таблицу. Вот как:

function linkedForms() {
  var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
  var formList = [];
  var files = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
  while (files.hasNext()) {
    var form = FormApp.openByUrl(files.next().getUrl());
    try {
      if (form.getDestinationId() == ssId) {
        formList.push(form.getPublishedUrl());
      }
    }
    catch(e) {
    }
  }
  return formList;
}

Примечания:

  • я кладу form.getDestinationId() в блоке try, потому что этот метод выдает ошибку, что электронная таблица назначения формы удаляется (вместо того, чтобы просто возвращать null)
  • Чтобы получить список идентификаторов форм вместо URL, используйте form.getId() в функции.

Я знаю, что это старый вопрос, но я все же добавлю ответ, кому он может быть интересен. Ответ @user3717023 работает нормально, но для большинства случаев использования есть способ получше.

Вообще говоря, Form связан с Sheet, а не Spreadsheetсам. Итак, один способ получить все Spreadsheet формы должны пройти через Sheets из Spreadsheets, и получите URL-адрес их формы, например:

function getFormsOfSpreadsheet(spreadsheetId) {
  const ss = SpreadsheetApp.openById(spreadsheetId);
  const sheets = ss.getSheets();
  const formsUrls = [];

  for (const sheet of sheets) {
    const formUrl = sheet.getFormUrl();
    // getFormUrl() returns null if no form connected
    if (formUrl) {
      formsUrls.push(formUrl);
    }
  }
  
  return formsUrls;
}

Документы

Если этот способ не оптимален для вас (например, у вас слишком много Sheetв твоем Spreadsheet и только некоторые из них связаны с Forms), все еще существует вероятность того, что Forms, которые вам нужно захватить, хранятся в том же Folder. В этом случае нет необходимости перебирать все Drive для их захвата вы можете использовать тот же метод, но с Folder:

function linkedForms() {
  var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
  var formList = [];
  var folder = DriveApp.getFolderById(yourFolderId);
  var files = folder.getFilesByType(MimeType.GOOGLE_FORMS);
  while (files.hasNext()) {
    var form = FormApp.openByUrl(files.next().getUrl());
    try {
      if (form.getDestinationId() == ssId) {
        formList.push(form.getPublishedUrl());
      }
    }
    catch(e) {
    }
  }
  return formList;
}

Документы

Другие вопросы по тегам