Как записать нетиповое значение в регистр сведений в 1С:ERP при проведении документа

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

При работе с крупными конфигурациями, такими как 1С:ERP Управление предприятием 2 или 1С:Комплексная автоматизация 2, разработчики часто сталкиваются с необходимостью изменить стандартную логику проведения документов. Типичная задача: добавить в табличную часть документа новое поле и сделать так, чтобы при проведении значение из этого поля попадало в ресурс регистра сведений вместо (или вместе) с типовым значением.

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

Особенности архитектуры проведения в 1С:ERP

Прежде чем приступать к написанию кода, давайте разберем, чем проведение в ERP отличается от проведения в старых конфигурациях (например, УПП 1.3). В современных решениях на базе Библиотеки Стандартных Подсистем (БСП) используется так называемая "запросная" модель проведения. Это означает, что движения формируются не путем перебора строк табличной части в цикле, а с помощью выполнения пакета запросов.

Основные этапы этой модели выглядят так:

  1. В модуле объекта документа вызывается процедура ОбработкаПроведения.
  2. Внутри неё происходит обращение к общему модулю (например, ПроведениеСерверУТ), который инициирует сбор данных.
  3. Система обращается к Модулю менеджера документа, где описаны тексты запросов для каждого регистра.
  4. Результаты этих запросов автоматически записываются в соответствующие наборы записей регистров.

Понимание этой схемы крайне важно: если вы будете пытаться менять движения "по старинке" в модуле объекта, вы можете столкнуться с тем, что ваши изменения будут перезаписаны типовым механизмом или приведут к ошибкам производительности.

Способ 1. Модификация запроса в модуле менеджера (Рекомендуемый)

Как мы выяснили, основной код формирования данных для движений находится в модуле менеджера документа. В случае с документом РегистрацияЗемельныхУчастков нас интересует одноименная процедура. Давайте рассмотрим пример кода, который подготавливает данные для записи в регистр.

Проанализируем типовой запрос, который извлекает данные из табличной части ОС документа:


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

Чтобы реализовать выбор между типовым полем и вашим новым полем (например, МояКадастроваяСтоимость), нам нужно использовать оператор ВЫБОР прямо в тексте запроса. Предположим, условием является заполненность нового поля.

Рассмотрим, как изменить фрагмент запроса:


|    ВЫБОР 
|        КОГДА ТабличнаяЧастьДокумента.МояКадастроваяСтоимость <> 0 
|        ТОГДА ТабличнаяЧастьДокумента.МояКадастроваяСтоимость 
|        ИНАЧЕ ТабличнаяЧастьДокумента.КадастроваяСтоимость 
|    КОНЕЦ КАК КадастроваяСтоимость,

Важный нюанс: поскольку ERP находится на поддержке, мы не должны менять типовой код напрямую. Для внесения изменений используйте Расширение конфигурации. В расширении используйте аннотацию &ИзменениеИКонтроль для процедуры модуля менеджера. Это позволит вам точечно заменить текст запроса, сохранив остальную логику нетронутой.

Способ 2. Подмена данных перед записью в документе

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

В модуле объекта документа в событии ПередЗаписью (или в ОбработкаПроведения до начала формирования движений) мы можем программно заполнить типовое поле значением из нашего нового поля. Тогда типовой запрос в модуле менеджера просто "подхватит" уже готовое значение.

Пример реализации в модуле объекта:


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

Плюсы этого метода: простота реализации и отсутствие необходимости править сложные запросы в модуле менеджера.

Минусы: данные в табличной части документа будут изменены физически. Если пользователю важно видеть в поле КадастроваяСтоимость одно значение, а в регистр передавать другое — этот метод не подойдет, так как он затирает исходные данные в документе.

Способ 3. Подписка на событие регистра

Иногда возникает вопрос: можно ли использовать подписку на событие ПередЗаписью самого регистра сведений? Технически — да, но для задач проведения документов в ERP это наименее предпочтительный вариант.

Разберем причины, почему так делать не стоит:

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

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

Резюме и рекомендации

Проанализировав ситуацию, мы пришли к выводу, что для 1С:ERP наиболее правильным и "чистым" решением является модификация текста запроса в модуле менеджера через расширение.

Давайте закрепим последовательность действий:

  1. Создаем расширение конфигурации.
  2. Добавляем в расширение документ РегистрацияЗемельныхУчастков и его модуль менеджера.
  3. Находим процедуру, отвечающую за формирование текста запроса для вашего регистра (обычно она называется так же, как регистр).
  4. Используем &ИзменениеИКонтроль, чтобы внедрить логику ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ в секцию ВЫБРАТЬ запроса.
  5. Обязательно проверяем, что новое поле табличной части также добавлено в расширение, иначе запрос к нему не отработает.

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

← На главную