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