Можно ли в отладчике 1С установить глобальную точку останова по значению реквизита?

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

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

Разберем архитектурные особенности платформы 1С:Предприятие, выясним, почему глобальная точка останова по данным не поддерживается напрямую, и рассмотрим практические способы решения этой задачи.

Ограничения платформы: почему нельзя поставить глобальную точку останова

В некоторых низкоуровневых средах разработки существует концепция точек останова по данным (watchpoints или data breakpoints). Они отслеживают обращения к конкретной области оперативной памяти на уровне процессора или виртуальной машины. В платформе 1С:Предприятие архитектура устроена иначе:

  1. Привязка отладчика только к строкам кода. Протокол отладки 1С умеет прерывать выполнение только на определенных строках модулей либо при возникновении системных исключений (ошибок). Отслеживание обращений к переменным в памяти на уровне платформы не предусмотрено ни в классическом Конфигураторе, ни в среде 1C:Enterprise Development Tools (EDT).
  2. Отсутствие переопределяемых аксессоров. В объектной модели языка 1С у реквизитов отсутствуют переопределяемые геттеры и сеттеры. Обычное присваивание значения переменной или реквизиту не инициирует системных событий, на которые можно было бы подписаться.
  3. Разные области видимости. Переменные или реквизиты с одинаковыми именами могут существовать в десятках различных контекстов, процедур и объектов конфигурации, что делает абстрактную глобальную проверку имени невозможной без явного указания контекста.

Способ 1. Точка останова с условием в предполагаемых местах изменения

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

Разберем по шагам, как настроить такую точку останова:

  1. Откроем нужный модуль конфигурации и установим курсор на строку, где происходит расчет или присвоение значения реквизиту.
  2. Нажмем клавишу F9 для создания точки останова.
  3. Откроем свойства точки останова через контекстное меню или список точек останова и заполним поле Условие. Например: Объект.Статус = Перечисления.СтатусыЗаказов.Отменен.

Отладчик остановит исполнение кода на этой строке только тогда, когда заданное выражение примет значение Истина.

Способ 2. Остановка по ошибке и искусственный чекпоинт

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

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


Если Объект.Реквизит = НужноеЗначение Тогда 
    ВызватьИсключение "Чекпоинт: обнаружено изменение реквизита";
КонецЕсли;

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

  1. В главном меню Конфигуратора перейдем в пункт Отладка — Настройка остановки по ошибке.
  2. Установим флаг Останавливаться по ошибке.
  3. Запустим сценарий в режиме предприятия. В момент срабатывания условия выполнение программы мгновенно прервется.
  4. Используем окно Стек вызовов, чтобы детально проанализировать всю цепочку вызовов, приведшую к установке данного значения.

Способ 3. Перехват изменений через подписку на событие

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

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

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

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

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

Способ 4. Анализ контекста через Технологический журнал

Если поведение воспроизводится исключительно под рабочей нагрузкой, в многопоточной среде или в фоновых заданиях, где подключение отладчика затруднено, используем Технологический журнал (ТЖ).

Настроим сбор событий с флагом контекста в конфигурационном файле logcfg.xml:

  1. Настроим фильтрацию по событию записи данных или обращению к СУБД для требуемой таблицы.
  2. Включим сбор свойства Context.
  3. После воспроизведения ситуации проанализируем сформированный лог ТЖ. Платформа зафиксирует полный стек вызовов процедур и функций на сервере в момент записи конкретного значения.
← На главную