Как открыть существующий элемент справочника в своей форме без изменения конфигурации в обычном приложении

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

При сопровождении типовых конфигураций на платформе 1С:Предприятие, работающих в режиме обычного приложения (ОФ), часто возникает задача доработать форму элемента справочника без снятия конфигурации с поддержки. Распространенный сценарий — создание внешней обработки со списком элементов, из которого требуется открывать модифицированную форму. Однако разработчики нередко сталкиваются с ситуацией, когда вместо выбранного элемента открывается пустая форма нового элемента или возникает ошибка вида «Элемент не выбран!» при попытке инициализации данных.

Разберем причины такого поведения платформы и пошагово рассмотрим правильный алгоритм решения этой задачи.

В чем заключается ошибка при передаче объекта в форму

Проанализируем типовой фрагмент кода, в котором возникает ошибка:


Процедура ТабличноеПолеПровайдерыПередНачаломИзменения(Элемент, Отказ)
    Отказ = Истина;
    Ссылка = ЭлементыФормы.ТабличноеПолеПровайдеры.ТекущиеДанные.Ссылка;
    Параметры = Новый Структура("Ключ", Ссылка);
    Форма = ПолучитьФорму("ФормаЭлемента", Параметры, ЭтаФорма);
    Форма.ЭтотОбъект = Ссылка.ПолучитьОбъект();
    Форма.Открыть();
КонецПроцедуры

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

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

Определяем основной реквизит формы элемента

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

Посмотрим, как устроен контекст скопированной формы:

  1. Откроем внешнюю обработку в конфигураторе и перейдем в форму элемента.
  2. В окне диалога формы откроем закладку «Реквизиты».
  3. Найдем реквизит, выделенный полужирным шрифтом. Это и есть основной реквизит формы, определяющий тип данных, с которыми форма взаимодействует напрямую.

Для формы элемента справочника этот реквизит по умолчанию имеет имя СправочникОбъект и тип СправочникОбъект.<ИмяСправочника>. Именно ему необходимо присваивать считанный из базы объект, а не системному свойству ЭтотОбъект.

Правильная реализация открытия формы

Разберем по шагам корректный алгоритм открытия формы существующего элемента во внешней обработке:


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

Рассмотрим подробнее важные детали этой реализации:

  1. Ключ уникальности: Передавая СсылкаНаЭлемент третьим параметром в метод ПолучитьФорму, мы предотвращаем дублирование окон. Если пользователь повторно нажмет на ту же строку, платформа активизирует уже открытое окно этого элемента вместо создания дубликата.
  2. Метод Прочитать(): Принудительный вызов метода Форма.Прочитать() гарантирует, что реквизиты формы и связанные с ними элементы управления на экране корректно заполнятся значениями из назначенного объекта базы данных.

Синхронизация данных со списком после записи

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

В модуле открываемой формы элемента в обработчике события ПослеЗаписи добавим системное оповещение:


Процедура ПослеЗаписи(Отказ)
    ОповеститьОбИзменении(СправочникОбъект.Ссылка);
КонецПроцедуры

А в основной форме списка во внешней обработке добавим процедуру ОбработкаОповещения, где обновим строки табличного поля:


Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    ЭлементыФормы.ТабличноеПолеПровайдеры.ОбновитьСтроки();
КонецПроцедуры

Ограничения обычного приложения при подмене форм

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

Единственный рабочий способ работы с кастомной формой без изменения типового кода — перехват действий пользователя (события ПередНачаломИзменения, Выбор) в специально разработанных внешних обработках со списками справочников.

← На главную