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

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

Как работать с текстовым файлом в 1С

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

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

Выбор инструмента зависит от размера файла и сценария. Если файл небольшой (до нескольких мегабайт), удобно загрузить его целиком через ТекстовыйДокумент. Если файл большой — сотни мегабайт логов или выгрузок, — правильнее читать его построчно через ЧтениеТекста, чтобы не исчерпать память сервера или клиента.

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

Объект ЧтениеТекста: читаем файл построчно

Объект ЧтениеТекста предназначен для последовательного чтения файла. Он не загружает всё содержимое в память, поэтому подходит для файлов любого размера. Типовой цикл чтения выглядит так: открыть файл, в цикле читать строки до тех пор, пока метод ПрочитатьСтроку() не вернёт Неопределено, затем закрыть файл.

Чтение = Новый ЧтениеТекста;

Чтение.Открыть("C:\Обмен\price.txt", КодировкаТекста.UTF8);

Строка = Чтение.ПрочитатьСтроку();

Пока Строка <> Неопределено Цикл

// обработка строки

Строка = Чтение.ПрочитатьСтроку();

КонецЦикла;

Чтение.Закрыть();

Метод ПрочитатьСтроку() возвращает строку без символа перевода строки. Когда данные закончились, возвращается Неопределено — это и есть условие выхода из цикла. Частая ошибка новичков — сравнивать результат с пустой строкой: пустая строка в файле — это валидное значение (пустая строка между блоками данных), и цикл по такому условию завершится преждевременно.

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

Объект ЗаписьТекста: создаём и дописываем файл

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

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

Запись.Открыть("C:\Обмен\export.txt", КодировкаТекста.UTF8);

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

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

КонецЦикла;

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

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

Кодировки: UTF-8, ANSI и символ BOM

Кодировка — самая частая причина «кракозябр» при обмене файлами. В 1С она задаётся перечислением КодировкаТекста: UTF8, ANSI (Windows-1251 для русского языка), OEM (DOS, CP866), UTF16 и другие. Правило простое: кодировка при чтении должна совпадать с кодировкой, в которой файл был записан.

Если кодировка файла неизвестна, можно открыть его без указания кодировки — платформа попытается определить её автоматически по сигнатуре BOM (byte order mark) в начале файла. Но если BOM отсутствует, автоопределение ненадёжно: файл в ANSI может быть ошибочно прочитан как UTF-8, и кириллица превратится в мусор.

При записи файлов для внешних систем уточняйте, нужен ли BOM. Некоторые старые системы не понимают UTF-8 с BOM и требуют «чистый» UTF-8 или ANSI. В 1С запись UTF-8 по умолчанию добавляет BOM; поведение зависит от способа открытия файла, поэтому результат стоит проверить, открыв готовый файл в редакторе, который показывает кодировку (например, Notepad++).

ТекстовыйДокумент: работа с файлом целиком

Объект ТекстовыйДокумент загружает файл в память полностью и даёт удобный доступ к строкам по индексу: КоличествоСтрок(), ПолучитьСтроку(Номер), ДобавитьСтроку(), ВставитьСтроку(), УдалитьСтроку(). Это удобно, когда нужно редактировать файл произвольно — например, вставить строку в середину или удалить дубликаты.

Док = Новый ТекстовыйДокумент;

Док.Прочитать("C:\Обмен\price.txt", КодировкаТекста.UTF8);

Для Н = 1 По Док.КоличествоСтрок() Цикл

Стр = Док.ПолучитьСтроку(Н);

// обработка

КонецЦикла;

Док.Записать("C:\Обмен\price_new.txt", КодировкаТекста.UTF8);

Ограничение очевидно: весь файл должен поместиться в память. Для файлов в десятки мегабайт это обычно не проблема, но для выгрузок в сотни мегабайт используйте ЧтениеТекста. Также помните, что нумерация строк в ТекстовыйДокумент начинается с 1, а не с 0.

Сравнение вариантов

ЧтениеТекста / ЗаписьТекста

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

ТекстовыйДокумент

Файл целиком в памяти, произвольный доступ к строкам по номеру, удобное редактирование. Не подходит для очень больших файлов.

ЧтениеXML / ЧтениеJSON

Если файл структурированный (XML, JSON), разбирайте его специализированными объектами, а не как обычный текст — так надёжнее и проще.

Разбор строк: разделители и структура данных

Чаще всего текстовый файл — это набор строк с полями, разделёнными точкой с запятой, табуляцией или вертикальной чертой. Встроенной функции split в языке 1С нет, поэтому разбор делают через СтрРазделить() (доступна в современных версиях платформы) или самописную функцию на базе СтрНайти().

Строка = Чтение.ПрочитатьСтроку();

Пока Строка <> Неопределено Цикл

Поля = СтрРазделить(Строка, ";");

Если Поля.Количество() >= 3 Тогда

Артикул = СокрЛП(Поля[0]);

Наименование = СокрЛП(Поля[1]);

Цена = Число(СтрЗаменить(Поля[2], ",", "."));

КонецЕсли;

Строка = Чтение.ПрочитатьСтроку();

