Разработка и Конфигурация · 12 мин
Как записать текстовый файл в 1С
Как записать текстовый файл в 1С: методы ТекстовыйДокумент.Записать и ЗаписьТекста, кодировки, запись на сервере и клиенте, типичные ошибки и примеры кода.
Запись текстового файла — одна из базовых задач при обмене данными в 1С: выгрузка в CSV, формирование файлов обмена с банками, логирование операций, выгрузка печатных форм в плоский текст. В языке 1С есть два основных инструмента для этого: объект ТекстовыйДокумент с методом Записать() и объект ЗаписьТекста, дающий потоковую запись с контролем кодировки и разделителей строк.
Выбор инструмента зависит от объёма данных и контекста выполнения. Для небольших файлов, сформированных целиком в памяти, удобнее ТекстовыйДокумент. Для больших выгрузок, где данные пишутся порциями в цикле, правильнее использовать ЗаписьТекста — он не держит весь файл в памяти и позволяет явно управлять кодировкой и символами переноса строк.
Отдельная тема — место выполнения кода. В клиент-серверном режиме файловая система сервера и клиента различны: запись «на диск C» в серверном контексте создаст файл на сервере, а не у пользователя. Ниже разобраны оба подхода, работа с кодировками, запись на клиенте без модальных окон и типичные ошибки, из-за которых файл получается пустым, битым или не той кодировки.
Запись файла через ТекстовыйДокумент
Объект ТекстовыйДокумент хранит текст построчно в памяти. Типовой сценарий: создать объект, добавить строки методом ДобавитьСтроку(), затем одним вызовом Записать() сохранить файл на диск. Это самый короткий путь, когда содержимое файла известно целиком.
Текст = Новый ТекстовыйДокумент;
Текст.ДобавитьСтроку("Номенклатура;Цена");
Текст.ДобавитьСтроку("Кирпич М-150;25,50");
Текст.ДобавитьСтроку("Цемент М-500;340,00");
Текст.Записать("C:\Обмен\price.csv", КодировкаТекста.UTF8);
Метод Записать() принимает имя файла и необязательные параметры: тип кодировки и разделитель строк. Если кодировку не указать, будет использована кодировка по умолчанию (как правило, ANSI текущей системы), что часто приводит к «кракозябрам» при открытии файла в другой программе. Правило простое: кодировку указывайте всегда явно.
Если текст уже сформирован в виде одной строковой переменной, можно установить его через УстановитьТекст() вместо построчного добавления. Для проверки результата удобно сразу после записи прочитать файл обратно методом Прочитать() и сравнить количество строк — это быстрый способ убедиться, что запись прошла без обрезки.
Потоковая запись через ЗаписьТекста
Объект ЗаписьТекста пишет данные в файл последовательно, не накапливая их в памяти. Это правильный выбор для выгрузок в десятки и сотни тысяч строк: журналы, большие CSV, файлы обмена. Конструктор принимает имя файла, кодировку, разделитель строк и признак перезаписи существующего файла.
Запись = Новый ЗаписьТекста("C:\Обмен\выгрузка.txt",
КодировкаТекста.UTF8, Символы.ПС + Символы.ВК, Истина);
Пока Выборка.Следующий() Цикл
Запись.ЗаписатьСтроку(Выборка.Артикул + ";" + Выборка.Наименование);
КонецЦикла;
Запись.Закрыть();
Ключевой момент — обязательный вызов Закрыть() после окончания записи. Пока файл не закрыт, данные могут оставаться в буфере, а сам файл остаётся заблокированным для других процессов. Если код прервётся исключением до Закрыть(), файл окажется пустым или неполным. Поэтому запись в цикле разумно оборачивать в Попытка...Исключение с закрытием файла в обеих ветках.
Метод Записать() (без «Строку») пишет текст без добавления перевода строки — полезно, когда разделители нужно расставлять вручную. Метод ЗаписатьСтроку() добавляет перевод строки автоматически, используя разделитель, заданный в конструкторе.
- 1Создайте объект: Новый ЗаписьТекста(путь, кодировка, разделитель, перезапись)
- 2Проверьте, что каталог назначения существует, иначе будет исключение
- 3В цикле вызывайте ЗаписатьСтроку() для каждой порции данных
- 4Обязательно вызовите Закрыть(), в том числе при ошибке — через Попытка/Исключение
- 5Откройте файл и проверьте кодировку и последнюю строку
Кодировки: как не получить нечитаемый файл
Большинство проблем с записью текстовых файлов в 1С сводится к кодировке. Перечисление КодировкаТекста предлагает основные варианты: UTF8, ANSI, OEM, UTF16 и другие. Какую выбрать — определяет программа, которая будет читать файл.
Для обмена с веб-сервисами, загрузки в Excel через CSV и большинства современных систем безопасный выбор — UTF-8. Если принимающая сторона — старая DOS-программа или банк-клиент, может потребоваться OEM (866) или ANSI (Windows-1251). Требования к кодировке всегда берите из спецификации формата обмена, а не подбирайте экспериментально.
Отдельный нюанс — BOM (метка порядка байтов) в UTF-8. Некоторые системы требуют файл с BOM, другие отвергают его. В ЗаписьТекста наличием BOM можно управлять через параметр конструктора ЗаписатьBOM; в ТекстовыйДокумент.Записать() поведение зависит от версии платформы, поэтому при жёстких требованиях к BOM надёжнее использовать ЗаписьТекста.
Сравнение способов записи
Подходит для небольших файлов, сформированных целиком. Простой код, но весь текст хранится в памяти; управление BOM ограничено.
Подходит для больших выгрузок и точного контроля: кодировка, разделитель строк, BOM, дозапись. Требует обязательного Закрыть().
Нужны, когда кроме текста требуется точный контроль байтов или смешанный формат. Сложнее в коде, избыточны для обычного текста.
Запись на сервере и на клиенте: в чём разница
В файловом режиме код выполняется на компьютере пользователя, и путь C:\Обмен\file.txt означает именно его диск. В клиент-серверном режиме код с директивой &НаСервере видит файловую систему сервера 1С, а не клиентскую машину. Файл, «успешно записанный» серверным кодом, пользователь на своём компьютере не найдёт.
Типовая схема выгрузки пользователю выглядит так: серверная процедура формирует файл (например, во временном каталоге через ПолучитьИмяВременногоФайла("txt")), читает его в двоичные данные и помещает во временное хранилище через ПоместитьВоВременноеХранилище(). Клиентская процедура затем получает данные из хранилища и сохраняет локально через ПолучитьФайл() или НачатьПолучениеФайлов().
Если файл нужен только на клиенте и данные небольшие, можно сформировать текст целиком на клиенте и записать локально — в тонком клиенте для работы с файловой системой используется расширение работы с файлами, а в веб-клиенте сохранение выполняется через механизм скачивания браузера.
Проверка результата и обработка ошибок
Успешное выполнение Записать() ещё не гарантирует корректный результат. Минимальная проверка: файл существует, имеет ненулевой размер, открывается в ожидаемой кодировке, последняя строка на месте (обрезка конца файла — признак прерванной записи).
Частая причина исключений — отсутствие каталога назначения. Ни ТекстовыйДокумент.Записать(), ни ЗаписьТекста не создают промежуточные каталоги автоматически: путь должен существовать. Перед записью проверяйте каталог через объект Файл и метод Существует(), при необходимости создавайте его через СоздатьКаталог().
Каталог = Новый Файл("C:\Обмен\Выгрузки");
Если Не Каталог.Существует() Тогда
СоздатьКаталог(Каталог.ПолноеИмя);
КонецЕсли;
Вторая группа ошибок — блокировка файла другой программой (открыт в Excel, антивирус сканирует) и нехватка прав. Оборачивайте запись в Попытка...Исключение и выводите пользователю понятное сообщение с именем файла и описанием ошибки из ОписаниеОшибки() — это сильно упрощает диагностику.
Как проверить результат записи
Файл существует, размер больше нуля и растёт при повторной выгрузке
Файл отсутствует или размер 0 байт — запись не выполнилась или не вызван Закрыть()
Кириллица читается при открытии в целевой программе
Кракозябры или знаки вопроса — несовпадение кодировки записи и чтения
Последняя ожидаемая строка присутствует, число строк совпадает с выборкой
Файл обрывается на середине — запись прервана исключением
Строки корректно разделяются в целевой системе
Весь текст в одну строку или пустые строки — неверный разделитель (CR/LF/CRLF)
Типичные ошибки при записи текстовых файлов
Разбор повторяющихся проблем помогает не наступать на одни и те же грабли. Ниже — ошибки, которые встречаются чаще всего в реальных доработках.
Отдельно выделим форматирование значений. При конкатенации числа и даты в строку 1С применяет региональные настройки сеанса: разделитель дробной части, разделитель групп разрядов, формат даты. Для обменных файлов используйте функцию Формат() с явной форматной строкой, например Формат(Сумма, "ЧРД=.; ЧГ=0") и Формат(Дата, "ДФ=yyyy-MM-dd").
Как выбрать подход
FAQ: частые вопросы о записи текстовых файлов в 1С
Как дописать данные в конец существующего файла, не стирая его?
В конструкторе ЗаписьТекста четвёртый параметр отвечает за перезапись: передайте Ложь, и новые данные будут добавлены в конец файла. Альтернатива — прочитать существующий текст в ТекстовыйДокумент, добавить строки и записать файл заново, но для больших файлов это медленнее.
Почему файл создаётся, но остаётся пустым?
Чаще всего не вызван метод Закрыть() у объекта ЗаписьТекста — буфер не сброшен на диск. Вторая причина: исключение внутри цикла записи, после которого выполнение ушло в обработчик, а файл так и не был закрыт. Проверьте, что Закрыть() вызывается и в ветке Исключение.
Как записать файл в кодировке UTF-8 без BOM?
Используйте ЗаписьТекста — в его конструкторе есть параметр, управляющий записью BOM. У ТекстовыйДокумент.Записать() прямого управления BOM нет, поэтому при жёстком требовании «UTF-8 без BOM» потоковый вариант предпочтительнее.
Как сохранить файл на компьютер пользователя в клиент-серверном режиме?
Сформируйте файл на сервере во временном каталоге, прочитайте его в ДвоичныеДанные, поместите во временное хранилище и верните адрес хранилища в клиентскую процедуру. На клиенте сохраните через ПолучитьФайл() или асинхронное НачатьПолучениеФайлов() с выбором пути у пользователя.
Чем записать CSV, чтобы он корректно открылся в Excel?
Записывайте через ЗаписьТекста или ТекстовыйДокумент в кодировке UTF-8 с BOM — так Excel правильно определит кириллицу. Разделитель выбирайте по региональным настройкам целевой машины (запятая или точка с запятой), а числа форматируйте явно через Формат().
Можно ли записывать файл порциями из разных вызовов процедуры?
Да, если держать объект ЗаписьТекста открытым между вызовами — но это рискованно: при падении сеанса файл останется незакрытым. Надёжнее накапливать данные и писать одним сеансом, либо открывать файл на дозапись (параметр перезаписи — Ложь) в каждой порции и сразу закрывать.
Что важно запомнить
Небольшие файлы записывайте через ТекстовыйДокумент.Записать(), большие выгрузки — через ЗаписьТекста с обязательным Закрыть(). Всегда указывайте кодировку явно, проверяйте существование каталога, форматируйте числа и даты через Формат(), а в клиент-серверном режиме различайте файловую систему сервера и клиента.