Как найти код, который записывает данные в регистр сведений 1С: советы по отладке

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

В процессе разработки и сопровождения сложных систем на базе 1С, таких как «Комплексная автоматизация» или «CRM», программисты часто сталкиваются с ситуацией «мистической» записи данных. Представьте: в регистр сведений внезапно записываются тысячи строк, хотя стандартный глобальный поиск по конфигурации не показывает явных мест вызова метода Записать(), а обычная точка останова в модуле набора записей не срабатывает. Разберем пошагово, как вычислить виновника записи, используя различные инструменты платформы.

Анализ событий модуля набора записей

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


Процедура ПередЗаписью(Отказ, Замещение)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    // Дальнейшая логика
КонецПроцедуры

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

Использование стека вызовов для поиска источника

Когда точка останова сработала, нам необходимо выяснить, какой именно алгоритм привел к записи. Для этого воспользуемся окном Стек вызовов (Call Stack). Проанализируем цепочку вызовов: если запись идет из общего модуля, название которого содержит слова «Почта», «Интеграция» или «CRM», мы сможем быстро перейти к исходному коду. Однако бывает, что запись происходит в фоновом задании. В этом случае убедитесь, что у вас включена отладка фоновых заданий в настройках предмета отладки, иначе выполнение кода пройдет мимо вашего внимания.

Создание подписки на событие в расширении

Если вы не хотите менять типовую конфигурацию или подозреваете, что запись идет через механизмы, которые сложно отследить напрямую, создадим Подписку на событие. В расширении выберите объект РегистрСведенийНаборЗаписей.ИмяВашегоРегистра и создайте обработчик для события ПередЗаписью. Этот метод гарантированно сработает при любой попытке изменения данных в регистре. Внутри обработчика можно прописать дополнительную проверку условий (например, количество записей в наборе), чтобы отладчик срабатывал только тогда, когда в регистр «валится» подозрительно большой объем данных.

Замер производительности как инструмент поиска

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

  1. Запускаем замер производительности в конфигураторе.
  2. Инициируем действие, которое приводит к записи (например, запуск регламентного задания по получению почты).
  3. Останавливаем замер.
  4. В окне результата используем поиск (Ctrl+F) по имени метаданных регистра (например, CRM_НепрочитанныеЭлектронныеПисьма).

Замер покажет все места, где происходило обращение к менеджеру или набору записей этого регистра, даже если вызов был динамическим, через конструкцию вида РегистрыСведений[ИмяРегистра]. Вы увидите конкретные строки кода и количество времени, затраченное на их выполнение.

Поиск динамических вызовов по строке

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

Попробуйте выполнить глобальный поиск по строке "CRM_НепрочитанныеЭлектронныеПисьма" (обязательно в кавычках). Это позволит найти места, где имя регистра используется как строковый литерал для обращения к метаданным. Также полезно выполнить поиск ссылок на объект метаданных через контекстное меню в дереве конфигурации.

Анализ фоновых заданий и Журнала регистрации

Если записи появляются «сами собой» через некоторое время после завершения основного процесса, проанализируем список фоновых заданий. В консоли фоновых заданий (или через стандартную обработку в «Администрировании») сопоставим время появления записей в регистре со временем работы различных процессов. В CRM-системах часто после основного задания «Получение почты» запускаются цепочки других заданий:

Заглянем в Журнал регистрации. Настроим отбор по метаданным (наш регистр) и событию «Данные. Изменение». В колонке «Данные» мы увидим, какие именно записи были сделаны, а в колонке «Сеанс» — номер сеанса фонового задания. Зная номер сеанса, мы сможем точно определить, какое регламентное задание инициировало процесс.

Специфика CRM и протокола IMAP

В случае с регистром CRM_НепрочитанныеЭлектронныеПисьма в КА 2.4, проблема часто кроется в механизме синхронизации флагов прочтения. Проанализируем, как работает этот процесс: 1С запрашивает у почтового сервера список сообщений и их атрибуты. Если почтовый сервер (например, при использовании протокола IMAP) возвращает некорректные идентификаторы (UID) или если папка на сервере была перемещена, 1С может решить, что все старые письма — новые, и заново запишет их в регистр непрочитанных.

Посмотрим на код из типового модуля:


ЗаписьДействия.Действие = ?(НЕ Прочитано, 
    Перечисления.CRM_ДействияПоIMAP.УстановитьФлагПрочтения, 
    Перечисления.CRM_ДействияПоIMAP.СнятьФлагПрочтения);

Этот фрагмент указывает на наличие очереди отложенных операций. То есть запись в ваш регистр может быть следствием обработки этой очереди другим процессом. Проверьте состояние регистра CRM_ОтложенныеОперацииПоIMAP — возможно, причина массовых записей кроется в накоплении ошибок синхронизации именно там.

Технологический журнал (для продвинутых случаев)

Если даже замер производительности не вносит ясности, воспользуемся «тяжелой артиллерией» — Технологическим журналом. Мы можем настроить сбор события SDBL (запросы к базе данных) с фильтром по имени таблицы, соответствующей нашему регистру. В лог-файле Технологического журнала будет зафиксирован не только сам факт записи, но и полный стек вызовов на языке 1С. Это позволит увидеть всю цепочку даже в самых запутанных случаях, когда используются сложные схемы динамического исполнения кода или COM-соединения.

← На главную