Часто в процессе разработки на управляемых формах возникает задача: пользователь пытается создать новый документ на основании существующего (например, «Карточка ремонта» на основании «Карточки приема»), но в системе такой документ уже был создан ранее. В этом случае вместо открытия пустой формы создания нового объекта нам необходимо найти уже существующий документ и открыть его.
Рассмотрим, почему реализация этой задачи в процедуре ОбработкаЗаполнения является ошибкой и как правильно настроить логику открытия формы.
ОбработкаЗаполнения не подходит для открытия формВажно помнить, что ОбработкаЗаполнения в модуле объекта выполняется на сервере. Эта процедура предназначена исключительно для подготовки данных нового объекта, а не для управления интерфейсом пользователя. Серверная часть не имеет доступа к клиентским методам открытия окон, поэтому попытки вызвать методы ОткрытьФорму или ОткрытьЗначение из ОбработкиЗаполнения приведут к ошибкам или будут просто проигнорированы.
ПриСозданииНаСервереДля решения задачи мы будем использовать событие ПриСозданииНаСервере модуля формы того документа, который мы пытаемся создать. Именно здесь у нас есть доступ к параметрам открытия, включая параметр Основание.
Рассмотрим пошаговый алгоритм действий:
ПриСозданииНаСервере.Ложь и инициировать открытие найденного объекта.Посмотрим на пример реализации такого кода в модуле формы документа:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем основание из параметров формы
Основание = Параметры.ЗначениеЗаполнения;
// Проверяем, что основание является ссылкой на нужный тип документа
Если ТипЗнч(Основание) = Тип("ДокументСсылка.КарточкаПриема") Тогда
// Ищем существующий документ КарточкаРемонта по реквизиту ДокументОснование
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КарточкаРемонта.Ссылка КАК Ссылка
|ИЗ
| Документ.КарточкаРемонта КАК КарточкаРемонта
|ГДЕ
| КарточкаРемонта.ДокументОснование = &Основание";
Запрос.УстановитьПараметр("Основание", Основание);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Если документ найден, открываем его и отменяем создание текущей формы
ПоказатьЗначение(, Выборка.Ссылка);
Отказ = Истина; // Отказываемся от создания текущей формы
Возврат;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Давайте проанализируем, что именно происходит в приведенном коде:
Параметры.ЗначениеЗаполнения. Это стандартный способ передачи данных при вводе на основании, который платформа заполняет автоматически.ПоказатьЗначение. Это универсальный метод, который откроет форму найденного документа в зависимости от настроек платформы.Отказ = Истина является критически важным шагом. Без этой команды система завершит создание текущего документа, несмотря на то, что мы уже открыли другой.Закрыть()Иногда логика поиска может быть реализована на клиенте в процедуре ПередОткрытием. Хотя серверный вариант предпочтительнее, так как он работает быстрее и не отрисовывает форму «впустую», клиентский подход также возможен. В этом случае вы проверяете наличие документа, открываете его, а текущую форму закрываете командой ЭтаФорма.Закрыть().
Однако помните: ЭтаФорма.Модифицированность = Ложь обязательна к исполнению перед закрытием, чтобы система не задавала пользователю лишних вопросов о сохранении изменений, которые он не успел внести.
Используя предложенные методы, вы добьетесь корректного поведения интерфейса, избежите дублирования документов в базе данных и обеспечите удобство работы конечных пользователей.