Как программно добавить товар в «Отчет о розничных продажах» в 1С:УНФ, чтобы он корректно провелся по регистрам?

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

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

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

Разбор ошибки «Аварийная ошибка» при записи

Рассмотрим ситуацию, когда разработчик пытается добавить строку и записать объект непосредственно в процедуре ОбработкаПроведения. Это классическая ошибка начинающих разработчиков 1С. Когда выполняется процедура проведения, система уже открыла транзакцию базы данных. Вызов метода Записать() внутри этой транзакции для того же самого объекта приводит к рекурсивному вызову или конфликту блокировок. В результате платформа генерирует Runtime Error (Аварийную ошибку) без подробного описания.

Запомним правило: никогда не вызывайте Записать() внутри процедур ПередЗаписью (если РежимЗаписи = Проведение), ПриЗаписи или ОбработкаПроведения для того же объекта. Все изменения в табличных частях должны вноситься до начала записи или в строго определенных местах жизненного цикла объекта.

Почему строки есть в документе, но нет движений в регистрах?

Проанализируем механизм проведения в УНФ версии 1.6 или 3.0. В отличие от старых конфигураций, где движения формировались прямым перебором строк табличной части в модуле объекта, в УНФ используется механизм инициализации данных.

  1. При проведении система вызывает процедуру модуля менеджера ИнициализироватьДанныеДокумента.
  2. Эта процедура выполняет сложные запросы к табличным частям документа (Запасы, Услуги, Оплата) и помещает результат во временные таблицы.
  3. Запросы в модуле менеджера содержат жесткие условия фильтрации. Если добавленная вами строка не соответствует критериям, она просто «отсеивается» и не попадает в выборку для формирования движений.

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

Шаг 1: Использование правильного события в расширении

Для добавления строк лучше всего использовать обработчик ПередЗаписью в расширении модуля объекта. Проанализируем пример кода:


&Перед("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, что это не просто сохранение, а запись с проведением или при определенных условиях
    Если РежимЗаписи = РежимЗаписиДокумента.Запись Или РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        
        // Логика проверки, нужно ли добавлять строку (например, из Регистра Сведений)
        НужноДобавить = Истина; // Ваша проверка
        
        Если НужноДобавить Тогда
            НоваяСтрока = Запасы.Добавить();
            // Заполнение базовых реквизитов
            НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Ваш Товар");
            НоваяСтрока.Количество = 1;
            НоваяСтрока.Цена = 100;
            
            // Критически важные реквизиты для УНФ:
            НоваяСтрока.Коэффициент = 1; 
            НоваяСтрока.ЕдиницаИзмерения = НоваяСтрока.Номенклатура.ЕдиницаИзмерения;
            НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
            НоваяСтрока.Всего = НоваяСтрока.Сумма; // В УНФ часто движения идут по полю Всего
        КонецЕсли;
        
    КонецЕсли;
КонецПроцедуры

Шаг 2: Заполнение обязательных «невидимых» реквизитов

Рассмотрим подробнее, без каких полей алгоритм проведения УНФ «выбросит» вашу строку из расчета:

Шаг 3: Вызов типовых механизмов пересчета

Вместо того чтобы вручную заполнять каждое поле, рекомендуется использовать экспортные процедуры самого документа или общих модулей УНФ. Это гарантирует, что все связанные реквизиты (счета учета, налоги, спецификации) будут заполнены корректно.

Посмотрим на пример правильного заполнения строки с использованием типовых функций:


// Внутри ПередЗаписью
НоваяСтрока = Запасы.Добавить();
НоваяСтрока.Номенклатура = СсылкаНаТовар;

// Структура для пересчета
ПараметрыПересчета = Новый Структура;
ПараметрыПересчета.Вставить("ИмяТабличнойЧасти", "Запасы");
ПараметрыПересчета.Вставить("ИмяРеквизита", "Номенклатура");

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

НоваяСтрока.Количество = 1;
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(НоваяСтрока);

Шаг 4: Отладка через «Замер производительности»

Если вы заполнили все поля, но движений всё равно нет, воспользуемся проверенным способом отладки. Проанализируем ситуацию через «Замер производительности» в конфигураторе:

  1. Включите замер производительности.
  2. Проведите документ.
  3. Остановите замер и найдите процедуру модуля менеджера ПодготовитьТаблицуЗапасы (или аналогичную, название начинается с ПодготовитьТаблицу...).
  4. Найдите внутри текст запроса. Вы увидите огромный текст с использованием временных таблиц.
  5. Посмотрите на секцию ГДЕ этого запроса. Там вы увидите условия вроде: ГДЕ ТаблицаЗапасы.Количество > 0 И ТаблицаЗапасы.Всего > 0.

Именно здесь ваша строка может отсеиваться. Если в запросе проверяется реквизит Склад, а в вашей новой строке он пустой (и не заполняется из шапки автоматически), то строка не попадет в движения по запасам.

Рекомендации по работе с расширением

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

Как этого избежать:

Таким образом, для успешного программного добавления товара в «Отчет о розничных продажах» необходимо:

  1. Использовать обработчик &Перед("ПередЗаписью") в расширении.
  2. Заполнять не только базовые поля, но и Коэффициент, СтавкаНДС, Сумма, Всего.
  3. Обязательно проверять условия фильтрации в модуле менеджера через замер производительности, если движения не появляются.
← На главную