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