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