К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как передать форму с клиента на сервер

Форму нельзя передать на сервер напрямую. Разбираем рабочие способы: контекст формы, ДанныеФормыВЗначение, структуры, JSON и временное хранилище.

Короткий ответ на вопрос «как передать форму с клиента на сервер в 1С» — никак. Управляемая форма (объект типа УправляемаяФорма) существует только на клиенте и не сериализуется: платформа не умеет упаковать её вместе с реквизитами, элементами и оформлением и отправить в серверный вызов. Попытка передать форму как параметр серверной процедуры закончится ошибкой о невозможности передачи данных между клиентом и сервером.

На практике задача решается иначе. Вместо самой формы на сервер передают её данные: значения реквизитов, преобразованные в прикладные объекты, структуры с нужными полями или сериализованные представления. В большинстве типовых сценариев передавать вообще ничего не нужно — серверная процедура, вызванная из контекста формы, уже имеет доступ к её реквизитам.

Ниже разобраны все рабочие варианты: от простого вызова серверной процедуры из модуля формы до передачи данных в фоновые задания и между разными формами. Для каждого способа указаны условия, ограничения и типичные ошибки.

Почему форму нельзя передать на сервер

Управляемая форма в 1С — это клиентский объект. Она содержит не только данные, но и дерево элементов интерфейса, настройки видимости, условное оформление, связи с элементами. Всё это существует в памяти клиентского приложения и не имеет серверного представления, которое можно было бы сериализовать.

Платформа явно контролирует типы, пересекающие границу «клиент–сервер». Разрешены примитивы (число, строка, дата, булево), ссылки на объекты базы, структуры, массивы, соответствия, таблицы значений (с ограничениями) и прикладные объекты. Тип УправляемаяФорма в этот список не входит — при попытке передать его параметром вы получите ошибку вида «Передача данных между клиентом и сервером невозможна».

Поэтому правильная постановка задачи звучит иначе: не «как передать форму», а «как передать данные формы» или «как выполнить серверную логику с доступом к данным формы». У каждой из этих задач есть штатное решение.

Способ 1. Серверная процедура в модуле формы с директивой &НаСервере

Самый частый случай: вам нужно выполнить серверную логику (запрос к базе, запись объекта, обращение к менеджерам), используя данные текущей формы. Здесь ничего передавать не требуется — достаточно объявить процедуру с директивой &НаСервере в модуле той же формы.

При таком вызове платформа сама пересоздаёт контекст формы на сервере: все реквизиты формы, включая основной реквизит (например, Объект типа ДанныеФормыСтруктура), доступны внутри процедуры напрямую. После завершения изменения возвращаются на клиент автоматически.

&НаКлиенте

Процедура РассчитатьИтог(Команда)

РассчитатьИтогНаСервере();

КонецПроцедуры

&НаСервере

Процедура РассчитатьИтогНаСервере()

// Объект и другие реквизиты формы доступны напрямую

Объект.СуммаДокумента = Объект.Товары.Итог("Сумма");

КонецПроцедуры

Обратите внимание на нюанс с директивой &НаСервереБезКонтекста. Такая процедура работает быстрее, потому что контекст формы на сервер не передаётся, — но и доступа к реквизитам формы в ней нет. Если вы объявили процедуру без контекста и пытаетесь обратиться к Объект.СуммаДокумента, получите ошибку компиляции. Выбирайте директиву осознанно: без контекста — только когда процедуре реально нужны лишь переданные параметры.

Способ 2. Преобразование данных формы через ДанныеФормыВЗначение

Основной реквизит управляемой формы документа или справочника имеет тип ДанныеФормыСтруктура — это не прикладной объект, а его «форменное» представление. Чтобы передать данные в серверный общий модуль или работать с объектом штатными средствами (проведение, проверка заполнения), его преобразуют методом ДанныеФормыВЗначение.

Метод доступен только на сервере и только в контексте формы. Обратное преобразование выполняется методом ЗначениеВДанныеФормы — так изменённый объект возвращается обратно в форму.

&НаСервере

Процедура ПровестиНаСервере()

ДокОбъект = ДанныеФормыВЗначение(Объект, Тип("ДокументОбъект.РеализацияТоваров"));

ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

ЗначениеВДанныеФормы(ДокОбъект, Объект);

КонецПроцедуры

Типичная ошибка — вызвать ДанныеФормыВЗначение на клиенте: метода там нет, и код упадёт ещё при проверке модуля. Вторая ошибка — забыть обратное преобразование: объект записан, но форма показывает старые данные, потому что ЗначениеВДанныеФормы не вызван.

