При сопровождении систем на базе 1С:Управление производственным предприятием (УПП) ред. 1.3 часто возникает ситуация, когда типовые отчеты заменяются модифицированными внешними версиями. Это позволяет оперативно обновлять логику отчета без необходимости динамического обновления конфигурации или выгона пользователей. Однако при этом ломаются стандартные кнопки в интерфейсах, которые были жестко привязаны к объектам метаданных. В этой статье мы подробно разберем, как восстановить работоспособность кнопок, направив их на открытие внешних файлов отчетов.
Рассмотрим сценарий: в конфигурации существовал отчет, который был выведен на панель инструментов одного из общих интерфейсов. После удаления отчета из состава метаданных и замены его внешним файлом (.erf), кнопка в интерфейсе перестала работать, так как ее свойство Действие ссылается на несуществующий объект. Нам необходимо изменить логику кнопки так, чтобы она программно находила внешний отчет в справочнике Внешние обработки и открывала его форму.
В «Обычном приложении» (которое используется в УПП 1.3) интерфейс настраивается в Конфигураторе. Чтобы кнопка могла выполнить какой-либо код, этот код должен быть оформлен в виде экспортной процедуры в общем модуле. Проанализируем важный нюанс: в редакторе интерфейсов в поле выбора действия отображаются только процедуры из Глобальных общих модулей.
Рассмотрим порядок действий:
РаботаСИнтерфейсомГлобальный) или используем существующий.Для того чтобы открыть внешний отчет, хранящийся в базе, нам нужно: найти его в справочнике, извлечь двоичные данные файла, сохранить их во временный файл на диске и создать объект через менеджер ВнешниеОтчеты. Разберем реализацию этой функции подробнее.
Добавим в наш общий модуль следующий код:
Функция ПолучитьОбъектВнешнегоОтчета(ИмяОтчета) Экспорт
Попытка
// Ищем отчет в справочнике по наименованию
СсылкаНаСправочник = Справочники.ВнешниеОбработки.НайтиПоНаименованию(ИмяОтчета, Истина);
Если СсылкаНаСправочник.Пустая() Тогда
Предупреждение("Внешний отчет '" + ИмяОтчета + "' не найден в справочнике!");
Возврат Неопределено;
КонецЕсли;
// Получаем двоичные данные из хранилища значения
ДвоичныеДанные = СсылкаНаСправочник.ХранилищеВнешнейОбработки.Получить();
Если ДвоичныеДанные = Неопределено Тогда
Предупреждение("Файл отчета пуст!");
Возврат Неопределено;
КонецЕсли;
// Формируем уникальное имя временного файла для предотвращения конфликтов
ИмяФайла = ПолучитьИмяВременногоФайла("erf");
ДвоичныеДанные.Записать(ИмяФайла);
// Создаем объект внешнего отчета.
// Второй параметр "Ложь" отключает безопасный режим (если отчету нужны полные права)
ОбъектОтчета = ВнешниеОтчеты.Создать(ИмяФайла, Ложь);
Возврат ОбъектОтчета;
Исключение
Сообщить("Ошибка при загрузке отчета: " + ОписаниеОшибки(), СтатусСообщения.Важное);
Возврат Неопределено;
КонецПопытки;
КонецФункции
Процедура ОткрытьВнешнийОтчетПродажи() Экспорт
Объект = ПолучитьОбъектВнешнегоОтчета("Отчет по продажам (внешний)");
Если Объект <> Неопределено Тогда
Форма = Объект.ПолучитьФорму();
Форма.Открыть();
КонецЕсли;
КонецПроцедуры
В данном коде мы используем метод ПолучитьИмяВременногоФайла, что критически важно для работы в терминальном режиме. Если жестко прописать путь к файлу, несколько пользователей не смогут открыть отчет одновременно из-за блокировки файла операционной системой.
Теперь перейдем к визуальной части. Разберем, как привязать нашу процедуру к кнопке:
ОткрытьВнешнийОтчетПродажи. Выберем ее.Важный нюанс: если вы не видите свою процедуру в списке, убедитесь, что она помечена ключевым словом Экспорт и модуль действительно является глобальным. Если вы принципиально не хотите использовать глобальные модули, воспользуйтесь следующим методом: создайте новый элемент интерфейса (кнопку), так как при создании нового элемента платформа иногда более гибко обновляет кэш доступных процедур.
Проанализируем ситуацию: в типовой конфигурации УПП 1.3 уже реализованы механизмы для работы с внешними объектами. Вместо написания своего велосипеда, можно обратиться к общему модулю УниверсальныеМеханизмы. Это более правильный подход с точки зрения поддержки архитектуры конфигурации.
Пример вызова через типовой механизм:
Процедура ОткрытьОтчетТиповымСпособом() Экспорт
СсылкаНаОтчет = Справочники.ВнешниеОбработки.НайтиПоНаименованию("МойВнешнийОтчет");
Если НЕ СсылкаНаОтчет.Пустая() Тогда
// Типовая функция УПП для открытия внешних форм
УниверсальныеМеханизмы.ОткрытьВнешнююФорму(СсылкаНаОтчет);
КонецЕсли;
КонецПроцедуры
Метод ОткрытьВнешнююФорму самостоятельно позаботится о создании временного файла, проверке прав доступа и корректном открытии основной формы объекта. Это сокращает количество кода и делает его более надежным.
Рассмотрим несколько советов, которые помогут избежать проблем при эксплуатации решения:
1. Очистка временных файлов. После выполнения метода ВнешниеОтчеты.Создать(ИмяФайла), объект отчета уже загружен в память 1С. Физический файл на диске больше не нужен. Хорошей практикой считается удаление файла сразу после создания объекта, чтобы не засорять папку Temp на сервере или компьютере пользователя.
2. Безопасный режим. Если внешний отчет получен из ненадежного источника, при его создании рекомендуется передавать параметр БезопасныйРежим = Истина. Это ограничит возможности отчета по работе с файловой системой и COM-объектами, защищая систему от вредоносного кода.
3. Использование Панели отчетов. Проанализируем альтернативу: вместо изменения интерфейса в Конфигураторе, можно зарегистрировать отчет в справочнике Внешние обработки и настроить его принадлежность к определенной подсистеме. В УПП 1.3 есть встроенная Панель отчетов, которая автоматически подхватывает такие отчеты. Это позволит пользователям видеть отчет в привычном разделе меню без внесения изменений в структуру самой конфигурации.
Таким образом, мы рассмотрели как прямой способ встройки через глобальные модули и редактор интерфейсов, так и более продвинутые методы с использованием типового функционала УПП. Выбор конкретного метода зависит от ваших требований к гибкости системы и необходимости минимизировать изменения в коде конфигурации.