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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Почему нельзя вызвать форму «напрямую» с сервера?

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

Метод 1: Возврат ссылки на созданный документ

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


&НаКлиенте
Процедура СоздатьИОткрытьДокумент(Команда)
    // Вызываем серверную функцию, которая вернет нам ссылку
    СсылкаНаНовыйДокумент = СоздатьДокументНаСервере();
    
    Если Не СсылкаНаНовыйДокумент.Пустая() Тогда
        // Подготавливаем параметры для открытия формы
        // "Ключ" — это стандартный параметр, указывающий на конкретный объект в базе
        ПараметрыОткрытия = Новый Структура("Ключ", СсылкаНаНовыйДокумент);
        
        ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыОткрытия);
    Иначе
        Сообщить("Не удалось создать документ.");
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СоздатьДокументНаСервере()
    НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
    НовыйДокумент.Дата = ТекущаяДатаСеанса();
    // Заполнение реквизитов...
    
    Попытка
        НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
        Возврат НовыйДокумент.Ссылка;
    Исключение
        Возврат Документы.РеализацияТоваровУслуг.ПустаяСсылка();
    КонецПопытки;
КонецФункции

В данном сценарии мы четко разделяем обязанности: сервер создает данные, а клиент управляет интерфейсом. Метод ОткрытьФорму принимает имя формы и структуру параметров, где в ключе "Ключ" передается ссылка. Система сама понимает, что нужно открыть существующий объект.

Метод 2: Использование структуры результата для сложных цепочек вызовов

Часто в процессе разработки возникает «цепочка вызовов», когда одна процедура вызывает другую, и простого возврата ссылки недостаточно. В таких случаях мы рекомендуем использовать специализированную структуру возврата. Это позволит клиентской части гибко реагировать на различные ситуации. Рассмотрим, как это реализовать:


&НаСервере
Функция ВыполнитьСложнуюОперациюНаСервере()
    Результат = Новый Структура;
    Результат.Вставить("Статус", Ложь);
    Результат.Вставить("Ссылка", Документы.РеализацияТоваровУслуг.ПустаяСсылка());
    Результат.Вставить("ТекстОшибки", "");

    // Логика создания документа
    Попытка
        // ... создание объекта ...
        Результат.Статус = Истина;
        Результат.Ссылка = СозданныйОбъект.Ссылка;
    Исключение
        Результат.ТекстОшибки = ОписаниеОшибки();
    КонецПопытки;

    Возврат Результат;
КонецФункции

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

Метод 3: Передача данных через временное хранилище

Бывают ситуации, когда документ еще не записан в базу (и ссылки нет), но вы хотите показать пользователю уже заполненную форму, чтобы он сам нажал кнопку «Записать». Если данных много, передавать их в структуре параметров между клиентом и сервером накладно для сети. Разберем использование ВременногоХранилища:

  1. На сервере подготавливаем данные (например, таблицу товаров или структуру реквизитов).
  2. Помещаем эти данные во временное хранилище с помощью метода ПоместитьВоВременноеХранилище().
  3. Возвращаем клиенту Адрес этого хранилища (строку).
  4. Передаем этот адрес в параметры открытия формы.
  5. В форме документа, в обработчике ПриСозданииНаСервере, извлекаем данные по адресу и заполняем объект.

Метод 4: Механизм «Обработки заполнения»

Посмотрим на альтернативный способ открытия формы с заполнением без предварительной записи. Если передать в ОткрытьФорму структуру, ключи которой совпадают с именами реквизитов документа (и эти ключи не являются системными), платформа попытается автоматически заполнить новый документ. Однако более профессиональный подход — использование процедуры ОбработкаЗаполнения в модуле самого документа.

Рассмотрим пример передачи данных:


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

В этом случае в модуле документа должен быть описан обработчик ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка), который корректно распределит данные по реквизитам и табличным частям.

Обновление интерфейса и оповещения

После того как вы программно создали объект и открыли его форму, важно убедиться, что другие части интерфейса (например, динамические списки в открытых окнах) узнали о появлении нового документа. Для этого проанализируем метод ОповеститьОЗаписиНового(Ссылка). Его следует вызывать на клиенте сразу после того, как сервер вернул ссылку на созданный объект. Это заставит списки перечитать данные и отобразить новую строку без перезагрузки всей формы.

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

Резюме и рекомендации

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

Соблюдение этих правил позволит вашему коду оставаться чистым, понятным и соответствующим стандартам разработки 1С.

← На главную