При автоматизации процессов в 1С:Предприятие часто возникает задача автоматического формирования отчетов по расписанию с последующим сохранением файла на диск или отправкой по электронной почте. Начинающие разработчики часто пытаются использовать для этого привычные методы работы с интерфейсом, например, создание или открытие формы отчета через ПолучитьФорму() или ОткрытьФорму(). Однако при попытке выполнить такой код внутри фонового или регламентного задания система выдает критическую ошибку.
В этой статье мы подробно разберем, почему исходный код с вызовом форм не работает в контексте регламентных заданий, проанализируем архитектуру выполнения серверного кода в 1С и изучим два надежных способа программной генерации отчетов на базе Схемы компоновки данных (СКД) без какого-либо участия интерфейса.
Рассмотрим исходный код, который пытался использовать автор темы на форуме:
ОтборОтчета = новый Структура("ОсновнаяСхемаКомпоновкиДанных");
ПараметрыОтчета = Новый Структура("СформироватьПриОткрытии, Отбор", истина, ОтборОтчета);
А = Отчеты.ОстаткиНашиИПоставщиков.ПолучитьФорму("Отчет.ОстаткиНашиИПоставщиков.Форма.ФормаОтчета",ПараметрыОтчета);
А.Активизировать;
Этот код абсолютно неработоспособен в регламентном задании по фундаментальным причинам архитектуры платформы 1С. Давайте разберем их по шагам.
rphost). На сервере полностью отсутствует понятие «клиентского окружения», нет экранных форм, окон, элементов управления и графического интерфейса пользователя.ПолучитьФорму(), ОткрытьФорму(), а также обращение к свойствам окон (например, Активизировать()) или интерактивным диалогам (Предупреждение(), Вопрос()) на сервере мгновенно приводят к вызову исключения и аварийной остановке выполнения фонового задания.Таким образом, для решения нашей задачи нам необходимо полностью исключить клиентские методы и переписать алгоритм так, чтобы отчет формировался строго в памяти сервера и записывался в файл. Рассмотрим, как это сделать практически.
Если ваш отчет разработан на базе Системы компоновки данных (СКД) и вам не нужно динамически менять сложную структуру колонок или группировок, самым простым и лаконичным решением будет использование встроенного метода СкомпоноватьРезультат().
Этот метод автоматически берет основную схему компоновки данных, применяет настройки по умолчанию (или те, которые были изменены программно в модуле объекта) и выводит результат в переданный табличный документ.
Рассмотрим по шагам пример серверной процедуры, которую можно вызывать непосредственно из регламентного задания:
Процедура СформироватьОтчетРегламентно() Экспорт
// Шаг 1. Создаем программный экземпляр объекта отчета на сервере
ОтчетОбъект = Отчеты.ОстаткиНашиИПоставщиков.Создать();
// Шаг 2. Инициализируем пустой табличный документ для вывода результата
ТабДок = Новый ТабличныйДокумент;
// Шаг 3. Вызываем встроенный метод компоновки.
// Он выполнит все запросы СКД и выведет готовые области в ТабДок.
// Если в модуле объекта определено событие ПриКомпоновкеРезультата, оно также выполнится.
ОтчетОбъект.СкомпоноватьРезультат(TabDoc);
// Шаг 4. Определяем путь для сохранения и записываем документ на диск сервера
// Формируем уникальное имя файла с текущей датой и временем
ИмяФайла = "Остатки_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".xlsx";
ПутьКФайлу = "C:\Reports\" + ИмяФайла; // Для Windows-сервера
Попытка
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
ЗаписьЖурналаРегистрации("РегламентныеЗадания.ФормированиеОтчета",
УровеньЖурналаРегистрации.Информация, , ,
"Отчет успешно сформирован и сохранен по пути: " + ПутьКФайлу);
Исключение
ЗаписьЖурналаРегистрации("РегламентныеЗадания.ФормированиеОтчета",
УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при записи файла отчета: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
При использовании этого способа система отрабатывает весь стандартный жизненный цикл генерации отчета. Если вам нужно установить какие-то базовые параметры, вы можете сделать это непосредственно перед вызовом компоновки, обратившись к КомпоновщикНастроек.
В реальных задачах часто требуется не просто сформировать отчет «как есть», но и предварительно установить динамические параметры (например, установить в качестве периода текущую дату начала дня) или наложить программные отборы по конкретным элементам справочников. Для этого мы разберем классическую схему программного вывода СКД.
Проанализируем детальный пример кода, который полностью заменяет интерактивное открытие формы и ручной ввод параметров пользователем:
Процедура СформироватьОтчетСПараметрамиРегламентно() Экспорт
// Шаг 1. Создаем объект отчета и получаем его схему компоновки
ОтчетОбъект = Отчеты.ОстаткиНашиИПоставщиков.Создать();
СхемаСКД = ОтчетОбъект.СхемаКомпоновкиДанных;
// Шаг 2. Получаем текущие настройки компоновщика (по умолчанию или пользовательские)
Настройки = ОтчетОбъект.КомпоновщикНастроек.Настройки;
// Шаг 3. Программная установка параметров данных
// Найдем параметр "Период" и установим в него текущую дату конца вчерашнего дня
ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрПериод <> Неопределено Тогда
ПараметрПериод.Значение = КонецДня(ТекущаяДата() - 86400); // Вчерашний день
ПараметрПериод.Использование = Истина;
КонецЕсли;
// Шаг 4. Динамическое добавление отбора (аналог "ОтборОтчета" из интерфейса формы)
// Добавим отбор по конкретной Организации
НовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
// Выполняем поиск нужного предопределенного элемента или по реквизиту на сервере
ОрганизацияСсылка = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7712345678");
Если ЗначениеЗаполнено(ОрганизацияСсылка) Тогда
НовыйОтбор.ПравоеЗначение = ОрганизацияСсылка;
НовыйОтбор.Использование = Истина;
Иначе
НовыйОтбор.Использование = Ложь; // Отключаем отбор, если элемент не найден
КонецЕсли;
// Шаг 5. Инициализация процесса компоновки макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки);
// Шаг 6. Инициализация процессора компоновки данных, который связывает макет и источник данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициазировать(МакетКомпоновки);
// Шаг 7. Вывод результатов в итоговый табличный документ
ТабДок = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Шаг 8. Сохранение полученного табличного документа на сервере в формате PDF
ПутьКФайлу = "D:\Exchange\ОстаткиОрганизации.pdf";
Попытка
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
Исключение
ВызватьИсключение "Не удалось сохранить файл отчета по причине: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
С помощью этой схемы мы полностью управляем структурой СКД, можем точечно менять настройки вывода, отключать ненужные группировки или добавлять новые поля прямо «на лету» в коде серверного фонового задания.
При переносе кода формирования отчетов в регламентные задания разработчики часто сталкиваются с сопутствующими инфраструктурными проблемами. Проанализируем самые распространенные из них, чтобы вы могли избежать их на практике.
Когда вы выполняете интерактивный код на клиенте, файл сохраняется от имени вашей учетной записи Windows/Linux. Регламентное же задание выполняется от имени технического пользователя ОС, под которым запущена служба сервера 1С:Предприятия (обычно это USR1CV8 на Windows или usr1cv8 на Linux).
Важно: У этого системного пользователя должны быть полные права на чтение, запись и изменение целевой папки на сервере (например, "C:\Reports\"). Если прав будет недостаточно, код завершится с ошибкой доступа к файлу. Избегайте сохранения файлов в папки профилей пользователей (такие как Desktop или Мои Документы конкретного юзера).
Процедура, которая запускается регламентным заданием, должна находиться в общем модуле. Убедитесь, что свойства этого общего модуля настроены корректно в конфигураторе:
Истина.Ложь.Экспорт в конце своей сигнатуры.Если серверная часть вашей системы 1С развернута на Linux, помните о двух вещах. Во-первых, пути к файлам должны использовать прямой слэш (например, "/var/1c/reports/report.xlsx"). Во-вторых, файловая система Linux чувствительна к регистру символов в именах папок и файлов. Убедитесь, что все пути прописаны безошибочно.
Если вы работаете в современной типовой конфигурации (например, 1С:ERP, 1С:Комплексная автоматизация, 1С:Управление торговлей или 1С:Бухгалтерия), то в них уже встроена мощная подсистема «Рассылка отчетов».
Вместо написания собственного программного кода и создания регламентных заданий вручную, вы можете зайти в пользовательский режим, открыть справочник «Рассылки отчетов», выбрать нужный вариант отчета, настроить расписание, указать получателей (или сетевую папку для сохранения) и формат сохраняемого файла. Платформа сделает всю рутинную работу автоматически без привлечения программиста.
Мы подробно разобрали основные подходы к программному формированию отчетов на сервере 1С. Понимание разницы между клиентским и серверным контекстом выполнения кода — это залог создания стабильно работающих и надежных фоновых процессов в вашей системе.