Как добавить реквизит в форму подписи документа и сохранить его в базе данных 1С

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия
← На главную

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

Разберем причину: Реквизит формы против Реквизита объекта

Проанализируем ситуацию: если вы просто создаете реквизит непосредственно в редакторе формы (на вкладке "Реквизиты" формы), он существует только до тех пор, пока эта форма открыта. Как только пользователь нажимает "ОК" или закрывает окно, данные исчезают из оперативной памяти. Внешняя обработка, которая обращается к ДокументСсылка или ДокументОбъект, ищет поле в базе данных, а не в интерфейсе пользователя. Именно поэтому возникает ошибка "Поле объекта не обнаружено".

Важное правило: Чтобы данные были доступны внешней обработке или отчету, они должны быть физически записаны в таблицу базы данных. Это значит, что реквизит должен быть добавлен в дерево метаданных самого объекта (документа) в расширении.

Шаг 1. Добавление реквизита в метаданные через расширение

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

  1. Добавим документ РеализацияТоваровУслуг в ваше расширение.
  2. В дереве метаданных расширения перейдем к узлу Реквизиты документа и создадим новый реквизит, например, Инициатор1 с типом СправочникСсылка.ФизическиеЛица.
  3. Если необходимо, чтобы данные были привязаны к конкретным строкам товаров, создадим аналогичный реквизит в табличных частях Товары и Услуги.
  4. Обновим конфигурацию базы данных. Теперь поле Инициатор1 физически существует в таблице документа.

Шаг 2. Вывод реквизита на форму подписей

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

Добавим саму форму в расширение. В редакторе формы на закладке "Реквизиты" найдем основной реквизит (обычно это Объект, выделенный жирным шрифтом). Если мы правильно добавили реквизит в документ на предыдущем шаге, он должен отобразиться в составе Объекта. Перетащим его мышкой на визуальную панель формы.

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

Шаг 3. Программная передача и сохранение данных

Выясним, как данные из вспомогательной формы попадают в основной документ. В типовой БП КОРП при нажатии "ОК" на форме подписей срабатывает механизм оповещения. Проанализируем пример кода, который необходимо разместить в модуле формы подписей для возврата значения:


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

В основной форме документа (ФормаДокумента) необходимо перехватить этот результат в процедуре ОбработкаВыбора и записать его в реквизит объекта:


&НаКлиенте
Процедура дор_ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") Тогда
        Если ВыбранноеЗначение.Свойство("Инициатор1") Тогда
            Объект.Инициатор1 = ВыбранноеЗначение.Инициатор1;
            ЭтаФорма.Модифицированность = Истина;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Шаг 4. Обращение к полю из внешней обработки

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


// В контексте внешней обработки, где Реализация - это Ссылка на документ
НовСтр.Инициатор1 = Реализация.Инициатор1; 

// Или через запрос (более предпочтительно для производительности)
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Реализация.Инициатор1 КАК Инициатор
    |ИЗ
    |   Документ.РеализацияТоваровУслуг КАК Реализация
    |ГДЕ
    |   Реализация.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ДокСсылка);

Устранение ошибки версионирования

Проанализируем ситуацию, упомянутую в обсуждении, когда возникает ошибка Метод объекта не обнаружен (ПриОпределенииНастроекВерсионированияОбъектов). Это происходит из-за того, что подсистема "Версионирование объектов" из состава БСП не ожидает появления новых реквизитов в расширении без соответствующей настройки.

Рекомендация: Вместо комментирования типового кода в общих модулях, проверьте настройки версионирования для вашего документа. Если версионирование для РеализацияТоваровУслуг включено, попробуйте временно отключить его в пользовательском режиме (Администрирование -> Общие настройки -> История изменений), чтобы убедиться, что проблема именно в этом. Для корректного решения следует добавить процедуру-заглушку в модуль менеджера документа в расширении, если БСП обращается к ней.

Резюме для реализации

Подведем итог: для успешного вывода значения в Excel из внешней обработки необходимо соблюсти цепочку: Реквизит метаданных (БД) -> Основной реквизит формы -> Поле ввода -> Механизм сохранения (Записать). Если хотя бы одно звено пропущено, данные либо не будут сохраняться, либо не будут видны программному коду вне формы.

← На главную