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

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

1С: как с сервера открыть форму

Разбираем, почему в 1С нельзя напрямую открыть форму с сервера, и какие механизмы использовать: ОткрытьФорму на клиенте, оповещения, обработчики ожидания и параметры формы.

Вопрос «как с сервера открыть форму» возникает у разработчиков 1С регулярно: логика выполняется в серверной процедуре, и кажется естественным оттуда же показать пользователю форму документа, отчёта или обработки. Однако архитектура платформы 1С:Предприятие 8 устроена иначе: серверный код не имеет доступа к интерфейсу пользователя и не может открывать формы напрямую. Попытка вызвать ОткрытьФорму() в серверном контексте завершится ошибкой компиляции или выполнения.

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

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

Почему серверный код не может открывать формы

В управляемом приложении 1С код явно разделён директивами компиляции: &НаСервере, &НаКлиенте, &НаСервереБезКонтекста. Клиентские методы интерактивного интерфейса — ОткрытьФорму(), ПолучитьФорму(), ОткрытьЗначение(), ПоказатьВопрос() — доступны только в контексте &НаКлиенте. Серверная процедура физически выполняется на сервере приложений, где нет ни экрана, ни сеанса тонкого клиента в привычном смысле.

Если попробовать вызвать ОткрытьФорму() внутри серверной процедуры, конфигуратор при проверке модуля выдаст ошибку вида «Процедура или функция с указанным именем не определена» либо ошибка возникнет в момент исполнения. Это защита платформы от логически невозможной операции: сервер может обслуживать десятки сеансов одновременно, и у него нет способа понять, на чей экран выводить форму.

Базовый способ: серверная логика плюс открытие формы на клиенте

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

// Клиентская процедура в форме или общем модуле

&НаКлиенте

Процедура СоздатьИОткрытьДокумент(Команда)

НоваяСсылка = СоздатьДокументНаСервере();

Если ЗначениеЗаполнено(НоваяСсылка) Тогда

ОткрытьЗначение(НоваяСсылка);

КонецЕсли;

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

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

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

Док = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

Док.Дата = ТекущаяДатаСеанса();

Док.Заполнить(Неопределено);

Док.Записать();

Возврат Док.Ссылка;

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

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

Если документ записывать на сервере раньше времени нежелательно (пользователь может отказаться от сохранения), лучше открывать форму с параметрами заполнения: создаётся структура с реквизитами, передаётся в ОткрытьФорму(), а документ записывается уже в форме по решению пользователя.

bsl
&НаКлиенте
Процедура ОткрытьСЗаполнением(Команда)
	ПараметрыЗаполнения = Новый Структура("Основание", ПолучитьДанныеОснования());
	ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыЗаполнения);
КонецПроцедуры

Открытие формы с параметрами, подготовленными на сервере

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

&НаКлиенте

Процедура ПоказатьПросроченныеЗаказы(Команда)

Отбор = СформироватьОтборНаСервере();

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

ПараметрыФормы.Вставить("Отбор", Отбор);

ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);

ОткрытьФорму("Документ.ЗаказПокупателя.ФормаСписка", ПараметрыФормы);

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

Параметр СформироватьПриОткрытии актуален для форм отчётов: он заставляет отчёт выполниться сразу при открытии, без нажатия кнопки «Сформировать». Для форм списков достаточно передать структуру Отбор — платформа сама применит его к динамическому списку, если поля отбора доступны.

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

Открытие формы «по событию с сервера»: оповещения и обработчики ожидания

Иногда требуется обратная инициатива: событие произошло на сервере (завершилось фоновое задание, изменились данные), и форма должна открыться или обновиться у пользователя. Прямого канала «сервер → клиент» в платформе нет, поэтому используются два механизма.

Оповещения между открытыми формами

Метод Оповестить() вызывается на клиенте и рассылает сообщение всем открытым формам, подписанным через обработчик ОбработкаОповещения. Типичный сценарий: форма А выполнила серверную операцию и оповещает форму Б, которая по этому сигналу открывает третью форму или обновляет список. Само по себе оповещение не «пробивает» границу сервер-клиент — оно работает только внутри клиентского сеанса.

Обработчик ожидания для проверки фоновых заданий

Если на сервере запущено длительное фоновое задание и по его завершении нужно открыть форму результата, используется ПодключитьОбработчикОжидания(). Клиент периодически (например, раз в 2–5 секунд) вызывает серверную функцию, проверяющую состояние задания по его уникальному идентификатору. Когда задание завершено, клиент получает результат из временного хранилища и открывает форму.

&НаКлиенте

Процедура ПроверитьЗавершениеЗадания()

Результат = ПроверитьЗаданиеНаСервере(ИдентификаторЗадания);

Если Результат.Завершено Тогда

ОтключитьОбработчикОжидания("ПроверитьЗавершениеЗадания");

ОткрытьФорму("Обработка.РезультатыЗагрузки.Форма.Результат",

Новый Структура("АдресРезультата", Результат.АдресХранилища));

КонецЕсли;

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

Порядок действий при длительной операции
  1. 1
    На клиенте запустите фоновое задание через серверный вызов (ДлительныеОперации.ВыполнитьВФоне в БСП или ФоновыеЗадания.Выполнить)
  2. 2
    Сохраните идентификатор задания и адрес временного хранилища результата
  3. 3
    Подключите обработчик ожидания с разумным интервалом (2–5 секунд)
  4. 4
    В обработчике проверяйте состояние задания серверным вызовом
  5. 5
    При завершении отключите обработчик, получите результат и откройте форму на клиенте

