Как программно назначить реквизит формы основным в 1С?

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

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

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

Архитектурные ограничения платформы 1С

Свойство Основной реквизит играет ключевую роль в поведении управляемой формы. Однако сделать его динамическим не удастся по следующим причинам:

  1. Жесткая фиксация в метаданных: Признак основного реквизита задается исключительно на этапе разработки в конфигураторе. Конструктор программного реквизита РеквизитФормы(Имя, ТипЗначения, Путь, Заголовок, СохраняемыеДанные) не содержит параметра, отвечающего за назначение реквизита основным. У объекта УправляемаяФорма также отсутствуют свойства или методы для программной смены основного реквизита.
  2. Ограничения метода ИзменитьРеквизиты(): Платформа позволяет добавлять новые реквизиты и удалять те из них, которые ранее были созданы программно. Изменить, заменить или удалить реквизиты, объявленные в конфигураторе (включая основной реквизит), программно невозможно — попытка выполнения такой операции вызовет исключение.
  3. Инициализация расширения формы: Тип основного реквизита жестко определяет, какое именно расширение формы будет подключено при ее инициализации (например, Расширение управляемой формы для документа или Расширение управляемой формы для справочника). Это расширение предоставляет события (ПередЗаписью, ОбработкаПроведения), системные свойства и стандартные команды. Платформа инициализирует расширение один раз в момент создания формы на сервере, и динамическая подмена расширения для уже созданного экземпляра формы не поддерживается архитектурой платформы.
  4. Отсутствие автогенерации элементов в режиме предприятия: Автоматическое создание полей ввода, таблиц и командных панелей работает исключительно в конфигураторе при перетаскивании реквизитов в дерево элементов. В режиме 1С:Предприятие платформа никогда автоматически не создает визуальные элементы управления при добавлении или изменении структуры данных формы.

Таким образом, идея назначить реквизит основным "на лету" и получить автоматически готовую форму объекта неосуществима штатным механизмом. Проанализируем два рабочих подхода к решению исходной бизнес-задачи.

Решение 1. Динамическое открытие штатной формы объекта (рекомендуемый подход)

Если цель состоит в том, чтобы предоставить пользователю возможность просматривать и редактировать выбранный объект со всеми его стандартными кнопками (проведение, печать, отчеты) и проверками, наиболее правильным и надежным решением является открытие собственной формы этого объекта.

Рассмотрим, как по выбранной ссылке определить имя формы и открыть ее программно:


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

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

Решение 2. Создание универсального динамического редактора

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

Разберем по шагам, как устроен этот процесс:

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

Посмотрим на пример базовой серверной процедуры записи данных в таком динамическом редакторе:


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

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

← На главную