В практике разработчика 1С часто возникает задача массового формирования печатных форм. Это может быть выгрузка инвентарных карточек, прайс-листов для разных контрагентов или актов сверки. Главная сложность здесь заключается не в самой печати, а в организации процесса автоматического сохранения каждого документа в отдельный файл с уникальным именем в заданную директорию. Разберем этот процесс подробно, изучим нюансы работы с путями и форматами файлов.
Для начала проанализируем базовый инструмент, который предоставляет платформа 1С для решения нашей задачи. У объекта ТабличныйДокумент существует встроенный метод Записать(). Многие начинающие разработчики полагают, что этот метод работает только с уже существующими файлами на диске. Однако это не так.
Метод Записать() принимает два основных параметра: полное имя файла (путь вместе с расширением) и тип файла. Если по указанному пути файла не существует, система создаст его автоматически. Рассмотрим простейший пример кода:
ТабличныйДокумент = Новый ТабличныйДокумент;
// Здесь происходит заполнение документа данными
// ...
ПутьКФайлу = "D:\MyFiles\Inventory_Card_001.xls";
ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLS);
В данном случае, если папка MyFiles на диске D: существует, 1С создаст файл и запишет в него содержимое табличного документа в формате Excel 97-2003.
Выясним, как сделать так, чтобы программа сама генерировала имена для сотен разных документов. Вместо использования жестко заданной строки (константы), мы будем собирать путь к файлу из переменных. Чаще всего для уникальности используют такие реквизиты объектов, как ИнвентарныйНомер, Код или Артикул.
Разберем по шагам алгоритм циклического сохранения документов:
Записать().Посмотрим на пример реализации этой логики:
БазовыйКаталог = "D:\ExportOC\";
Выборка = Справочники.ОсновныеСредства.Выбрать();
Пока Выборка.Следующий() Цикл
// Формируем печатную форму (функция СформироватьКарточку должна возвращать ТабличныйДокумент)
ТабДок = СформироватьКарточку(Выборка.Ссылка);
// Очищаем наименование от недопустимых символов (/\:*?"<>|)
ИмяФайла = Выборка.ИнвентарныйНомер + "_" + Выборка.Наименование;
ИмяФайла = СтрЗаменить(ИмяФайла, "/", "-");
ИмяФайла = СтрЗаменить(ИмяФайла, "\", "-");
ПолныйПуть = БазовыйКаталог + ИмяФайла + ".xlsx";
// Сохраняем файл
Попытка
ТабДок.Записать(ПолныйПуть, ТипФайлаТабличногоДокумента.XLSX);
Исключение
Сообщить("Не удалось сохранить файл для: " + Выборка.Наименование + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Проанализируем ситуацию, когда указанного каталога на диске еще не существует. Метод Записать() выдаст ошибку, если путь к папке невалиден. Чтобы этого избежать, перед выполнением операции сохранения необходимо убедиться в наличии директории или создать её программно.
Для этого в 1С предусмотрена функция СоздатьКаталог(). Рассмотрим правильный подход к подготовке рабочего пространства:
РабочийПуть = "C:\Reports\2023\October\";
ФайлНаДиске = Новый Файл(РабочийПуть);
Если Не ФайлНаДиске.Существует() Тогда
СоздатьКаталог(РабочийПуть);
КонецЕсли;
Важно помнить: если ваш код выполняется на стороне сервера (например, в фоновом задании), то пути типа C:\Reports\ будут относиться к файловой системе сервера, а не вашего локального компьютера. Учетная запись, под которой запущена служба 1C:Enterprise Server, должна обладать правами "Запись" и "Изменение" для целевой папки.
При сохранении табличного документа важно правильно выбрать значение перечисления ТипФайлаТабличногоДокумента. Рассмотрим два наиболее популярных варианта для работы с Excel:
Мы рекомендуем использовать ТипФайлаТабличногоДокумента.XLSX для всех новых разработок, так как это минимизирует риски потери данных при больших объемах выгрузки.
Часто задача звучит так: "Сформировать отчет на сервере, но сохранить его в папку, которую выберет пользователь на своем ПК". Напрямую метод Записать() с сервера до диска пользователя не "дотянется".
В этом случае мы используем следующий алгоритм:
ТабличныйДокумент на сервере.ПолучитьИмяВременногоФайла().ВременноеХранилище.ПолучитьФайл() или ПолучитьФайлы().Пример кода для клиентской части (управляемая форма):
&НаКлиенте
Процедура ВыгрузитьИСохранить()
АдресФайлаВоХранилище = СформироватьФайлНаСервере();
ПараметрыПолучения = Новый ПараметрыПолученияФайлов(Истина); // Истина - запросить путь у пользователя
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла("Отчет.xlsx", АдресФайлаВоХранилище);
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(ОписаниеФайла);
НачатьПолучениеФайлов(,, МассивФайлов, ПараметрыПолучения);
КонецПроцедуры
Если нам необходимо сохранить тысячи файлов, операция может занять значительное время. Чтобы интерфейс программы не "зависал", и пользователь мог продолжать работу, рассмотрим рекомендации по оптимизации:
Фоновые задания: Выносите тяжелые процессы выгрузки в фоновые задания. Это позволит серверу обрабатывать данные в отдельном потоке.
Отключение итогов: При формировании огромных табличных документов отключайте автоматический расчет итогов и вывод сетки, если они не нужны, это ускорит процесс заполнения ТабДок.
PDF как альтернатива: Если инвентарные карточки нужны только для архива или печати и не требуют дальнейшего редактирования в Excel, используйте формат ТипФайлаТабличногоДокумента.PDF. Это гарантирует, что оформление документа останется идентичным на любом устройстве, а размер файла будет оптимальным.
Подводя итог, можно сказать, что программное сохранение файлов в 1С — это гибкий механизм. Главное — следить за уникальностью имен файлов, проверять существование путей на диске и учитывать контекст выполнения кода (Сервер/Клиент). Мы надеемся, что эти рекомендации помогут вам эффективно реализовать задачу любой сложности.