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

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

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

Выясняем причину: разделение контекстов выполнения

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

Рассмотрим основные ограничения серверного контекста:

  1. Отсутствие интерактивности: На сервере нельзя вызывать диалоги, предупреждения, вопросы или команды открытия форм.
  2. Изоляция процессов: Код на сервере работает с данными (таблицами, запросами, объектами), а код на клиенте — с отображением этих данных.
  3. Различия в платформе: В файловой базе (особенно в толстом клиенте) границы контекстов могут быть размыты, из-за чего старый код может «случайно» работать. Но в полноценном клиент-серверном варианте (SQL) такие вызовы всегда будут вызывать исключение.

Поэтому фраза «в модуле документа — никак» (сообщение 3) является технически верной. Для решения задачи нам необходимо вернуть управление на клиентскую сторону.

Решение 1: Возврат созданных ссылок на клиент

Если ваша задача — программно создать несколько документов в базе, записать их и затем показать пользователю, проанализируем следующую схему работы. Мы должны инициировать процесс с клиента, выполнить создание на сервере, вернуть массив ссылок и открыть их на клиенте.

Посмотрим на пример реализации в модуле формы или в модуле команды:


&НаКлиенте
Процедура СоздатьИОткрытьДокументы()
    
    // 1. Вызываем серверную функцию для создания объектов
    МассивСсылок = СоздатьДокументыНаСервере();
    
    // 2. Возвращаемся на клиент и в цикле открываем каждую форму
    Для Каждого СсылкаИзСписка Из МассивСсылок Цикл
        // Используем стандартный метод открытия значения
        ПоказатьЗначение(, СсылкаИзСписка);
    КонецЦикла;
    
КонецПроцедуры

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

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

Решение 2: Открытие формы незаписанного документа

Иногда пользователю не нужно сразу записывать документы в базу. Например, если он должен проверить заполненные данные перед сохранением. В этом случае мы не можем передать «Ссылку», так как объекта в базе еще нет. Рассмотрим, как использовать механизм ЗначенияЗаполнения.

Для этого в методе ОткрытьФорму передается структура параметров. Платформа автоматически передаст эти данные в обработчик ОбработкаЗаполнения в модуле объекта нового документа.


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

Проанализируем преимущества этого подхода:

Решение 3: Использование обработчика оповещений

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

  1. На сервере после записи документа вызываем: ОповеститьОбИзменении(ТипЗнч(НовыйДокумент.Ссылка)).
  2. В форме, из которой инициировалось создание, прописываем клиентский обработчик ОбработкаОповещения.
  3. В этом обработчике анализируем данные и при необходимости открываем форму.

Анализируем особенности работы в интерфейсе «Такси»

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

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

Типичные ошибки при реализации

Выясним, на чем чаще всего спотыкаются разработчики:

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

← На главную