Отладка модуля документа: как найти, где формируются движения по регистру в УПП

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет Промышленность, строительство и АПК
← На главную

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

Проблема: Почему точки останова не срабатывают?

Прежде чем приступать к активному поиску кода, проанализируем ситуацию: вы ставите точку останова в модуле набора записей регистра, но отладчик «пролетает» мимо. В 90% случаев это происходит из-за того, что отладка на сервере не включена. В УПП проведение документа почти всегда выполняется в серверном контексте. Чтобы отладчик начал реагировать на точки останова в серверных модулях и модулях набора записей, необходимо запустить службу агента сервера 1С с параметром /debug. Без этого параметра отладка кода, исполняемого на сервере, невозможна.

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

Рассмотрим пример того, как проверить содержимое регистра в табло отладчика:

Движения.ПартииТоваровБух.Прочитать(); Движения.ПартииТоваровБух.Выгрузить()

Метод 1: Анализ через Модуль набора записей и Стек вызовов

Это самый надежный «профессиональный» способ. Мы пойдем от обратного — не от документа к записи, а от момента записи к коду, который ее вызвал. Разберем по шагам:

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

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

Метод 2: Замер производительности и текстовый поиск

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

Процесс выглядит так:

  1. Откроем документ, который нужно провести.
  2. В конфигураторе включим «Замер производительности» (Меню Отладка — Замер производительности).
  3. В режиме «Предприятие» нажмем «Провести».
  4. После завершения операции вернемся в конфигуратор и выключим замер.

Перед нами появится таблица со списком всех процедур и функций. Чтобы не «просеивать» тысячи строк вручную, нажмем Ctrl + F прямо в окне замера и введем имя регистра (например, ПартииТоваровБух). Если прямого обращения нет, попробуем поискать метод Записать() или ключевое слово Движения. Обратите внимание на колонку «Количество строк» и «Чистое время» — наиболее тяжеловесные процедуры в УПП обычно связаны именно с расчетом партий.

Метод 3: Особенности архитектуры УПП — Динамические имена

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


ИмяРегистра = "ПартииТоваров" + ?(ВестиБухУчет, "Бух", "");
НаборЗаписей = Движения[ИмяРегистра];
// Далее идет заполнение НаборЗаписей...

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

Метод 4: Скрытые подписки на события

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

Чтобы проверить это:

  1. В дереве метаданных перейдем в раздел Общие -> Подписки на события.
  2. Отсортируем их по «Источнику» или «Событию» (ищем ОбработкаПроведения).
  3. Проверим те подписки, где в качестве источника указан ДокументОбъект или массив типов, включающий ваш документ.

Метод 5: Проверка режима РАУЗ

Важный нюанс для пользователей УПП: если в настройках параметров учета включен режим РАУЗ (Расширенная аналитика учета затрат), то классический партионный учет (регистры «Партии товаров...») вообще не используется! Все движения по движению МПЗ и затрат пишутся в единый регистр УчетЗатратРегламентированный.

Выясним это, проверив константу ИспользоватьРасширеннуюАналитикуУчетаЗатрат. Если она установлена в «Истина», искать код, заполняющий регистр ПартииТоваровБух, бессмысленно — он просто не вызывается системой, так как учет ведется по другой методологии.

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

Для эффективного поиска места формирования движений мы рекомендуем придерживаться следующего алгоритма:

  1. Убедиться, что серверная отладка включена (ключ /debug).
  2. Поставить точку останова в ПередЗаписью модуля набора записей регистра и изучить стек вызовов.
  3. Если это не помогло, выполнить замер производительности и провести поиск по названию регистра или методам Записать / ВыполнитьСписание.
  4. Проверить общие модули серии УправлениеЗапасами... на предмет динамического обращения к коллекции Движения через квадратные скобки.
  5. В самой ОбработкеПроведения проверить, не устанавливается ли признак Движения.ПартииТоваровБух.Записывать = Истина в самом начале, что может означать отложенное заполнение регистра в конце процедуры.

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

← На главную