Архивация в ZIP средствами 1С 8.3: один файл, папка, пароль и 7-Zip
Содержание
Чтобы сжать файл в ZIP в 1С, создайте объект ЗаписьZipФайла с путём к будущему архиву, добавьте файл методом Добавить() и вызовите Записать(). Три строки кода, никаких внешних программ и COM-объектов. Работает в платформе 1С:Предприятие 8.3 на Windows и Linux.
Отдельного объекта с именем «ZipManager» в платформе нет. За архивы отвечают два встроенных объекта: ЗаписьZipФайла (создать архив
) и ЧтениеZipФайла (прочитать и распаковать). Внешние утилиты вроде 7-Zip нужны только в особых случаях, про них в конце.
Какие объекты 1С работают с ZIP-архивами
Вся работа с архивами в 1С держится на двух объектах и нескольких системных перечислениях. Их имена стоит запомнить: по ним удобно искать справку в синтакс-помощнике Конфигуратора (Справка → Синтакс-помощник, поиск по слову «Zip»).
| Объект или перечисление | Для чего нужен |
|---|---|
ЗаписьZipФайла | создаёт архив, добавляет в него файлы, записывает результат |
ЧтениеZipФайла | открывает архив, показывает список файлов, извлекает их |
МетодСжатияZIP | Сжатие (по умолчанию) или Копирование — положить без сжатия |
УровеньСжатияZIP | Минимальный, Оптимальный, Максимальный |
МетодШифрованияZIP | Zip20, AES128, AES192, AES256 |
РежимСохраненияПутейZIP | НеСохранятьПути, СохранятьОтносительныеПути, СохранятьПолныеПути |
РежимОбработкиПодкаталоговZIP | НеОбрабатывать или ОбрабатыватьРекурсивно |
Логика у ЗаписьZipФайла простая. При создании объекта вы задаёте, куда писать архив и как сжимать. Методом Добавить() накапливаете список файлов. Сам архив физически появляется на диске только после Записать().
Все параметры конструктора, кроме первого, необязательные. Если их не указать, 1С сожмёт файл методом «Сжатие» с оптимальным уровнем и без пароля. Для большинства задач этого хватает.
Как сжать один файл в ZIP: пошагово
Пример ниже упаковывает выгрузку export.xml в архив export.zip в том же каталоге. Код выполняется на сервере или в толстом клиенте — там, где лежит файл.
- Сформируйте полный путь к будущему архиву.
- Создайте
ЗаписьZipФайла, передав путь первым параметром. - Вызовите
Добавить()с полным путём к исходному файлу. - Вызовите
Записать()— архив создаётся на диске, объект закрывается. - Проверьте, что файл архива существует и не пустой.
Процедура СжатьФайлВZip(ПутьКФайлу, ПутьКАрхиву) Экспорт
Архив = Новый ЗаписьZipФайла(ПутьКАрхиву);
Архив.Добавить(ПутьКФайлу, РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Записать();
ФайлАрхива = Новый Файл(ПутьКАрхиву);
Если Не ФайлАрхива.Существует() Тогда
ВызватьИсключение "Архив не создан: " + ПутьКАрхиву;
КонецЕсли;
КонецПроцедуры
// Вызов
СжатьФайлВZip("C:\Обмен\export.xml", "C:\Обмен\export.zip");
Режим НеСохранятьПути кладёт файл в корень архива. Без него в ZIP может попасть структура папок, и получатель распакует export.xml не туда, куда ждёт.
В один архив можно добавить несколько отдельных файлов: просто вызовите Добавить() несколько раз до Записать().
Архив = Новый ЗаписьZipФайла("C:\Обмен\пакет.zip");
Архив.Добавить("C:\Обмен\товары.xml", РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Добавить("C:\Обмен\цены.xml", РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Добавить("C:\Обмен\остатки.xml", РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Записать();
Если файл с таким именем архива уже есть, ЗаписьZipФайла перезапишет его. Дописать файлы в существующий архив этим объектом нельзя: нужно распаковать старый архив и собрать новый.
Если пользователь работает в тонком клиенте
В тонком клиенте и веб-клиенте файл обычно лежит на компьютере пользователя, а код архивации удобнее выполнять на сервере. Порядок такой:
- 📤 передайте файл на сервер стандартными методами помещения файлов (
НачатьПомещениеФайлаНаСерверилиПоместитьФайлв старых конфигурациях); - 🗜️ на сервере сохраните двоичные данные во временный файл и сожмите его;
- 📥 отдайте готовый архив пользователю через временное хранилище и
НачатьПолучениеФайлаССервера.
Архивация папки с подкаталогами в ZIP
Для массовой упаковки не нужно перебирать файлы вручную. Метод Добавить() понимает маски вида * и *.xml, а флаг рекурсии заставляет 1С обойти все вложенные папки.
Процедура СжатьКаталогВZip(Каталог, ПутьКАрхиву) Экспорт
Разделитель = ПолучитьРазделительПути();
Архив = Новый ЗаписьZipФайла(ПутьКАрхиву);
Архив.Добавить(
Каталог + Разделитель + "*",
РежимСохраненияПутейZIP.СохранятьОтносительныеПути,
РежимОбработкиПодкаталоговZIP.ОбрабатыватьРекурсивно);
Архив.Записать();
КонецПроцедуры
СжатьКаталогВZip("D:\Сканы\2025", "D:\Архивы\сканы.zip");
Что дают режимы путей на практике:
| Режим | Что будет внутри архива | Когда выбирать |
|---|---|---|
НеСохранятьПути | все файлы в одной куче в корне | несколько файлов без вложенности |
СохранятьОтносительныеПути | структура подпапок от указанного каталога | архив папки целиком — основной вариант |
СохранятьПолныеПути | путь от корня диска, вроде D\Сканы\2025\... | редко, получателю обычно неудобно |
Чтобы отобрать только нужные типы, меняйте маску: "*.pdf" упакует лишь PDF. Если нужно несколько масок, вызовите Добавить() для каждой.
Не кладите архив внутрь папки, которую архивируете. При рекурсивном обходе 1С может попытаться добавить в архив сам создаваемый файл. Пишите ZIP в соседний каталог или во временный.
Ограничение по возрасту и размеру файлов
Маска не умеет фильтровать по дате или размеру. Для отбора используйте НайтиФайлы(Каталог, "*", Истина): функция вернёт массив объектов Файл. Проверьте у каждого ПолучитьВремяИзменения() или Размер() и добавьте подходящие по одному. При этом режим СохранятьОтносительныеПути для отдельных файлов уже не сохранит дерево папок так, как при добавлении каталога маской, — проверьте результат на тестовой папке.
Сжатие двоичных данных в памяти без лишних файлов
Частая задача: в реквизите или во временном хранилище лежат ДвоичныеДанные, и их нужно отдать архивом — например, приложить к письму или отправить HTTP-запросом. Временный файл на диске при этом хочется свести к минимуму.
Сам архив можно писать не в файл, а в поток ПотокВПамяти: конструктор ЗаписьZipФайла принимает поток первым параметром. Исходные данные при этом всё равно добавляются из файла, поэтому один временный файл понадобится.
Функция СжатьДвоичныеДанные(Данные, ИмяВнутриАрхива) Экспорт
// 1. Исходные данные во временный каталог под нужным именем
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ПутьКФайлу = ВременныйКаталог + ПолучитьРазделительПути() + ИмяВнутриАрхива;
Данные.Записать(ПутьКФайлу);
// 2. Архив сразу в память
Поток = Новый ПотокВПамяти;
Архив = Новый ЗаписьZipФайла(Поток);
Архив.Добавить(ПутьКФайлу, РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Записать();
Результат = Поток.ЗакрытьИПолучитьДвоичныеДанные();
// 3. Уборка
УдалитьФайлы(ВременныйКаталог);
Возврат Результат;
КонецФункции
Временный каталог здесь нужен ради имени: файл внутри архива получит то имя, под которым лежал на диске. Если записать данные прямо в ПолучитьИмяВременногоФайла("xml"), внутри ZIP окажется случайное служебное имя.
Обратная операция тоже обходится без записи архива на диск. ЧтениеZipФайла принимает поток, полученный из двоичных данных архива методом ОткрытьПотокДляЧтения():
Поток = ДанныеАрхива.ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеZipФайла(Поток);
Для Каждого Элемент Из Чтение.Элементы Цикл
Сообщить(Элемент.ПолноеИмя + " — " + Формат(Элемент.НесжатыйРазмер, "ЧГ=0") + " байт");
КонецЦикла;
Чтение.ИзвлечьВсе(КаталогДляРаспаковки, РежимВосстановленияПутейФайловZIP.Восстанавливать);
Чтение.Закрыть();
Работа с потоками в ZIP-объектах появилась не в первых версиях 8.3. Если в старой базе конструктор с ПотокВПамяти даёт ошибку, проверьте режим совместимости конфигурации и при необходимости пишите архив во временный файл, а затем читайте его в ДвоичныеДанные.
Уровень сжатия и пароль на ZIP-архив
Параметры сжатия и шифрования передаются в конструктор по порядку: путь или поток, пароль, комментарий, метод сжатия, уровень сжатия, метод шифрования.
Архив = Новый ЗаписьZipФайла(
"C:\Обмен\отчёт.zip",
"Пароль_2025!", // пароль
"Выгрузка для аудитора", // комментарий к архиву
МетодСжатияZIP.Сжатие,
УровеньСжатияZIP.Максимальный,
МетодШифрованияZIP.AES256);
Архив.Добавить("C:\Обмен\отчёт.xlsx", РежимСохраненияПутейZIP.НеСохранятьПути);
Архив.Записать();
Какой уровень сжатия выбрать
| Значение | Скорость | Размер | Когда использовать |
|---|---|---|---|
Минимальный | быстро | больше | регулярные выгрузки по расписанию, большие объёмы |
Оптимальный | средне | средний | вариант по умолчанию, подходит почти всегда |
Максимальный | медленно | меньше | отправка по почте с лимитом на вложения |
МетодСжатияZIP.Копирование | мгновенно | без изменений | JPEG, PDF, видео, уже сжатые архивы |
Текстовые форматы — XML, JSON, CSV, выгрузки .dt в виде файлов-частей — сжимаются хорошо, часто в разы. Сканы в JPEG и PDF почти не уменьшаются, и максимальный уровень на них только тратит время процессора.
Шифрование: Zip20 или AES
- 🔓
Zip20— классическое шифрование ZIP. Архив откроет даже встроенный проводник Windows, но защита слабая: её подбирают специальными программами. - 🔐
AES256— надёжный вариант для персональных данных и бухгалтерской отчётности. Минус: проводник Windows такой архив не распакует, получателю нужен 7-Zip, WinRAR или аналог.
Пароль в открытом виде в коде модуля видят все, у кого есть доступ к Конфигуратору. Храните его в защищённом хранилище или в константе с ограниченными правами, а получателю передавайте отдельным каналом.
Шифруется только содержимое файлов. Список имён файлов внутри ZIP виден без пароля — не давайте файлам говорящих имён вроде зарплата_Иванов.xlsx, если это критично.
Когда нужны 7-Zip и COM-объекты
Встроенных объектов хватает почти для всех задач. Внешний архиватор оправдан в трёх случаях:
- 📦 нужен другой формат — 7z, tar.gz, многотомный архив;
- 🏢 действует корпоративное требование к конкретной программе;
- 🧱 очень старая платформа, где ZIP-объектов ещё нет.
7-Zip вызывается из 1С командой ЗапуститьПриложение с ожиданием завершения и кодом возврата:
Команда = """C:\Program Files\7-Zip\7z.exe"" a -tzip -mx=9 ""D:\Архивы\сканы.zip"" ""D:\Сканы\2025\*""";
КодВозврата = 0;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
ВызватьИсключение "7-Zip завершился с кодом " + Формат(КодВозврата, "ЧГ=0");
КонецЕсли;
Ключи 7-Zip: a — добавить в архив, -tzip — формат ZIP, -mx=9 — максимальное сжатие (0 — без сжатия), -p — пароль, -mem=AES256 — шифрование AES для ZIP. Код 0 означает успех, 1 — предупреждение (например, часть файлов была занята), 2 и выше — ошибка.
Старый приём через COM-объект Shell.Application и «сжатую ZIP-папку» Windows лучше не использовать. Копирование в нём асинхронное: метод возвращает управление раньше, чем архив дописан, и код вынужден ждать паузами. Плюс он не работает
на сервере под Linux и в службе без интерактивного рабочего стола.
На сервере 1С внешняя программа запускается от имени пользователя службы сервера. У этой учётной записи должны быть права на запуск архиватора и на чтение и запись нужных папок. Сетевые диски, подключённые у вас в сеансе Windows, службе не видны — указывайте UNC-путь вида \\server\share.
Ошибки при архивации и как их устранить
Ещё одна неочевидная проблема — временные файлы. Если процедура упала посередине, УдалитьФайлы не выполнится, и временные каталоги копятся на сервере месяцами. Уборку ставьте в обе ветки — и после успешной записи, и в блоке Исключение.
Для фоновых заданий, которые архивируют выгрузки каждую ночь, добавьте проверку свободного места и запись размера архива в журнал регистрации. Так проблему с переполненным диском заметят по журналу, а не по жалобам пользователей утром.