В процессе администрирования и сопровождения крупных баз 1С перед разработчиками часто возникает задача автоматизации рутинных процессов. Один из типичных примеров — необходимость периодически (например, каждую ночь или в конце месяца) выгружать результаты различных отчетов (Оборотно-сальдовая ведомость, Книга покупок, Книга продаж, Журнал счетов-фактур) в сторонний формат, чаще всего в PDF, для последующего архивирования или отправки руководству. Ситуация усложняется, когда конфигурация должна оставаться на полной поддержке («типовая»), баз в обслуживании много (например, около 300 филиалов), а сами отчеты построены на разных технологиях — часть на СКД, а часть на собственном программном алгоритме.
В этой статье мы подробно разберем, почему популярные интерактивные методы (имитация нажатия клавиш, поиск открытых окон) не работают в фоновом режиме, и рассмотрим надежные программные способы решения этой задачи в конфигурации 1С:Бухгалтерия предприятия 3.0 (БП 3.0) с использованием механизмов БСП (Библиотеки стандартных подсистем).
На начальном этапе у разработчиков часто возникает соблазн использовать простые «кликерные» решения. Например, получить форму отчета, найти кнопку «Сформировать» и программно вызвать её действие с помощью метода ПолучитьДействие или сымитировать нажатие клавиш через COM-объект Wscript.Shell:
Wsh = Новый СОМОбъект("Wscript.shell");
Wsh.SendKeys("^+Enter"); // Попытка вызвать "Сформировать"
Проанализируем, почему этот путь ведет в тупик:
ПолучитьОкна() требует предварительного ручного открытия этих форм пользователем, что полностью перечеркивает саму идею автоматизации.Выяснив нежизнеспособность «клиентских» методов, перейдем к правильным серверным решениям, которые работают незаметно для пользователя.
Прежде чем писать собственный код, давайте обратим внимание на отличный штатный функционал, который уже заложен разработчиками 1С в БСП. В разделе Администрирование — Рассылки отчетов доступен мощный инструмент.
Этот механизм позволяет настраивать:
Важная особенность: этот механизм отлично подходит для отчетов, разработанных на базе Системы компоновки данных (СКД). Однако для некоторых специфических регламентированных отчетов (таких как Книга покупок или Книга продаж) стандартный функционал рассылок в базовом виде может не подойти из-за особенностей их формирования. В таком случае нам потребуется программный вызов.
Все стандартные бухгалтерские отчеты в БП 3.0 используют унифицированный программный интерфейс общего модуля БухгалтерскиеОтчетыВызовСервера. Нам не нужно открывать форму отчета, чтобы получить его результат. Достаточно сформировать структуру параметров и вызвать серверный метод.
Рассмотрим по шагам, как программно сформировать ОСВ по счету 41 и сохранить результат в PDF:
// 1. Формируем структуру параметров отчета
ПараметрыОтчета = Новый Структура;
ПараметрыОтчета.Вставить("НачалоПериода", НачалоДня(ТекущаяДата() - 86400)); // Например, за вчерашний день
ПараметрыОтчета.Вставить("КонецПериода", КонецДня(ТекущаяДата() - 86400));
ПараметрыОтчета.Вставить("Организация", Справочники.Организации.НайтиПоРеквизиту("ИНН", "7700000000"));
ПараметрыОтчета.Вставить("Счет", ПланыСчетов.Хозрасчетный.ТоварыНаСкладах); // Счет 41
// 2. Создаем уникальный идентификатор и подготавливаем временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
// 3. Вызываем формирование отчета на сервере без участия интерфейса
БухгалтерскиеОтчетыВызовСервера.СформироватьОтчет(ПараметрыОтчета, АдресХранилища);
// 4. Получаем табличный документ из хранилища
РезультатВыполнения = ПолучитьИзВременногоХранилища(АдресХранилища);
Если РезультатВыполнения <> Неопределено Тогда
// Обратите внимание: в зависимости от релиза БП имя свойства может отличаться (Result или Результат)
ТабДок = РезультатВыполнения.Result;
// Записываем полученный табличный документ в файл на диске
ПутьКФайлуPDF = "C:\Reports\ОСВ_41_" + Формат(ТекущаяДата(), "ДФ=ггггММдд") + ".pdf";
ТабДок.Записать(ПутьКФайлуPDF, ТипФайлаТабличногоДокумента.PDF);
КонецЕсли;
Данный подход является абсолютно «чистым»: он не требует открытия окон, работает непосредственно на сервере и может выполняться в рамках любого регламентного задания.
Отчеты по НДС, такие как Книга покупок, имеют сложную структуру формирования и не используют стандартную СКД в чистом виде. Тем не менее, у объекта конфигурации ОтчетОбъект.КнигаПокупок есть программный интерфейс, который мы можем задействовать напрямую.
Рассмотрим пример генерации Книги покупок программным способом:
// Создаем экземпляр объекта отчета программно
ОтчетОбъект = Отчеты.КнигаПокупок.Создать();
КомпоновщикНастроек = ОтчетОбъект.КомпоновщикНастроек;
// Заполняем настройки компоновщика (параметры отчета)
КомпоновщикНастроек.Настройки.Параметры.УстановитьЗначениеПараметра("ДатаНачала", НачалоКвартала(ТекущаяДата()));
КомпоновщикНастроек.Настройки.Параметры.УстановитьЗначениеПараметра("ДатаОкончания", КонецКвартала(ТекущаяДата()));
ОрганизацияСсылка = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7700000000");
КомпоновщикНастроек.Настройки.Параметры.УстановитьЗначениеПараметра("Организация", ОрганизацияСсылка);
// Инициализируем чистый Табличный Документ для вывода результата
ТабДок = Новый ТабличныйДокумент;
// Вызываем предопределенный метод формирования отчета
ОтчетОбъект.СформироватьОтчет(ТабДок, КомпоновщикНастроек.Настройки);
// Сохраняем результат в PDF
ПутьККнигеПокупок = "C:\Reports\КнигаПокупок_" + ОрганизацияСсылка.Код + ".pdf";
ТабДок.Записать(ПутьККнигеПокупок, ТипФайлаТабличногоДокумента.PDF);
Этот метод позволяет полностью отказаться от эмуляции нажатия кнопок на форме отчета КнигаПокупок и гарантирует корректное построение бланка в соответствии со всеми актуальными требованиями законодательства, заложенными в модуль отчета.
Когда перед разработчиком стоит задача внедрить этот механизм в 300 баз, вносить изменения непосредственно в основную конфигурацию или даже создавать и поддерживать 300 расширений — крайне нерационально. При обновлении конфигурации типовыми релизами любые изменения могут потребовать ручной работы по адаптации кода.
Идеальным решением в данной ситуации является использование встроенного механизма БСП — «Дополнительные отчеты и обработки».
Алгоритм развертывания выглядит следующим образом:
.epf).СведенияОВнешнейОбработке(), чтобы система распознала её как дополнительную обработку.ВыполнитьКоманду() размещаем наш код автоматического формирования необходимых отчетов (используя алгоритмы из Решений 2 и 3) и логику сохранения файлов в целевую папку или на FTP.Для массового распределения этой обработки по 300 базам можно написать простой скрипт на VBScript, PowerShell или Python, который через COM-соединение (V83.COMConnector) подключится к каждой информационной базе, найдет в справочнике ДополнительныеОтчетыИОбработки нужный элемент по наименованию и обновит двоичные данные файла обработки:
// Пример схематичного кода обновления обработки через COM-соединение
СправочникСсылка = Соединение1С.Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("АвтосохранениеОтчетов");
Если Не СправочникСсылка.Пустая() Тогда
ОбработкаОбъект = СправочникСсылка.ПолучитьОбъект();
ОбработкаОбъект.ХранилищеОбработки = Новый Соединение1С.ХранилищеЗначения(Соединение1С.НовыйДвоичныеДанные(ПутьКЛокальномуФайлуEPF));
ОбработкаОбъект.Записать();
КонецЕсли;
Использование этого подхода гарантирует, что ваша основная конфигурация останется абсолютно типовой, базы будут беспрепятственно обновляться автоматическими инструментами 1С, а логика формирования архива отчетов будет централизованно управляться через один внешний файл обработки.