Почему регламентное задание 1С выгружает не все данные в XML и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с регламентными заданиями в 1С:Предприятие часто преподносит сюрпризы, особенно когда речь идет о длительных операциях выгрузки данных в сторонние системы. Одной из наиболее запутанных ситуаций является «тихий» сбой: Журнал регистрации рапортует об успешном завершении задания, но по факту в конечном файле XML отсутствуют целые блоки данных (например, определенные периоды или группы записей). При этом ручной запуск той же самой обработки отрабатывает без нареканий.

В данной статье мы подробно разберем, почему возникают подобные аномалии, как организовать надежную диагностику и какие архитектурные подходы гарантируют стабильную выгрузку больших объемов информации.

Выясним основную причину: конфликт копий и совместный доступ

Разберем ситуацию, которая часто встречается в реальной практике. Если у вас на сервере развернута копия основной базы (для тестов, отчетов или разработки), в ней по умолчанию могут быть включены те же регламентные задания, что и в «проде». Проанализируем, что происходит в этом случае:

  1. Две базы (продуктив и копия) одновременно инициируют выгрузку в один и тот же сетевой каталог или локальный файл.
  2. Один процесс блокирует файл для записи, а второй либо прерывается с ошибкой «Ошибка совместного доступа к файлу», либо перезаписывает данные первого.
  3. В некоторых случаях rphost может аварийно завершить поток записи, из-за чего файл XML остается «обрезанным» (без закрывающих тегов), но статус задания в Журнале регистрации помечается как «Выполнено», если ошибка произошла на уровне файловой системы в финальный момент закрытия потока.

Решение: Всегда отключайте регламентные задания в копиях информационных баз. Проверим программный способ защиты: добавим в начало модуля регламентного задания проверку на имя сервера или путь к базе данных. Рассмотрим пример кода:


Процедура ВыполнитьВыгрузкуДанных()
    СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
    Если Найти(Врег(СтрокаСоединения), "SERVER_PRODUCTION") = 0 Тогда
        ЗаписьЖурналаРегистрации("ВыгрузкаДанных", УровеньЖурналаРегистрации.Предупреждение, , , "Запуск в копии базы отменен.");
        Возврат;
    КонецЕсли;
    
    // Далее идет основная логика выгрузки
КонецПроцедуры

Диагностика через Технологический журнал и логирование

Если проблема не в копиях, нам потребуется «тяжелая артиллерия». Обычный Журнал регистрации может не фиксировать падения рабочих процессов сервера. Рассмотрим, как настроить инструменты мониторинга.

Во-первых, проанализируем состояние рабочих процессов rphost. При выгрузке огромных файлов XML (гигабайты данных) потребление памяти может превысить допустимые лимиты, установленные в консоли кластера. В этом случае сервер 1С принудительно перезапускает процесс. Для отслеживания таких событий настроим Технологический журнал (файл logcfg.xml) на событие EXCP (исключительные ситуации) и PROC (завершение процессов):


<log location="C:\1C_Logs" history="72">
    <event>
        <eq property="Name" value="EXCP"/>
    </event>
    <event>
        <eq property="Name" value="PROC"/>
    </event>
    <property name="all"/>
</log>

Во-вторых, создадим собственное «текстовое логирование». Это позволит нам увидеть реальный прогресс выполнения задания в режиме реального времени. Посмотрим на пример реализации логирования в отдельный файл:


ТекстЛога = Новый ТекстовыйДокумент;
ТекстЛога.ДобавитьСтроку("" + ТекущаяДата() + ": Начало выгрузки.");
// ... выборка данных ...
ТекстЛога.ДобавитьСтроку("" + ТекущаяДата() + ": Выбрано записей: " + КоличествоЗаписей);
ТекстЛога.Записать("C:\Logs\export_log.txt");

Рекомендуется записывать метки времени через каждые 10 000 — 50 000 итераций. Если выгрузка прервется, по последней записи в текстовом логе мы поймем, на каком именно этапе произошел сбой.

Оптимизация работы с памятью при записи XML

Частой ошибкой программистов является формирование всего XML-документа в одной строковой переменной или использование объекта ДокументDOM для очень больших объемов данных. Это гарантированный путь к переполнению оперативной памяти.

Рассмотрим правильный подход с использованием объекта ЗаписьXML. Этот объект выполняет потоковую запись данных непосредственно на диск, не накапливая весь текст в памяти 1С. Проанализируем структуру кода:


Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ПутьКФайлу, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Root");

Выборка = РегистрыСведений.НазваниеРегистра.Выбрать(ДатаНачала, ДатаКонца);
Пока Выборка.Следующий() Цикл
    Запись.ЗаписатьНачалоЭлемента("Item");
    Запись.ЗаписатьАтрибут("Period", Формат(Выборка.Период, "ДФ=yyyy-MM-dd"));
    // Запись остальных данных
    Запись.ЗаписатьКонецЭлемента(); // Item
КонецЦикла;

Запись.ЗаписатьКонецЭлемента(); // Root
Запись.Закрыть();

Важный момент: использование конструкции Попытка...Исключение вокруг всего цикла выгрузки обязательно. В блоке Исключение необходимо принудительно вызывать Запись.Закрыть(), иначе файл останется заблокированным процессом даже после ошибки.

Исключение конфликтов с внешними системами (Qlik, PowerBI и др.)

Если внешняя система (приемник данных) настроена на автоматическое считывание файла при его появлении, может возникнуть ситуация, когда 1С еще пишет данные, а Qlik уже пытается их прочитать. Это приводит к блокировке файла и неполной выгрузке.

Разберем стратегию «Временного файла», которая считается стандартом в промышленной разработке:

  1. Выгружаем данные во временный файл с расширением .tmp (например, data_2023.xml.tmp).
  2. Только после выполнения метода Запись.Закрыть(), когда файл гарантированно сформирован и освобожден 1С, выполняем переименование файла в целевой (data_2023.xml).
  3. Операция переименования на уровне ОС происходит мгновенно, и внешняя система получает доступ только к полностью готовому файлу.

Для переименования используем метод ПереместитьФайл():


ИмяФайлаВременное = "C:\Export\data.xml.tmp";
ИмяФайлаИтоговое  = "C:\Export\data.xml";
// ... процесс выгрузки в ИмяФайлаВременное ...
ПереместитьФайл(ИмяФайлаВременное, ИмяФайлаИтоговое);

Использование «флагов завершения»

Для еще большей надежности можно использовать механизм «файлов-флагов». Рассмотрим эту методику: после успешной выгрузки 1С создает в папке пустой файл с именем success.txt. Система-приемник начинает обработку только при наличии этого файла, а после завершения чтения — удаляет его. Регламентное задание 1С перед началом новой выгрузки проверяет отсутствие флага. Если флаг еще существует, значит, предыдущая порция данных не обработана или процесс завис, и запуск стоит отложить.

Проанализируем преимущества этого метода:

Заключение

Подводя итог, отметим, что «сбои» регламентных заданий редко бывают случайными. Чаще всего это следствие нехватки ресурсов (памяти), конфликтов доступа или отсутствия проверок на среду выполнения (продуктив/копия). Используя потоковую запись через ЗаписьXML, настраивая технологический журнал и внедряя схему с временными файлами, мы можем добиться стопроцентной стабильности интеграционных процессов.

← На главную