Как быстро выгрузить большой объем записей журнала регистрации 1С без зависания системы?

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

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

Почему зависает команда «Вывести список»?

Проанализируем техническую сторону работы штатного механизма:

  1. Формирование табличного документа в ОЗУ: Команда «Вывести список» создает в оперативной памяти клиента объект ТабличныйДокумент. Каждая ячейка такого документа хранит метаданные о форматировании, шрифтах, границах и типах данных. Для таблицы в 700 000 строк это требует нескольких гигабайт памяти.
  2. Ограничения разрядности клиента: Если используется 32-разрядный клиент 1С, процесс ограничен адресным пространством в 2–3 ГБ. Превышение этого лимита приводит либо к постоянному сбросу страниц памяти в файл подкачки (свопингу), из-за чего система кажется «намертво зависшей», либо к ошибке «Недостаточно памяти».
  3. Ограничение на чтение журнала: Платформа 1С в клиент-серверном варианте имеет внутреннее ограничение — не более 4 одновременных запросов на чтение журнала регистрации на одну базу. Длительная блокировка интерфейса мешает нормальной работе других сеансов.
  4. Ограничения форматов электронных таблиц: Стоит учитывать, что файл Excel (.xlsx) поддерживает максимум 1 048 576 строк, а сторонние редакторы начинают работать медленно уже при объемах в десятки тысяч строк.

Способ 1. Потоковая выгрузка в CSV с помощью метода «ВыгрузитьЖурналРегистрации»

Самый быстрый и надежный программный способ выгрузить сотни тысяч записей — использовать метод ВыгрузитьЖурналРегистрации() с последующей потоковой записью строк в текстовый файл формата CSV через объект ЗаписьCSV или ЗаписьТекста. Чтобы не переполнять оперативную память, чтение выполняется порциями (по дням или с ограничением по количеству строк).

Рассмотрим пример кода обработки, которая читает журнал регистрации порциями и сразу сбрасывает данные на диск:


ФильтрЖР = Новый Структура;
ФильтрЖР.Вставить("ДатаНачала", НачалоДня(ПериодНачала));
ФильтрЖР.Вставить("ДатаОкончания", КонецДня(ПериодОкончания));

ЗаписьФайла = Новый ЗаписьТекста("C:\Export\LogData.csv", КодировкаТекста.UTF8);
// Записываем заголовок CSV
ЗаписьФайла.ЗаписатьСтроку("Дата;Пользователь;Событие;ПредставлениеДанных;Комментарий");

ТекущаяДатаСреза = НачалоДня(ПериодНачала);
Пока ТекущаяДатаСреза <= КонецДня(ПериодОкончания) Цикл
    ФильтрЖР.ДатаНачала = ТекущаяДатаСреза;
    ФильтрЖР.ДатаОкончания = КонецДня(ТекущаяДатаСреза);
    
    ВременнаяТаблицаЖР = Новый ТаблицаЗначений;
    // Обязательно указываем только нужные колонки для экономии памяти
    ВыгрузитьЖурналРегистрации(ВременнаяТаблицаЖР, ФильтрЖР, "Дата, Пользователь, Событие, ПредставлениеДанных, Комментарий");
    
    Для Каждого СтрЛога Из ВременнаяТаблицаЖР Цикл
        ТекстСтроки = СтрШаблон("%1;%2;%3;%4;%5", 
            Формат(СтрЛога.Дата, "ДФ=yyyy-MM-dd HH:mm:ss"),
            СтрЛога.Пользователь,
            СтрЛога.Событие,
            СтрЗаменить(СтрЛога.ПредставлениеДанных, ";", ","),
            СтрЗаменить(СтрЛога.Комментарий, ";", ",")
        );
        ЗаписьФайла.ЗаписатьСтроку(ТекстСтроки);
    КонецЦикла;
    
    ВременнаяТаблицаЖР.Очистить();
    ТекущаяДатаСреза = ТекущаяДатаСреза + 86400; // переход к следующим суткам
КонецЦикла;

ЗаписьФайла.Закрыть();

Потоковая запись позволяет выгрузить 700 000 строк за считанные минуты, так как объем оперативной памяти фиксирован размером суточной порции записей.

Способ 2. Прямая выгрузка в XML штатным методом платформы

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


ФильтрЖР = Новый Структура;
ФильтрЖР.Вставить("ДатаНачала", ПериодНачала);
ФильтрЖР.Вставить("ДатаОкончания", ПериодОкончания);

// Передаем путь к файлу XML вместо ТаблицыЗначений
ВыгрузитьЖурналРегистрации("C:\Export\EventLogExport.xml", ФильтрЖР, "Дата, Пользователь, Событие, ПредставлениеДанных");

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

Способ 3. Использование инструментов разработчика (ИР) и консоли отчетов

Если требуется интерактивный анализ без ручного написания обработок, рекомендуется использовать специализированные внешние инструменты:

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

Способ 4. Прямой доступ к файлу базы журнала регистрации (SQLite)

В современных версиях платформы 1С при использовании нового (единого) формата журнала регистрации логи хранятся в файле 1Cv8.lgd, который представляет собой стандартную базу данных SQLite. К этому файлу можно обратиться напрямую:

  1. Файл 1Cv8.lgd находится в каталоге журнала регистрации на сервере 1С:Предприятия.
  2. К нему можно подключиться через любые утилиты для работы с SQLite, скрипты на Python или механизм Power Query в Microsoft Excel.
  3. С помощью обычного SQL-запроса с условиями по полям даты и типа события можно быстро отобрать и экспортировать нужный объем строк напрямую, не создавая никакой нагрузки на рабочий сервер 1С.

Для старого разделенного формата журнала (файлы .lgp и .lgf) аналогичный результат достигается прямым парсингом текстовых файлов с помощью скриптов.

← На главную