Открытие форм из внешних источников: HTTP-сервисы, регламентные задания, COM

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

Практические альтернативы:

  • Запись события в базу. Регламентное задание сохраняет информацию (например, в регистр сведений «УведомленияПользователей»), а клиентские сеансы периодически проверяют её обработчиком ожидания и открывают форму при появлении новых записей.
  • Система взаимодействия. Встроенный механизм обсуждений и уведомлений позволяет отправить пользователю сообщение с навигационной ссылкой — по клику откроется нужная форма или объект.
  • Навигационные ссылки. Метод ПолучитьНавигационнуюСсылку() формирует ссылку вида e1cib/data/..., которую можно отправить пользователю любым способом; при переходе по ней в сеансе 1С откроется форма объекта.

Если требуется открыть форму на стороне COM-соединения или внешнего соединения — это возможно только если внешнее приложение само является клиентом 1С (например, через Automation-сервер с видимостью). В тонком и веб-клиенте такой сценарий недоступен и считается устаревшей практикой.

Сравнение подходов и выбор под задачу

Выбор способа зависит от того, где возникает потребность открыть форму и есть ли активный клиентский сеанс. Таблица помогает сопоставить условия.

СценарийМеханизмОграничения
Кнопка в форме, нужна серверная логика перед открытиемСерверный вызов + ОткрытьФорму на клиентеДва вызова, но работает везде
Открытие формы по завершении фонового заданияОбработчик ожидания + проверка состоянияЗадержка до интервала опроса
Событие от регламентного задания или обменаРегистр уведомлений / система взаимодействияНет гарантии мгновенной доставки
Переход к объекту из письма или внешней системыНавигационная ссылка e1cibТребует запущенного сеанса 1С
Связь между двумя открытыми формамиОповестить + ОбработкаОповещенияРаботает только внутри одного сеанса

Сравнение вариантов

ОткрытьФорму после серверного вызова

Универсальный и предсказуемый вариант; подходит для любых интерактивных сценариев, но требует разделения кода на два метода

Обработчик ожидания

Единственный способ реагировать на серверные события в активном сеансе; минус — лишние серверные вызовы и задержка реакции

Система взаимодействия и навигационные ссылки

Подходит для асинхронных уведомлений без активного ожидания; требует настройки и не даёт мгновенного открытия формы

Типичные ошибки и как их избежать

Первая и самая частая ошибка — попытка вызвать ОткрытьФорму() или Предупреждение() внутри серверной процедуры «для проверки». Даже если код иногда «работает» в файловом варианте при толстом клиенте, в клиент-серверном режиме и веб-клиенте он гарантированно сломается. Проверку модулей с разными режимами компиляции стоит включать в конфигураторе при разработке.

Вторая ошибка — передача несериализуемых объектов с сервера на клиент: ДокументОбъект, Запрос, РезультатЗапроса. Это вызывает ошибку «Ошибка передачи данных между клиентом и сервером». Решение — возвращать ссылки, структуры, массивы и таблицы значений.

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

Типичные ошибки
01
Вызов ОткрытьФорму в серверной процедуре — ошибка компиляции или выполнения; выносите открытие в клиентский контекст
02
Возврат ДокументОбъект с сервера — ошибка сериализации; возвращайте ссылку или структуру данных
03
Интервал обработчика ожидания меньше секунды — избыточная нагрузка на сервер; ставьте 2–5 секунд
04
Не отключённый обработчик ожидания — ошибки после закрытия формы; отключайте в ПриЗакрытии и при получении результата
05
Ожидание мгновенной реакции на событие регламентного задания — её нет; используйте периодическую проверку или систему взаимодействия

Проверка результата и диагностика

После внедрения выбранного механизма проверьте его в условиях, близких к рабочим: в клиент-серверном режиме (если он используется), в тонком и веб-клиенте, под пользователем с ограниченными правами. Ошибки контекста часто всплывают только в веб-клиенте, где недоступны многие возможности толстого клиента.

Для сценариев с фоновыми заданиями полезно логировать состояние задания в журнал регистрации: запись о запуске, завершении и ошибках позволяет быстро понять, на каком этапе цепочка «задание → проверка → открытие формы» оборвалась. Если форма не открывается, проверьте: завершилось ли задание, вернула ли серверная функция ожидаемое значение, не отклонил ли вызов ОткрытьФорму обработчик ОбработкаЗаполнения или права доступа к объекту.

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

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

Вызов ОткрытьФорму
Норма

Форма открылась с переданными параметрами и отбором

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

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

Серверная функция
Норма

Возвращает ссылку или структуру простых типов

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

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

Обработчик ожидания
Норма

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

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

Продолжает срабатывать после закрытия формы

Права пользователя
Норма

Форма открывается под целевой ролью

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

Нарушение прав доступа при открытии

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

Можно ли открыть форму прямо из процедуры &НаСервере?

Нет. Методы интерактивного интерфейса недоступны в серверном контексте по архитектурным причинам. Нужно вернуть данные на клиент и вызвать ОткрытьФорму() в клиентской процедуре.

Как открыть форму нового документа, заполнив его на сервере, но не записывая?

Передайте с сервера структуру с данными заполнения и откройте форму с параметром ЗначенияЗаполнения, либо обработайте параметры в ПриСозданииНаСервере формы объекта. Документ будет записан только при нажатии «Записать» или «Провести».

Как узнать на клиенте, что фоновое задание завершилось?

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

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

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

Почему код с ОткрытьФорму работает в файловой базе, но падает на сервере?

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

Итог

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

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