В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда необходимо открыть форму нового или только что созданного документа непосредственно в момент выполнения кода. Однако попытка вызвать методы ОткрытьФорму или ОткрытьЗначение внутри модуля документа или любого другого серверного модуля приводит к ошибке «Процедура или функция не определена». Проанализируем, почему это происходит и как правильно организовать логику открытия форм в клиент-серверной архитектуре.
Разберем по шагам, что происходит в системе. В 1С существует жесткое разделение на клиентский и серверный контексты. Серверный контекст (модуль объекта, модуль менеджера, серверные общие модули) выполняется в процессе rphost на стороне сервера базы данных. У этого процесса физически нет доступа к графическому интерфейсу пользователя, монитору или окнам.
Рассмотрим основные ограничения серверного контекста:
Поэтому фраза «в модуле документа — никак» (сообщение 3) является технически верной. Для решения задачи нам необходимо вернуть управление на клиентскую сторону.
Если ваша задача — программно создать несколько документов в базе, записать их и затем показать пользователю, проанализируем следующую схему работы. Мы должны инициировать процесс с клиента, выполнить создание на сервере, вернуть массив ссылок и открыть их на клиенте.
Посмотрим на пример реализации в модуле формы или в модуле команды:
&НаКлиенте
Процедура СоздатьИОткрытьДокументы()
// 1. Вызываем серверную функцию для создания объектов
МассивСсылок = СоздатьДокументыНаСервере();
// 2. Возвращаемся на клиент и в цикле открываем каждую форму
Для Каждого СсылкаИзСписка Из МассивСсылок Цикл
// Используем стандартный метод открытия значения
ПоказатьЗначение(, СсылкаИзСписка);
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция СоздатьДокументыНаСервере()
МассивРезультат = Новый Массив;
Для Итератор = 1 По 3 Цикл
НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
// Заполнение реквизитов...
НовыйДок.Записать();
МассивРезультат.Добавить(НовыйДок.Ссылка);
КонецЦикла;
Возврат МассивРезультат;
КонецФункции
Важный момент: Обратите внимание на использование метода ПоказатьЗначение вместо устаревшего ОткрытьЗначение. В современных конфигурациях, работающих в режиме без модальности, асинхронные методы являются предпочтительными.
Иногда пользователю не нужно сразу записывать документы в базу. Например, если он должен проверить заполненные данные перед сохранением. В этом случае мы не можем передать «Ссылку», так как объекта в базе еще нет. Рассмотрим, как использовать механизм ЗначенияЗаполнения.
Для этого в методе ОткрытьФорму передается структура параметров. Платформа автоматически передаст эти данные в обработчик ОбработкаЗаполнения в модуле объекта нового документа.
&НаКлиенте
Процедура ОткрытьНовыйДокументНаОсновании()
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("Основание", СсылкаНаОбъектОснование);
ПараметрыЗаполнения.Вставить("Склад", ВыбранныйСклад);
ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ПараметрыЗаполнения);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
Проанализируем преимущества этого подхода:
ОбработкаЗаполнения), что соответствует стандартам разработки 1С.Если документы создаются в фоновом задании или сложной цепочке вызовов, где прямой возврат массива ссылок неудобен, можно использовать механизм оповещений. Рассмотрим ситуацию: сервер закончил работу и «сообщает» об этом всем открытым формам.
ОповеститьОбИзменении(ТипЗнч(НовыйДокумент.Ссылка)).ОбработкаОповещения.При открытии нескольких форм подряд (как предлагалось в решении 1), важно учитывать пользовательский опыт. В интерфейсе «Такси» каждое открытие ОткрытьФорму создает новую вкладку. Если ваш цикл создаст 20 документов, у пользователя откроется 20 вкладок, что может привести к замедлению работы клиентского приложения.
В таких случаях рекомендуем рассмотреть альтернативный вариант: вместо открытия множества окон вывести пользователю список ссылок (например, в виде таблицы в текущей форме или через СписокЗначений), чтобы он сам выбрал, какой документ ему нужно просмотреть в данный момент.
Выясним, на чем чаще всего спотыкаются разработчики:
ПолучитьФорму() на сервере: Этот метод доступен только в толстом клиенте. В управляемом приложении работа с формой как с объектом на сервере запрещена.Возврат функции) нельзя передавать сам объект (ДокументОбъект). Нужно передавать только Ссылка, Структура, Массив или другие простые типы.&НаКлиенте: Если процедура открытия формы не помечена этой директивой, она по умолчанию может пытаться выполниться на сервере (зависит от контекста модуля), что приведет к ошибке.Подводя итог, запомним главное правило архитектуры 1С: Сервер готовит данные и выполняет расчеты, Клиент управляет отображением и взаимодействует с пользователем. Соблюдение этого разделения гарантирует стабильную работу вашей конфигурации в любых режимах — от файлового до крупного кластера серверов.