Как записать значение новой колонки из документа «Реализация товаров и услуг» в регистр «Продажи» в УТ 10.3

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

При адаптации типовой конфигурации «Управление торговлей 10.3» под нужды бизнеса часто возникает задача: добавить в табличную часть документа (например, РеализацияТоваровУслуг) новое поле и сделать так, чтобы его значение записывалось в регистр накопления при проведении. На первый взгляд задача кажется простой, но новички часто сталкиваются с тем, что данные либо не записываются, либо создают лишние строки в регистре, либо «затирают» друг друга.

В этой статье мы подробно разберем, почему стандартные подходы через НаборЗаписей могут не работать, и как правильно внедрить свой код в типовой механизм проведения УТ 10.3.

Анализ проблемы: почему не работает простой перебор строк

Рассмотрим ситуацию: вы добавили колонку Бонус_Добавленно в табличную часть Товары и аналогичный реквизит в регистр накопления Продажи. Попытка записать данные через прямое обращение к набору записей в подписке на событие или в конце процедуры ОбработкаПроведения часто выглядит так:


Для каждого Запись из НаборЗаписей Цикл
    Запись.Бонус_Добавленно = Объект.Товары[НомерСтроки].Бонус_Добавленно;
КонецЦикла;

Выясним причину, почему это плохой подход:

  1. Отсутствие соответствия 1:1. В типовых решениях УТ 10.3 при проведении строки табличной части документа часто сворачиваются (группируются). Если в документе две строки с одним и тем же товаром по одинаковой цене, в регистре Продажи может появиться всего одна строка с суммарным количеством. Прямой индекс [НомерСтроки] приведет к ошибке или записи неверных данных.
  2. Лишние движения. Если вы просто добавляете новую запись в Движения.Продажи (как в Коде №1 из вопроса), система создаст дополнительную строку, не связанную с основной продажей товара. Это исказит отчеты: в одной строке будет количество и выручка, а в другой — только ваш бонус.
  3. Производительность. Чтение и перезапись набора записей после того, как документ уже сформировал движения — это двойная работа для сервера базы данных.

Решение №1: Использование типового механизма формирования движений (Рекомендуемое)

В конфигурации УТ 10.3 движения формируются не «в лоб», а через подготовку специальных временных таблиц. Проанализируем путь данных. Основная логика сосредоточена в процедуре ДвиженияПоРегистрамУпр. Чтобы ваша колонка попала в регистр автоматически, нужно изменить место формирования исходной таблицы.

Рассмотрим по шагам, как это сделать:

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

Шаг 2. Модификация запроса. Нам нужно добавить нашу колонку Бонус_Добавленно в текст запроса. Найдите место, где описываются поля выбора:


|	ТЧТовары.Номенклатура КАК Номенклатура,
|	ТЧТовары.Количество КАК Количество,
|	ТЧТовары.Бонус_Добавленно КАК Бонус_Добавленно, // Добавляем наше поле

Шаг 3. Группировка данных. Поскольку движения могут сворачиваться, определите, как должен вести себя бонус. Если это числовой ресурс (сумма бонуса), его нужно добавить в секцию СУММА:

|СУММА(Бонус_Добавленно) КАК Бонус_Добавленно

Если же бонус — это признак (например, категория), его нужно добавить в СГРУППИРОВАТЬ ПО.

Шаг 4. Автоматическая запись. В УТ 10.3 используется механизм, при котором, если имя колонки в подготовленной таблице совпадает с именем ресурса/реквизита в регистре, система сама переносит данные. Вам даже не придется писать Запись.Бонус = Строка.Бонус.

Решение №2: Исправление кода в подписке на событие

Если вы все же решили использовать подписку на событие ОбработкаПроведения (чтобы не менять типовой модуль документа), разберем, как сделать это правильно, избегая «г@внокода».

Проблема автора в Сообщении №11 заключалась в двойном цикле, который просто затирал значения. Проанализируем правильный алгоритм сопоставления:

  1. Получаем движения документа через Источник.Движения.Продажи.
  2. Устанавливаем Записывать = Истина.
  3. Поскольку мы не можем гарантировать порядок строк, нам нужно сопоставить строку ТЧ документа и строку регистра по ключевым полям (Номенклатура, Склад, Характеристика).

Пример правильной логики в подписке:


Процедура ОбработкаПроведения_Подписка(Источник, Отказ, РежимПроведения) Экспорт
    // Движения уже сформированы стандартным кодом документа
    ТаблицаТоваров = Источник.Товары.Выгрузить();
    
    // Индексируем таблицу для быстрого поиска
    ТаблицаТоваров.Индексы.Добавить("Номенклатура");
    
    Для Каждого Движение Из Источник.Движения.Продажи Цикл
        // Ищем соответствующую строку в документе
        // Внимание: если строки сворачивались, логика поиска должна быть сложнее (через запрос)
        ПараметрыОтбора = Новый Структура("Номенклатура", Движение.Номенклатура);
        НайденныеСтроки = ТаблицаТоваров.НайтиСтроки(ПараметрыОтбора);
        
        Если НайденныеСтроки.Количество() > 0 Тогда
            // Если строк несколько (была группировка), решаем, как распределить бонус
            // В простом случае берем из первой найденной строки
            Движение.Бонус_Добавленно = НайденныеСтроки[0].Бонус_Добавленно;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важные нюансы работы с ресурсами

Рассмотрим вопросы из Сообщения №20: как рассчитывается Стоимость и СтоимостьБезСкидки?

В типовых конфигурациях эти суммы рассчитываются в общих модулях (например, ЗаполнениеУправленческогоУчета). Система учитывает:

Совет: никогда не пытайтесь пересчитать эти суммы вручную в своем коде. Если вам нужно получить уже рассчитанную стоимость для вашего бонуса, используйте данные из таблицы ТаблицаПоТоварам, которая передается в процедуру ДвиженияПоРегистрамУпр. Там все числа уже «чистые» и финальные.

Рекомендации по отладке

Если вы видите, что Запись.Бонус_Добавленно «не принимает значение» (как писал автор в Сообщении №13), проверьте следующие моменты:

Подведем итог: самый правильный и «чистый» путь для 1С v8.3 на обычных формах (УТ 10.3) — это интеграция в запрос функции ПодготовитьТаблицуТоваров. Это обеспечит целостность данных, правильную группировку строк и высокую скорость работы системы.

← На главную