Способ 3. Передача данных через структуру

Когда серверной процедуре нужны не все данные формы, а несколько конкретных значений, их упаковывают в структуру и передают параметром. Это стандартный способ для вызовов &НаСервереБезКонтекста и серверных общих модулей.

&НаКлиенте

Процедура ПодобратьЦену(Команда)

ПараметрыРасчета = Новый Структура;

ПараметрыРасчета.Вставить("Номенклатура", Объект.Номенклатура);

ПараметрыРасчета.Вставить("Дата", Объект.Дата);

Объект.Цена = ПолучитьЦенуНаСервере(ПараметрыРасчета);

КонецПроцедуры

&НаСервереБезКонтекста

Функция ПолучитьЦенуНаСервере(ПараметрыРасчета)

// работа с параметрами структуры

КонецФункции

Структура хорошо сериализуется, но содержимое должно состоять из допустимых типов: примитивов, ссылок, вложенных структур, массивов. Вложить туда элемент формы, таблицу формы или саму форму нельзя — ошибка та же, что и при прямой передаче формы.

Если нужно передать табличную часть, варианта два: либо работать в контексте формы (&НаСервере), где таблица доступна как ДанныеФормыКоллекция, либо выгрузить её в таблицу значений на сервере через преобразование объекта. Передавать ДанныеФормыКоллекция параметром в процедуру без контекста нельзя.

Типичные ошибки
01
Передача УправляемойФормы параметром серверной процедуры — ошибка сериализации, способ не существует в принципе
02
Вызов ДанныеФормыВЗначение на клиенте — метод доступен только на сервере
03
Объявление процедуры &НаСервереБезКонтекста и обращение к реквизитам формы — ошибка компиляции модуля
04
Забытое ЗначениеВДанныеФормы после изменения объекта — форма отображает устаревшие данные
05
Попытка положить элемент формы или ДанныеФормыКоллекция в структуру для передачи — ошибка передачи данных

Способ 4. JSON и временное хранилище для сложных сценариев

Сериализация в JSON

Если данные формы нужно передать не просто на сервер, а дальше — во внешний сервис, в фоновое задание с собственным соединением, в другой сеанс — используют сериализацию. Платформа имеет встроенные средства: ЗаписьJSON/ЧтениеJSON и функции СериализаторXDTO.

На практике чаще собирают структуру с нужными полями и сериализуют её в JSON-строку. Строка — примитивный тип, она свободно пересекает границу клиент–сервер и хранится где угодно. На приёмной стороне строка разбирается обратно. Минус подхода — ссылки при сериализации превращаются в строковые представления, и восстанавливать их нужно отдельно (обычно по уникальному идентификатору).

Временное хранилище

Временное хранилище — штатный механизм передачи больших данных между серверными вызовами и между формами. Данные помещаются на сервере методом ПоместитьВоВременноеХранилище, а клиенту или другой форме передаётся только адрес — строка вида e1cib/tempstorage/....

&НаСервере

Функция ПодготовитьДанныеНаСервере()

ТаблицаРезультат = СформироватьТаблицу();

Адрес = ПоместитьВоВременноеХранилище(ТаблицаРезультат, УникальныйИдентификатор);

Возврат Адрес;

КонецФункции

Второй параметр — уникальный идентификатор формы — привязывает хранилище к времени жизни формы: пока форма открыта, данные гарантированно доступны. Без привязки данные удаляются при очистке, и момент очистки не гарантирован. Этот же механизм используется при передаче данных между формами: открывающая форма помещает данные в хранилище, открываемая получает адрес через параметры.

Сравнение способов

Контекст формы (&НаСервере)

Подходит почти всегда внутри модуля формы; не работает из общих модулей и других форм

Структура параметров

Оптимальна для вызовов без контекста; ограничена сериализуемыми типами

ДанныеФормыВЗначение

Нужен для работы с прикладным объектом на сервере; требует обратного преобразования

Временное хранилище

Для больших данных и передачи между формами; требует контроля времени жизни

JSON

Для фоновых заданий и обмена с внешними системами; ссылки требуют ручного восстановления

Способ 5. Данные формы в фоновом задании

Длительные операции из формы принято запускать через фоновые задания (ДлительныеОперации в БСП или ФоновыеЗадания.Выполнить напрямую). Фоновое задание выполняется в отдельном сеансе, где никакой формы не существует — передать туда можно только сериализуемые параметры.

