Единая форма Google для нескольких листов

Из-за постоянного управления версиями, а также из-за, казалось бы, непреодолимых проблем с реализацией обходных путей для разрешений пользователей, мне нужно захватывать данные формы, связанные с листом, который не виден пользователям. Вместо этого я хочу запустить форму из отдельного приложения для работы с электронными таблицами, используя настраиваемое меню. Тем не менее, несмотря на тщательный поиск в Google и метод с дразнящим названием FormApp.openById, я не могу найти способ добиться этого.

Я знаю, что здесь я сбился с пути; может ли кто-нибудь указать мне обратный путь?


person Tim    schedule 17.06.2013    source источник


Ответы (2)


Шаг 1. Создайте форму

Обычная рабочая процедура - создайте форму либо с помощью скрипта, либо с помощью пользовательского интерфейса форм. Захватите идентификатор формы. Например, из URL-адреса в редакторе:

https://docs.google.com/forms/d/1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ/edit
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Прикрепите электронную таблицу, чтобы записывать ответы. (Мы не собираемся здесь больше ничего делать.)

Шаг 2: клиентский скрипт

В доступной пользователю электронной таблице создайте связанный с контейнером скрипт (чтобы он имел доступ к пользовательскому интерфейсу электронной таблицы). Следующий сценарий создает настраиваемое меню с выбором, запускающим форму во всплывающем окне пользовательского интерфейса.

/**
 * Uses the Forms service to get a handle on an existing form, then retrieve its published URL.
 * Uses the UrlFetch Service to get a copy of the HTML for the form.
 * Uses the HtmlService to embed the form's HTML in a Spreadsheet UI.
 * ... which is finally shown using Spreadsheet.show().
 */
function launchForm() {
  var formID = '1-AWccGNgdJ7_5Isjer5K816UKNSaUPSlvlkY3dGJ1UQ';
  var form = FormApp.openById(formID);
  var formUrl = form.getPublishedUrl();

  var response = UrlFetchApp.fetch(formUrl);
  var formHtml = response.getContentText();

  var htmlApp = HtmlService
      .createHtmlOutput(formHtml)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setTitle('Ta Daaa!')
      .setWidth(500) 
      .setHeight(450);

  SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Launch Form",
    functionName : "launchForm"
  }];
  sheet.addMenu("Custom Menu", entries);
};

Демо

Вот что вы видите, когда выбираете «Запустить форму» в «Пользовательском меню». Одно небольшое раздражение - когда форма отправлена, пользователь попадает в другое окно или вкладку браузера. В электронной таблице пользовательский интерфейс остается открытым, и его необходимо закрыть вручную. Эта проблема исчезла с использованием изолированной программной среды IFRAME!

Снимок экрана - встроенная форма


РЕДАКТИРОВАТЬ: недавно были внесены изменения в настройки по умолчанию для песочницы ECMA, которые требуют, чтобы режим песочницы был явно установлен на ИСХОДНЫЙ, чтобы этот метод работал. Код обновлен.

Снова ИЗМЕНИТЬ: новый режим песочницы IFRAME сохраняет все возможности формы внутри диалогового окна.

person Mogsdad    schedule 17.06.2013
comment
Привет, Могсдад, я только что начал использовать этот метод, и он работает очень хорошо - еще раз спасибо! Однако одна проблема заключается в том, что загрузка занимает довольно много времени. Сама форма не особо сложная, состоит из 17 полей, только 2 со списками из 30 элементов. При запуске из меню «Форма» на листе, на котором размещена форма, она, как всегда, быстро загружается в новую вкладку. Я думаю, мне нужно отредактировать CSS, чтобы убрать некоторые теги по умолчанию, созданные Google, но интересно, есть ли что-то еще, что я мог упустить из виду - какие-нибудь мысли? - person Tim; 21.07.2013
comment
При многократных вызовах служб этот метод будет медленным - и я предполагаю, что больше всего будут стоить вызовы служб. (Проверьте стенограмму выполнения, чтобы узнать, куда идет время.) Этому может помочь использование Cache Services для хранения опубликованного URL-адреса и activeSpreadsheet, удаление 4+ вызовов службы и экономия нескольких секунд. - person Mogsdad; 21.07.2013
comment
Кнопка отправки формы не работает во всплывающем окне. Почему? - person MSD; 16.11.2016

Mogsdad направил меня на верный путь, но для того, чтобы кнопка отправки работала, мне пришлось встроить ее прямо в код.

1) Создайте форму и в меню форм выберите «Вставить форму на веб-страницу».

2) Скопируйте весь появившийся блок кода. Это должно выглядеть примерно так:

<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>

3) Добавьте эту функцию на свою страницу сценария

function launchForm() {
  var embeddedHtml = '<iframe src="https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true" width="500" height="450" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>'
  var htmlApp = HtmlService.createHtmlOutput(embeddedHtml)
  SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Title');
}

Если вы хотите, чтобы форматирование и баннер формы остались, удалите ?embedded=true со встроенной ссылки https://docs.google.com/forms/d/e/<YOUR_ID_NUMBER_HERE/viewform?embedded=true

person Hurricane    schedule 23.03.2020