К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как записать файл в 1С программно

Как программно записать файл в 1С: методы ЗаписьТекста, ЗаписьXML, двоичные данные, работа с кодировкой и путями. Примеры кода, ошибки и проверка результата.

Запись файла программно — одна из базовых задач при разработке и доработке конфигураций 1С: выгрузка данных в CSV или XML, формирование отчётов для сторонних систем, сохранение логов обмена, экспорт печатных форм. Встроенный язык 1С предоставляет несколько объектов для записи файлов, и выбор конкретного зависит от типа данных, требуемой кодировки и места выполнения кода — на клиенте или на сервере.

Ключевая особенность, которую часто упускают начинающие разработчики: код, выполняемый на сервере 1С, не имеет доступа к диску компьютера пользователя, а клиентский код не видит файловую систему сервера. Поэтому перед записью файла нужно чётко понимать, где выполняется процедура и где должен оказаться результат. Игнорирование этого правила — причина большинства ошибок «файл не найден» и «нет доступа к каталогу».

Ниже разобраны основные объекты записи (ЗаписьТекста, ЗаписьXML, ДвоичныеДанные, ЗаписьДанных), работа с кодировками, передача файла с сервера на клиент, проверка результата и типичные ошибки с готовыми примерами кода на встроенном языке.

Какие объекты 1С используются для записи файлов

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

Основные варианты:

  • ЗаписьТекста — текстовые файлы любого формата: CSV, TXT, JSON, логи. Позволяет задать кодировку, разделитель строк и запись порциями.
  • ЗаписьXML — корректное формирование XML-документов с контролем структуры тегов.
  • ДвоичныеДанные — запись любых файлов как массива байтов: картинки, PDF, архивы, Excel.
  • ЗаписьДанных — низкоуровневая запись байтов и буферов, нужна редко, в основном для потоковой обработки.
  • ТекстовыйДокумент.Записать() и ТабличныйДокумент.Записать() — когда данные уже находятся в соответствующем объекте.

Сравнение способов записи

ЗаписьТекста

Подходит для CSV, JSON, логов. Контроль кодировки и построчная запись. Не подходит для бинарных данных.

ЗаписьXML

Гарантирует валидный XML с закрывающими тегами. Избыточен для простого текста.

ДвоичныеДанные

Единственный способ записать картинку, PDF или архив. Требует, чтобы содержимое уже было в виде байтов.

ТабличныйДокумент.Записать()

Быстрый экспорт печатной формы в Excel, PDF, HTML. Ограничен форматами, поддерживаемыми платформой.

Запись текстового файла через ЗаписьТекста

Объект ЗаписьТекста — самый востребованный инструмент. Типовой сценарий: создать объект, указать путь и кодировку, записать строки, закрыть файл. Если не вызвать метод Закрыть(), данные могут остаться в буфере и файл окажется пустым или неполным.

ЗаписьТекста = Новый ЗаписьТекста("C:\Обмен\выгрузка.csv", КодировкаТекста.UTF8);

ЗаписьТекста.ЗаписатьСтроку("Номенклатура;Цена;Количество");

Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл

СтрокаФайла = СтрокаТовара.Наименование + ";"

+ Формат(СтрокаТовара.Цена, "ЧРД=.") + ";"

+ Формат(СтрокаТовара.Количество, "ЧГ=");

ЗаписьТекста.ЗаписатьСтроку(СтрокаФайла);

КонецЦикла;

ЗаписьТекста.Закрыть();

Кодировку лучше указывать явно. Если её не задать, платформа использует кодировку по умолчанию, и на другом компьютере кириллица может превратиться в нечитаемые символы. Для обмена с внешними системами чаще всего подходит UTF-8, для старых программ — ANSI (Windows-1251).

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

Запись XML и выгрузка структурированных данных

Для формирования XML ручная сборка строк через ЗаписьТекста — плохая практика: легко забыть закрывающий тег или экранировать спецсимволы. Объект ЗаписьXML контролирует структуру автоматически и при закрытии завершает все незакрытые элементы.

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.ОткрытьФайл("C:\Обмен\заказы.xml");

ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("Заказы");

