В процессе разработки или доработки конфигураций на базе 1С:Предприятие 8.3 (особенно таких сложных, как УТ 11, ERP 2 или КА 2) программисты часто сталкиваются с ситуацией, когда добавленный или существующий регистр сведений (РС) заполняется «магическим» образом. Стандартный глобальный поиск по названию регистра не дает результатов, в модуле документа-регистратора чисто, а подписки на события не указывают на нужный участок кода. Разберем подробно, как найти скрытые механизмы формирования движений, используя различные инструменты отладки и особенности архитектуры современных систем.
Если мы не знаем, какой именно объект или процедура инициирует запись в регистр РС1, логичнее всего «поймать» систему непосредственно в момент записи данных в базу. Самый быстрый способ сделать это — использовать модуль набора записей самого регистра.
Выполним следующие шаги:
РС1.ПередЗаписью.А = 1;) и установим на него точку останова (клавиша F9).Проанализируем ситуацию: теперь при проведении документа система обязательно остановится на этой строке. В этот момент нам необходимо открыть окно Стек вызовов (Call Stack). Это ключевой инструмент, который покажет всю цепочку процедур, приведших к записи. Проследив стек вниз, мы увидим ту самую процедуру в модуле документа или общем модуле, которая вызвала метод Записать() для нашего набора записей.
Когда кода слишком много, и точка останова срабатывает слишком часто (например, при регистрации изменений для обмена данными), на помощь приходит Замер производительности. Этот метод позволяет увидеть абсолютно все процедуры, которые выполнялись в период проведения документа.
Разберем алгоритм действий:
Перед нами появится список всех выполненных строк кода. Нажмем Ctrl + F и введем имя нашего регистра РС1. Замер подсветит строки, где происходит обращение к метаданным регистра или к коллекции Движения. Это позволяет быстро локализовать код, даже если он скрыт глубоко в недрах общих модулей проведения.
В современной практике разработки часто используется механизм расширений. Если доработки делали не вы, велика вероятность, что логика формирования движений вынесена именно туда. Глобальный поиск по основной конфигурации в этом случае не найдет код, находящийся в расширении.
Проанализируем, где именно в расширениях может прятаться код:
ОбработкаПроведения или типовые процедуры формирования таблиц движений.В конфигурациях УТ 11 / ERP реализована сложная архитектура проведения. Часто движения не записываются напрямую через Движения.ИмяРегистра.Добавить(). Вместо этого система собирает данные во временные таблицы.
Посмотрим на пример того, как это обычно выглядит в модуле документа:
Процедура ДобавитьТаблицыДвижений(ТаблицыДвижений)
Таблица = ТаблицыДвижений.Добавить();
Таблица.Имя = Метаданные.РегистрыСведений.РС1.Имя;
Таблица.Использование = Истина;
КонецПроцедуры
В данном случае в модуле документа лишь декларируется, что регистр будет использоваться. Само заполнение происходит в процедуре СформироватьТаблицыДвижений. Ищите в коде именно эти названия. Запись в базу при такой архитектуре выполняется общим модулем (например, ПроведениеСервер), который итерирует коллекцию подготовленных таблиц и программно заполняет наборы записей. Именно поэтому прямой поиск Движения.РС1.Записать() может не давать результатов.
Выясним причину, по которой глобальный поиск может «промахнуться». Иногда разработчики обращаются к регистрам динамически, используя строковые переменные или метаданные. Рассмотрим пример:
ИмяРегистра = "РС1";
Набор = РегистрыСведений[ИмяРегистра].СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Ссылка);
// ... заполнение ...
Набор.Записать();
При таком подходе поиск по ключевому слову РС1 сработает только в одной строке (где задается имя), но если имя формируется конструктором (например, из настроек или перечислений), то поиск не поможет вовсе. В таких случаях следует искать по фразам РегистрыСведений[ или анализировать Метаданные.РегистрыСведений.
Часто данные для движений подготавливаются в одном модуле, а записываются в другом. Передача данных осуществляется через структуру ДополнительныеСвойства объекта документа. Рассмотрим этот механизм подробнее.
Проанализируем ситуацию: в процедуре ОбработкаПроведения вызывается функция, которая помещает таблицу значений с будущими движениями в ЭтотОбъект.ДополнительныеСвойства.ТаблицыДляДвижений. Затем в подписке на событие ПриЗаписи или в общем модуле проведения эти таблицы извлекаются и записываются в соответствующие регистры. Если вы столкнулись с такой логикой, ищите, где в коде заполняется структура ДополнительныеСвойства.
Если стек вызовов слишком запутанный, можно прибегнуть к радикальному методу отладки. В модуле набора записей регистра РС1 в процедуре ПередЗаписью напишите:
ВызватьИсключение "Ловушка для отладки";
При попытке проведения документа система выдаст критическую ошибку. В окне сообщения об ошибке будет кнопка «Подробно», а затем «Конфигуратор». Нажав на неё, вы попадете точно в ту строку кода, которая инициировала запись, и сможете увидеть текущее состояние переменных и контекст вызова.
Подводя итог, можно сказать, что в современных конфигурациях 1С логика движений редко лежит «на поверхности». Использование Замера производительности в сочетании с анализом расширений и стека вызовов позволяет гарантированно найти место формирования записей в любом регистре.