Как найти, где формируются движения по регистру накопления при проведении документа в 1С

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

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

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

Причина 1. Специфика архитектуры проведения и записи наборов записей

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

Рассмотрим пример кода, который часто применяется для записи движений по партиям:


НаборЗаписей = РегистрыНакопления.ПартииТоваровБух.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);

// Заполнение набора записей из подготовленной таблицы значений
Для Каждого СтрокаТаблицы Из ТаблицаПартий Цикл
    НоваяСтрока = НаборЗаписей.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицы);
КонецЦикла;

НаборЗаписей.Записать();

Поскольку в этом случае запись происходит напрямую через объект НаборЗаписей, коллекция Движения.ПартииТоваровБух внутри самого документа остается пустой на протяжении всего процесса проведения. Именно поэтому интерактивный анализ коллекции в табло отладчика не приносит результатов.

Решение 1. Точка останова в модуле набора записей регистра

Самый простой и надежный способ поймать момент записи в регистр — использовать обработчик событий самого регистра накопления. Для этого выполним следующие действия по шагам:

  1. Откроем конфигуратор вашей базы данных.
  2. В дереве метаданных найдем нужный регистр накопления (в нашем примере это ПартииТоваровБух).
  3. Нажмем по нему правой кнопкой мыши и выберем пункт Открыть модуль набора записей.
  4. Создадим предопределенную процедуру ПередЗаписью или ПриЗаписи.
  5. Поставим внутри этой процедуры точку останова.

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


Процедура ПередЗаписью(Отказ, Замещение)
    
    // Ставим точку останова на строчке ниже
    Если ЭтотОбъект.Количество() > 0 Тогда
        ИмяРегистратора = ЭтотОбъект.Отбор.Регистратор.Значение;
    КонецЕсли;
    
КонецПроцедуры

Когда документ начнет проводить транзакцию и дело дойдет до записи движений в базу данных, система автоматически передаст управление в этот обработчик. В этот момент мы сможем открыть окно Стек вызовов (Call Stack) в отладчике и увидеть всю цепочку процедур и функций, приведшую к записи.

Важное примечание: Если точка останова в модуле набора записей регистра не срабатывает, выясним две главные причины:

  1. Не включена серверная отладка. Поскольку проведение документов и запись движений происходят на стороне сервера приложений "1С:Предприятие", клиентский отладчик просто не увидит выполнение этого кода. Необходимо перезапустить службу сервера 1С с ключом -debug.
  2. Фоновые задания. Проведение по партиям или расчет себестоимости могут выполняться в фоновом режиме. Чтобы поймать их, в меню конфигуратора перейдем в Отладка -> Подключение и настроим автоматическое подключение фоновых заданий.

Решение 2. Использование инструмента "Замер производительности"

Если код отрабатывает слишком быстро или стандартная отладка по шагам затруднена из-за огромного количества итераций, отличной альтернативой является Замер производительности.

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

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

Перед нами откроется окно с полным списком всех строк кода, которые выполнялись в системе. Нам остается лишь выполнить поиск (Ctrl + F) по ключевому слову ПартииТоваровБух или НаборЗаписей. Замер покажет точные строки в общих модулях и подписках на события, которые принимали участие в формировании движений.

Решение 3. Проверка настроек учетной политики и РАУЗ в УПП

Если мы отлаживаем именно конфигурацию УПП, то движения могут отсутствовать по чисто архитектурным причинам, заложенным в логику программы. Рассмотрим две основные настройки:

  1. Режим РАУЗ (Режим аналитического учета затрат). Если в настройках параметров учета вашей УПП включен РАУЗ, то классический партионный учет в системе отключен. В этом режиме движения по регистру ПартииТоваровБух физически не должны формироваться — все затраты и партии отражаются в регистрах учета затрат (например, УчетЗатратРег).
  2. Настройка "Списывать партии при проведении документов". Если эта опция выключена в учетной политике, то при проведении документов движения по партиям вообще не создаются в режиме реального времени. Они рассчитываются и записываются позже специальной регламентной обработкой Проведение по партиям. В этом случае отлаживать нужно именно проведение этой обработки, а не сам документ.

Решение 4. Анализ специализированных общих модулей УПП

В типовой архитектуре УПП формирование партионного учета вынесено за пределы документов. Почти все документы используют единые механизмы проведения.

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

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

Решение 5. Динамический поиск по метаданным

В переписанных базах данных разработчики нередко используют универсальные механизмы проведения, где имя регистра получается динамически. Например:


Для Каждого Движение Из ЭтотОбъект.Движения Цикл
    ИмяРегистра = Движение.Метаданные().Имя;
    Если Найти(ИмяРегистра, "Партии") > 0 Тогда
        // Здесь выполняется логика проведения
    КонецЕсли;
КонецЦикла;

При таком подходе глобальный поиск по строке "ПартииТоваровБух" не даст результатов. Чтобы перехватить такое динамическое обращение, мы можем зайти в общий модуль проведения документов (например, ДвиженияДокументов) и установить точку останова с условием.

Для этого кликнем правой кнопкой мыши на точку останова, выберем пункт Свойства точки останова и в поле Условие напишем:

Движение.Метаданные().Имя = "ПартииТоваровБух"

Система остановит выполнение кода ровно в тот момент, когда универсальный алгоритм дойдет до обработки нашего целевого регистра.

← На главную