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