Как записать большое количество файлов на клиенте без блокировки интерфейса в 1С?

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

При разработке внешних обработок или сложных отчетов часто возникает задача массового сохранения документов. Типичный пример — формирование сотни табличных документов и их экспорт в формат PDF на локальный диск пользователя. Основная проблема заключается в том, что клиентское приложение 1С является однопоточным. Если выполнять запись «в лоб» через цикл, интерфейс программы замирает, и пользователь не может продолжать работу, пока все файлы не будут обработаны. Рассмотрим подробнее, как решить эту проблему, используя современные механизмы платформы и БСП.

Анализ причин медленной работы

Прежде чем переходить к коду, разберем, почему процесс занимает много времени. Основная нагрузка ложится не на саму операцию записи на диск, а на процесс конвертации объекта ТабличныйДокумент в формат PDF. Этот процесс требует значительных вычислительных ресурсов процессора. Если выполнять его на стороне клиента, то весь сеанс пользователя блокируется до завершения последней итерации цикла.

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

Решение 1: Перенос формирования на сервер и фоновое выполнение

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

  1. Пользователь нажимает кнопку «Сформировать».
  2. На сервере запускается фоновое задание через механизм БСП ДлительныеОперации.
  3. Фоновое задание формирует табличные документы, сохраняет их в PDF во временные файлы на сервере и помещает их во ВременноеХранилище.
  4. Клиент получает массив адресов временного хранилища и выполняет итоговую запись на диск.

Проанализируем пример кода для запуска фонового задания:


// На клиенте
ПараметрыЗадания = Новый Структура("СписокДокументов", Объект.ДокументыКПечати);
РезультатЗадания = ДлительныеОперации.ЗапуститьВыполнениеВФоне(УникальныйИдентификатор, 
    "МойМодульСервер.СформироватьФайлыPDF", ПараметрыЗадания, "Подготовка файлов PDF");

// Запускаем ожидание через стандартные механизмы БСП
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
ДлительныеОперацииКлиент.ОжидатьЗавершение(РезультатЗадания, 
    Новый ОписаниеОповещения("ЗавершитьПодготовкуФайлов", ЭтотОбъект), ПараметрыОжидания);

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

Решение 2: Пакетное получение файлов методом ПолучитьФайлы

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

Рассмотрим, как подготовить описание передаваемых файлов:


МассивФайловДляПередачи = Новый Массив;
Для Каждого СтрокаФайла Из ПодготовленныеДанные Цикл
    // ОписаниеПередаваемогоФайла(ПутьНаКлиенте, АдресВоВременномХранилище)
    Описание = Новый ОписаниеПередаваемогоФайла(СтрокаФайла.ИмяФайлаНаДиске, СтрокаФайла.АдресХранилища);
    МассивФайловДляПередачи.Добавить(Описание);
КонецЦикла;

// Выполняем групповое получение без интерактивного диалога для каждого файла
ПолучитьФайлы(МассивФайловДляПередачи, , Ложь);

Использование этого метода оптимизирует трафик и минимизирует количество блокирующих операций на клиенте в момент передачи данных.

Решение 3: Асинхронные методы записи

В современных версиях платформы (8.3.18+) 1С активно внедряет асинхронную модель. Если ваша конфигурация позволяет, вместо Записать() следует использовать ЗаписатьАсинхронно(). Это не ускорит конвертацию PDF как таковую, но позволит операционной системе и платформе управлять потоками более эффективно, не замораживая отрисовку интерфейса.

Пример использования асинхронного вызова для табличного документа:


// Пример для платформы 8.3.18+
Ждать ТабДок.ЗаписатьАсинхронно(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);

Это делает код более чистым и современным, позволяя избежать устаревших конструкций с ОписаниеОповещения в простых сценариях.

Решение 4: Архивация на сервере

Если файлов действительно очень много (тысячи), то даже пакетная передача может занять время. В этом случае рассмотрим вариант с созданием ZIP-архива на сервере. Мы упаковываем все PDF-файлы в один архив, передаем один файл на клиент и там же его распаковываем.

Выясним причину, почему это эффективно: во-первых, сжатие PDF (если внутри много текста) уменьшает объем передаваемых данных. Во-вторых, операционной системе гораздо проще скопировать один файл размером 100 Мб, чем 1000 файлов по 100 Кб, из-за особенностей работы файловых таблиц (MFT в NTFS).

Распаковку на клиенте можно выполнить как средствами встроенного объекта ЧтениеZipФайла, так и через запуск внешнего приложения (например, системного архиватора) в фоновом режиме, чтобы не блокировать 1С.

Оптимизация самого Табличного Документа

Иногда корень проблемы кроется в самом макете. Проанализируем ситуацию: если запись одного листа занимает 5 секунд, то 100 листов — это уже более 8 минут. Чтобы ускорить ТабличныйДокумент.Записать(..., PDF), придерживайтесь следующих правил:

  1. Шрифты: Старайтесь использовать стандартные шрифты (Arial, Times New Roman). При записи в PDF 1С встраивает шрифты в файл. Необычные шрифты увеличивают размер файла и время обработки.
  2. Картинки: Огромные логотипы высокого разрешения в шапке документа — главный враг производительности. Уменьшите разрешение картинок до 72-96 DPI перед вставкой в макет.
  3. Автомасштаб: Отключите свойство Автомасштаб. Если оно включено, платформе приходится делать предварительный рендеринг для расчета коэффициента сжатия, что замедляет экспорт. Лучше заранее рассчитать ширину колонок под формат A4.

Влияние антивирусов

При массовой записи файлов на диск часто срабатывает монитор антивируса, который проверяет каждый новый PDF-файл. Это может замедлить процесс в несколько раз. Если вы столкнулись с аномальными тормозами именно в момент записи на клиенте, попробуйте временно отключить антивирус для теста. В качестве технического решения можно записывать файлы в специализированную временную директорию, которая добавлена в исключения антивирусного ПО, а затем перемещать их в целевую папку.

Подводя итог, можно сказать, что «золотой стандарт» решения данной задачи — это подготовка данных в фоновом задании на сервере с последующей пакетной передачей через ПолучитьФайлы. Это обеспечивает наилучший пользовательский опыт и стабильную работу системы.

← На главную