Для Каждого Заказ Из СписокЗаказов Цикл

ЗаписьXML.ЗаписатьНачалоЭлемента("Заказ");

ЗаписьXML.ЗаписатьАтрибут("Номер", Заказ.Номер);

ЗаписьXML.ЗаписатьЭлемент("Дата", Формат(Заказ.Дата, "ДФ=yyyy-MM-dd"));

ЗаписьXML.ЗаписатьЭлемент("Сумма", Формат(Заказ.Сумма, "ЧРД=."));

ЗаписьXML.ЗаписатьКонецЭлемента();

КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.Закрыть();

Альтернатива для обмена между информационными базами 1С — сериализация через ЗаписьXML в связке со встроенными средствами XDTO или функцией ЗаписатьXML(), которая сохраняет объекты конфигурации напрямую. Это удобно для переноса данных между базами с одинаковой структурой, но такой файл будет привязан к формату платформы.

Запись двоичных файлов: картинки, PDF, архивы

Когда нужно сохранить не текст, а готовый файл — изображение из базы, PDF-документ, архив, — используются ДвоичныеДанные. Чаще всего источником служит хранилище значения в реквизите объекта или временное хранилище.

// Сохранение файла из хранилища значения

ДвоичныеДанные = Объект.ФайлХранилище.Получить();

Если ДвоичныеДанные <> Неопределено Тогда

ДвоичныеДанные.Записать("C:\Файлы\" + Объект.ИмяФайла);

КонецЕсли;

Табличный документ (печатная форма) записывается напрямую своим методом Записать() с указанием типа файла: ТипФайлаТабличногоДокумента.PDF, XLSX, HTML и другие. Это самый простой способ программно сформировать PDF-отчёт и положить его в каталог или отправить по почте.

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

Клиент и сервер: где физически окажется файл

Это самый важный раздел для практики. В клиент-серверном режиме код с директивой &НаСервере выполняется на сервере 1С, и путь «C:\Обмен\...» указывает на диск сервера, а не компьютера пользователя. Пользователь файл на своей машине не увидит.

Стандартный приём передачи файла с сервера клиенту — поместить данные во временное хранилище и получить их на клиенте:

&НаСервере

Функция СформироватьФайлНаСервере()

ЗаписьТекста = Новый ЗаписьТекста(

ПолучитьИмяВременногоФайла("csv"), КодировкаТекста.UTF8);

// ... запись данных ...

ЗаписьТекста.Закрыть();

ДвоичныеДанные = Новый ДвоичныеДанные(ЗаписьТекста.ИмяФайла);

Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

КонецФункции

&НаКлиенте

Процедура СохранитьФайл(Команда)

Адрес = СформироватьФайлНаСервере();

ПолучитьФайл(Адрес, "выгрузка.csv", Истина);

КонецПроцедуры

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

Проверка результата и обработка ошибок

Запись файла может завершиться неудачно: нет прав, диск переполнен, путь занят другим процессом, антивирус заблокировал операцию. Код, который молча продолжает работу после неудачной записи, создаёт скрытые проблемы — например, обмен «отработал», а файл пустой.

Минимальный каркас надёжной записи:

Попытка

ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);

ЗаписьТекста.ЗаписатьСтроку(СодержимоеФайла);

ЗаписьТекста.Закрыть();

Исключение

ЗаписьЖурналаРегистрации("Запись файла",

УровеньЖурналаРегистрации.Ошибка, , ,

ОписаниеОшибки());

ВызватьИсключение "Не удалось записать файл: " + ИмяФайла;

КонецПопытки;

// Проверка результата

Файл = Новый Файл(ИмяФайла);

Если Не Файл.Существует() Или Файл.Размер() = 0 Тогда

ВызватьИсключение "Файл не создан или пуст: " + ИмяФайла;

КонецЕсли;

Контрольные точки

Как проверить результат

Существование файла
Норма