КонецЦикла;

Обратите внимание на защитные приёмы в примере: проверка количества полей перед обращением по индексу, СокрЛП() для удаления пробелов, замена запятой на точку перед преобразованием в число. Реальные файлы от контрагентов почти всегда содержат «грязные» данные — пропущенные поля, лишние пробелы, смешанные разделители дробной части. Преобразование Число() на некорректном значении вызовет исключение, поэтому либо оборачивайте его в попытку, либо предварительно проверяйте строку.

Порядок действий при загрузке файла
  1. 1
    Определите кодировку файла и разделитель полей, открыв файл в текстовом редакторе
  2. 2
    Напишите цикл чтения через ЧтениеТекста с проверкой на Неопределено
  3. 3
    Добавьте разбор строки на поля с проверкой их количества
  4. 4
    Обработайте данные: поиск или создание элементов справочников, запись документов
  5. 5
    Закройте файл и выведите пользователю итог: сколько строк обработано, сколько пропущено с ошибками

Работа с файлами на сервере и в тонком клиенте

В клиент-серверном режиме важно понимать, где физически находится файл. Код, выполняющийся на сервере (директива &НаСервере), видит только файловую систему сервера. Файл, который пользователь выбрал на своём компьютере, серверу недоступен напрямую.

Стандартный приём — передать файл на сервер через временное хранилище. На клиенте файл помещается в хранилище методом НачатьПомещениеФайла(), на сервере данные извлекаются из хранилища, сохраняются во временный файл (ПолучитьИмяВременногоФайла()) и обрабатываются. Обратная схема работает для выгрузки: сервер формирует файл, помещает его в хранилище, клиент сохраняет через диалог.

Для выбора файла пользователем используйте ДиалогВыбораФайла с режимом РежимДиалогаВыбораФайла.Открытие или Сохранение. В тонком и веб-клиенте для работы с файловой системой может потребоваться расширение работы с файлами — платформа сама предложит его установить при первом обращении.

Типичные ошибки
01
Не закрыт файл после обработки — файл остаётся заблокированным, и следующая попытка записи завершается ошибкой
02
Сравнение результата ПрочитатьСтроку() с пустой строкой вместо Неопределено — цикл обрывается на первой пустой строке файла
03
Чтение файла в ANSI как UTF-8 или наоборот — кириллица превращается в нечитаемые символы
04
Обращение к файлу на диске C: из серверного кода — сервер ищет файл на своём диске, а не на компьютере пользователя
05
Отсутствие обработки исключений — одна битая строка в файле обрывает всю загрузку без пояснения причины

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

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

Перед чтением полезно проверить существование файла через объект Файл: Новый Файл(ИмяФайла).Существует(). Это позволяет отличить ситуацию «файла нет» от «файл есть, но не читается» и дать пользователю точную подсказку.

После записи файла проверьте результат: откройте файл в редакторе, убедитесь, что кодировка правильная, первая и последняя строки на месте, нет обрезанных данных. Для регламентных выгрузок полезно вести счётчики: сколько строк записано, сколько пропущено и почему — это сильно упрощает разбор претензий получателя файла.

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

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

Кодировка выгруженного файла
Норма

Редактор показывает ожидаемую кодировку, кириллица читается

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

Вместо русских букв «кракозябры» или знаки вопроса

Полнота выгрузки
Норма

Количество строк в файле совпадает с количеством обработанных записей с учётом заголовка

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

Файл обрывается посередине данных или последняя строка неполная

Чтение загруженных данных
Норма

Все строки файла обработаны, счётчик ошибок равен нулю или все ошибки объяснены

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

Часть строк пропущена без сообщений, итоговые суммы не сходятся с источником

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

Как прочитать файл, если неизвестна его кодировка?

Откройте файл без указания кодировки — платформа попробует определить её по BOM. Если сигнатуры нет, переберите варианты вручную: чаще всего это UTF-8 или ANSI (Windows-1251). Практический способ — открыть файл в Notepad++, который показывает кодировку в строке состояния, и затем указать её в коде явно.

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

Используйте конструктор с параметром добавления: Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8, , Истина). Четвёртый параметр со значением Истина включает режим дозаписи. Метод Открыть() для существующего файла, наоборот, полностью очищает его содержимое.

Почему файл не удаётся открыть — ошибка «файл занят»?

Файл открыт другой программой (например, Excel или блокнотом) или не был закрыт в предыдущем сеансе работы 1С из-за ошибки в коде. Закройте файл во всех программах, а в коде убедитесь, что метод Закрыть() вызывается всегда, в том числе в блоке Исключение.

Как прочитать CSV-файл с запятыми внутри полей?

Простое разделение через СтрРазделить() не подойдёт: запятая внутри кавычек будет ошибочно принята за разделитель. Нужен парсер, который учитывает кавычки, — либо собственная функция посимвольного разбора, либо готовые библиотеки. Альтернатива — договориться с источником о разделителе, который не встречается в данных, например о вертикальной черте.

Можно ли работать с текстовым файлом в веб-клиенте?

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

Чем читать очень большой файл, который не помещается в память?

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

Итог

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

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