Почему не срабатывает точка останова в общем модуле при вызове из СКД и как это исправить

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

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

Проверка подключения фоновых заданий

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

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

  1. Откроем Конфигуратор.
  2. Перейдем в меню Отладка — Подключение...
  3. В открывшемся окне нажмем кнопку Настройка...
  4. Установим флажок Автоматическое подключение для пункта Фоновые задания.
  5. Также рекомендуется включить автоматическое подключение для Тонкого клиента и Сервера.

После этого попробуем снова запустить отчет. Теперь при старте фонового задания отладчик должен автоматически «подцепиться» к нему, и точка останова сработает.

Настройка параметров отладки в текущем сеансе

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

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

Флаги и свойства общего модуля

Для того чтобы функция была доступна СКД и при этом корректно отлаживалась, необходимо проверить свойства самого объекта ОбщийМодуль в дереве метаданных. Выясним, какие флаги должны быть установлены:

  1. Глобальный: Если флаг снят, обращение в СКД идет через имя модуля: ИмяМодуля.ИмяФункции().
  2. Клиент (управляемое приложение) и Сервер: Поскольку компоновка данных обычно происходит на стороне сервера, флаг Сервер является обязательным.
  3. Вызов сервера: Этот флаг критичен, если вызов инициируется с клиента, а код должен выполниться на сервере.

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

Особенности внешних отчетов и безопасный режим

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


ПараметрыОткрытия = Новый Структура("КлючНазначенияИспользования", "ОтчетПоПродажам");
ПараметрыОткрытия.Вставить("БезопасныйРежим", Истина);
ОткрытьФорму("ВнешнийОтчет.МойОтчет.Форма", ПараметрыОткрытия);

То вызовы функций общих модулей могут блокироваться, либо отладчик не сможет в них зайти. Попробуем временно установить БезопасныйРежим = Ложь для целей отладки.

Кэширование выражений в процессоре компоновки

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

Чтобы «заставить» СКД гарантированно заходить в код для каждой строки, добавим в параметры функции поле, которое точно меняется. Например:

Вместо МойМодуль.Посчитать() напишем МойМодуль.Посчитать(Ссылка).

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

Принудительная остановка через исключение

Если все вышеперечисленные способы не помогают и точка останова упорно игнорируется, применим метод «грубой силы». Это позволит нам понять: код вообще выполняется или управление до него просто не доходит.

Вставьте в начало функции общего модуля следующую строку:

ВызватьИсключение "Код выполняется!";

Теперь запустим отчет. Возможны два варианта развития событий:

  1. Программа выдала ошибку с текстом "Код выполняется!": Это означает, что вызов функции происходит успешно, но проблема именно в настройках отладчика. Нужно еще раз проверить сеансы в окне Подключение.
  2. Отчет сформировался (или выдал другую ошибку): Это значит, что управление до вашей функции не доходит. Причину нужно искать в самой схеме компоновки — возможно, не выполняется условие, при котором рассчитывается данное вычисляемое поле, или функция указана с ошибкой в имени.

Проверка «чистоты» и доступности функции

Напоследок проанализируем саму структуру функции. Для корректной работы с СКД должны соблюдаться следующие правила:

Рассмотрим пример правильно оформленной функции для СКД:


// В общем модуле "РаботаСОтчетами" (флаг Сервер установлен)
Функция ПолучитьДополнительныйКоэффициент(АктуальнаяДата, СсылкаНаОбъект) Экспорт
    
    // Установим точку останова здесь
    Результат = 1;
    
    Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
        // Логика расчета
        Результат = 1.15;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

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

← На главную