Новый Файл(ИмяФайла).Существует() возвращает Истина

Тревожный признак

Файла нет — проверяйте путь, права и контекст выполнения

Размер файла
Норма

Размер больше нуля и соответствует объёму данных

Тревожный признак

Нулевой размер — данные не записаны или не вызван Закрыть()

Содержимое
Норма

Файл открывается в целевой программе, кириллица читается

Тревожный признак

Крякозябры — несовпадение кодировки записи и чтения

Права доступа
Норма

Запись выполняется под учётной записью службы сервера 1С

Тревожный признак

Ошибка доступа — у учётной записи нет прав на каталог

Типичные ошибки при записи файлов в 1С

Большинство проблем с записью файлов повторяются от проекта к проекту и легко предотвращаются, если знать о них заранее.

Типичные ошибки
01
Не вызван метод Закрыть() — файл остаётся пустым или заблокированным для других процессов до завершения сеанса.
02
Кодировка не указана — на сервере с другой локалью кириллица превращается в нечитаемые символы.
03
Запись на клиенте в серверном коде или наоборот — файл создаётся не на том компьютере, пользователь его не находит.
04
Абсолютный путь прошит в коде — после переезда базы на другой сервер обмен перестаёт работать.
05
Исключения не обрабатываются — обмен молча завершается без файла, ошибка обнаруживается через дни.
06
Имя файла содержит недопустимые символы из наименований объектов (\/:*?"<>|) — конструктор ЗаписьТекста выдаёт ошибку.

Отдельно стоит упомянуть одновременный доступ: если два фоновых задания пишут в один файл, результат непредсказуем. Используйте уникальные имена (например, с добавлением даты-времени или GUID через Новый УникальныйИдентификатор) либо блокировки.

При регулярных выгрузках удобно формировать имя файла с меткой времени: "orders_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".csv". Это исключает перезапись, упрощает поиск нужной выгрузки и позволяет хранить историю обменов для разбора расхождений.
ПЗ
Практическое замечание

Частые вопросы

Как записать файл в 1С без диалога выбора у пользователя?

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

В какой кодировке лучше записывать файлы для обмена?

Оптимальный выбор — UTF-8: эту кодировку корректно читают практически все современные системы. Исключение — интеграции со старым ПО, которое понимает только Windows-1251 (КодировкаТекста.ANSI). Главное правило: кодировка записи должна совпадать с кодировкой, которую ожидает принимающая сторона.

Почему файл создаётся пустым?

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

Как дописать данные в существующий файл, не стирая его?

Передайте в конструктор ЗаписьТекста параметр дозаписи: Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8, , Истина). Альтернатива — метод Открыть() с флагом дозаписи. Учтите, что перед добавлением строки в CSV может понадобиться проверить наличие перевода строки в конце файла.

Как сохранить файл, полученный из интернета или по HTTP?

При получении данных через HTTPЗапрос укажите в методе Получить() имя файла — ответ сохранится на диск напрямую. Либо получите тело ответа как двоичные данные методом ПолучитьТелоКакДвоичныеДанные() и запишите их методом Записать(). Для текстовых ответов (JSON, XML) обычно удобнее обработать строку без промежуточного файла.

Можно ли записать файл на сетевой ресурс?

Да, если указать UNC-путь вида \\Сервер\ОбщаяПапка\файл.csv. Критично, чтобы учётная запись, под которой работает служба агента сервера 1С, имела права на запись в эту папку. Ошибки доступа к сетевым ресурсам — одна из самых частых причин сбоев обменов в клиент-серверном режиме.

Итог

Что важно запомнить

Выбирайте объект записи по типу данных: ЗаписьТекста для текста, ЗаписьXML для XML, ДвоичныеДанные для готовых файлов. Всегда указывайте кодировку, вызывайте Закрыть(), обрабатывайте исключения и помните про разделение клиента и сервера — файл пишется на том компьютере, где выполняется код. Проверка существования и размера файла после записи избавит от скрытых сбоев обмена.