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