Порядок действий стандартный: на клиенте или в серверном контексте формы собираете структуру параметров, при необходимости большие данные помещаете во временное хранилище и передаёте в задание адрес. Результат задание также кладёт во временное хранилище, а форма забирает его по адресу после оповещения о завершении.

Порядок действий для фонового задания
  1. 1
    Соберите нужные поля формы в структуру параметров
  2. 2
    Поместите объёмные данные во временное хранилище с привязкой к УникальныйИдентификатор формы
  3. 3
    Запустите фоновое задание, передав структуру и адрес хранилища
  4. 4
    В процедуре задания получите данные из хранилища по адресу
  5. 5
    Результат поместите во временное хранилище, верните адрес
  6. 6
    В форме по оповещению о завершении загрузите результат и обновите реквизиты

Частая ошибка — попытка передать в фоновое задание ДанныеФормыКоллекция или ссылку на «форменные» данные. В новом сеансе эти объекты не существуют. Передавайте только примитивы, ссылки, структуры и адреса хранилища.

Проверка результата и границы безопасной работы

После внедрения любого из способов проверьте три вещи. Первое: серверный вызов выполняется без ошибок передачи данных — это видно уже при первом запуске. Второе: данные на сервере совпадают с тем, что введено в форме, особенно табличные части и значения ссылочных типов. Третье: после серверной обработки форма отображает актуальные данные — если выполнялось ДанныеФормыВЗначение, убедитесь, что сделан обратный ЗначениеВДанныеФормы.

Дополнительно проверьте работу в тонком и веб-клиенте, если решение должно работать в обоих. Некоторые особенности сериализации и доступности методов различаются, и код, проверенный только в толстом клиенте, может вести себя иначе.

Контрольные точки

Как проверить результат

Серверный вызов из формы
Норма

Выполняется без ошибок передачи данных

Тревожный признак

Ошибка «передача данных между клиентом и сервером невозможна»

Значения на сервере
Норма

Совпадают с данными формы, включая табличные части

Тревожный признак

Пустые или устаревшие значения реквизитов

Форма после обработки
Норма

Отображает изменённые данные

Тревожный признак

Данные записаны в базу, но форма показывает старое

Фоновое задание
Норма

Получает параметры и возвращает результат по адресу

Тревожный признак

Ошибка сериализации параметров при запуске

Работа с передачей данных не затрагивает данные базы напрямую, но будьте осторожны с процедурами, которые внутри серверного вызова записывают или проводят объекты. Тестируйте такие доработки на копии базы: ошибка в логике проведения, запущенная из формы массовой обработки, испортит реальные документы.

Часто задаваемые вопросы

Можно ли передать форму как параметр в общий серверный модуль?

Нет. Тип УправляемаяФорма не сериализуется, и платформа запрещает его передачу между клиентом и сервером. Передавайте в общий модуль структуру с нужными значениями или адрес временного хранилища — это штатные замены.

Чем &НаСервере отличается от &НаСервереБезКонтекста?

Процедура &НаСервере получает на сервере весь контекст формы — реквизиты доступны напрямую. &НаСервереБезКонтекста работает быстрее, но контекст не передаётся, и обращаться к реквизитам формы внутри такой процедуры нельзя — только к переданным параметрам.

Как передать табличную часть формы в процедуру без контекста?

Напрямую — никак: ДанныеФормыКоллекция не сериализуется. Либо перенесите логику в процедуру &НаСервере с контекстом, либо преобразуйте объект через ДанныеФормыВЗначение и выгрузите табличную часть в таблицу значений, которую уже можно использовать на сервере.

Зачем нужен второй параметр в ПоместитьВоВременноеХранилище?

Это уникальный идентификатор формы, к которому привязывается время жизни данных. С привязкой данные гарантированно доступны, пока форма открыта. Без неё хранилище может быть очищено в непредсказуемый момент, и попытка получить данные по адресу вернёт ошибку.

Можно ли получить доступ к форме из фонового задания?

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

Почему после записи объекта на сервере форма показывает старые данные?

Вы изменили прикладной объект, полученный через ДанныеФормыВЗначение, но не вернули его в форму. Добавьте вызов ЗначениеВДанныеФормы(Объект, реквизит формы) после изменений — тогда форма отобразит актуальное состояние.

Итог

Что важно запомнить

Форму на сервер передать нельзя — передают её данные. Внутри модуля формы используйте контекст (&НаСервере), для вызовов без контекста — структуры параметров, для прикладных объектов — ДанныеФормыВЗначение с обратным преобразованием, для больших данных и фоновых заданий — временное хранилище.