Как вызвать функцию из расширения во внешнем отчете 1С и настроить отладку

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

При работе с типовыми конфигурациями, такими как ЗУП 3.1, ERP или КА, разработчики часто сталкиваются с необходимостью доработки внешних отчетов, которые должны взаимодействовать с кодом, вынесенным в расширение. Типичная ситуация: в расширении создан общий модуль с полезными функциями, но при попытке вызвать их из внешнего отчета конфигуратор выдает ошибку: Переменная не определена. Кроме того, часто возникает проблема с отладкой, когда точка останова в коде внешнего отчета попросту игнорируется системой.

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

Почему возникает ошибка компиляции «Переменная не определена»

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

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

Решение 1: Использование методов БСП для динамического вызова

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

Вместо прямого вызова:

ТЗ = _НашаОрг_.ПолучитьИсториюФЛ(ТЗ);

Мы используем метод ОбщегоНазначения.ОбщийМодуль(). Это позволяет «обмануть» компилятор, так как имя модуля передается в виде строки, и проверка наличия этого модуля будет происходить уже непосредственно в момент выполнения кода в пользовательском режиме.

Посмотрим на пример кода:


// Получаем ссылку на модуль расширения динамически
НашМодуль = ОбщегоНазначения.ОбщийМодуль("_НашаОрг_");

// Вызываем экспортную функцию из этого модуля
ТЗ = НашМодуль.ПолучитьИсториюФЛ(ТЗ);

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

Решение 2: Использование функции Вычислить()

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

Разберем пример реализации:


// Формируем строку вызова функции с параметрами
ИмяМодуля = "_НашаОрг_";
ИмяФункции = "ПолучитьИсториюФЛ";
Результат = Вычислить(ИмяМодуля + "." + ИмяФункции + "(ТЗ)");

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

Почему не работает точка останова и как это исправить

Ситуация, когда точка останова установлена, но отладчик на ней не замирает, крайне распространена при работе с внешними отчетами и расширениями. Выясним основные причины этого поведения:

  1. Безопасный режим. Внешние отчеты, загруженные через справочник «Дополнительные отчеты и обработки», по умолчанию запускаются в безопасном режиме. В этом режиме отладка часто блокируется, а доступ к модулям расширений может быть ограничен. Решение: В карточке дополнительного отчета найдите настройку режима безопасности и попробуйте отключить его (установите «Небезопасный режим» или снимите флаг защиты).
  2. Фоновые задания. В современных конфигурациях (особенно в ЗУП 3.1) формирование отчетов часто происходит в фоновом задании на сервере. По умолчанию отладчик «цепляется» только к текущему сеансу пользователя. Решение: Перейдите в меню Отладка — Подключение, нажмите кнопку Настройка и убедитесь, что установлен флаг Автоматическое подключение: Фоновые задания.
  3. Кэширование расширений. Платформа 1С агрессивно кэширует код расширений. Иногда изменения, внесенные в расширение, уже работают, но отладчик использует старые индексы строк. Решение: Попробуйте очистить кэш (удалить базу из списка и добавить снова) или перезапустить службу 1С:Предприятия, если разработка ведется на серверной базе.
  4. Область видимости (Клиент/Сервер). Проверьте, где именно стоит точка останова. Если вы пытаетесь отладить серверный вызов из клиентской процедуры без соответствующих прав или настроек протокола отладки (TCP/IP или HTTP), остановка не произойдет.

Проверка доступности модуля программным способом

Чтобы ваш отчет не «падал» с критической ошибкой, если расширение по какой-то причине будет отключено или удалено, рекомендуется добавить проверку существования модуля. Рассмотрим, как это сделать правильно:


Попытка
    НашМодуль = ОбщегоНазначения.ОбщийМодуль("_НашаОрг_");
    ТЗ = НашМодуль.ПолучитьИсториюФЛ(ТЗ);
Исключение
    ТекстОшибки = "Не удалось выполнить операцию: модуль расширения '_НашаОрг_' не найден или недоступен.";
    ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
КонецПопытки;

Использование конструкции Попытка...Исключение в данном случае оправдано, так как объектная модель Метаданные.ОбщиеМодули не всегда корректно отображает состав модулей из расширений в зависимости от версии платформы и режима совместимости.

Подведем итоги

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

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

← На главную