Чтение текстовых файлов во встроенном языке 1С 8.3: код, кодировки, большие объёмы
Содержание
Прочитать TXT файл в 1С 8.3 проще всего объектом ЧтениеТекста: создаёте его с путём к файлу и кодировкой, затем вызываете ПрочитатьСтроку() в цикле, пока метод не вернёт Неопределено. Если файл небольшой и нужен целиком, хватит одной строки — Прочитать(). Для доступа к строке по номеру удобнее ТекстовыйДокумент.
Типичная ситуация: склад присылает выгрузку остатков из своей программы в виде текстового файла, и её надо разобрать в документ 1С. Ниже — рабочий код под каждый случай: маленький файл, файл на 500 МБ, «кракозябры» вместо кириллицы, файл на компьютере пользователя при работе через сервер. Всё сказанное относится к платформе 1С:Предприятие 8.3 и не зависит от конфигурации: БП, ЗУП, УТ — код одинаковый.
Чем открыть TXT в 1С: три объекта встроенного языка
У платформы есть три штатных способа прочитать текстовый файл. Они отличаются тем, сколько памяти тратят и что умеют.
| Объект | Как читает | Когда брать |
|---|---|---|
ЧтениеТекста | Построчно или целиком, потоком | Почти всегда; обязательно для больших файлов |
ТекстовыйДокумент | Загружает весь файл в память | Нужна строка по номеру, показать текст пользователю |
ДвоичныеДанные + ПолучитьСтрокуИзДвоичныхДанных() | Целиком из двоичных данных | Файл пришёл через временное хранилище или HTTP |
Самый короткий вариант — прочитать весь текст одной командой:
Чтение = Новый ЧтениеТекста("C:\Обмен\ostatki.txt", КодировкаТекста.UTF8);
ВесьТекст = Чтение.Прочитать();
Чтение.Закрыть();
Метод Прочитать() без параметров возвращает содержимое файла одной строкой. Дальше её можно разбить на строки функцией СтрРазделить(ВесьТекст, Символы.ПС).
Тот же файл через ТекстовыйДокумент:
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать("C:\Обмен\ostatki.txt", КодировкаТекста.UTF8);
Для НомерСтроки = 1 По Текст.КоличествоСтрок() Цикл
Строка = Текст.ПолучитьСтроку(НомерСтроки);
// обработка строки
КонецЦикла;
Нумерация строк в ТекстовыйДокумент начинается с 1, а не с 0. В массиве из СтрРазделить — с 0. Путаница здесь даёт потерю первой или последней строки.
ТекстовыйДокумент удобен ещё и тем, что его можно вывести на форму или открыть методом Показать() — пользователь увидит файл прямо в 1С.
Построчное чтение TXT файла: код, который выдержит гигабайт
Если файл крупный — журнал регистрации в текстовом виде, выгрузка из банка за год, прайс на 300 тысяч позиций, — не загружайте его целиком. Прочитать() и ТекстовыйДокумент держат весь текст в памяти, и на файлах в сотни мегабайт рабочий процесс или клиент упрётся в память.
Построчный вариант держит в памяти только текущую строку:
Процедура ПрочитатьФайлПострочно(ИмяФайла)
Чтение = Новый ЧтениеТекста(ИмяФайла, КодировкаТекста.UTF8);
НомерСтроки = 0;
Строка = Чтение.ПрочитатьСтроку();
Пока Строка <> Неопределено Цикл
НомерСтроки = НомерСтроки + 1;
Если Не ПустаяСтрока(Строка) Тогда
ОбработатьСтроку(Строка, НомерСтроки);
КонецЕсли;
Строка = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
КонецПроцедуры
Ключевой момент — условие выхода. В конце файла ПрочитатьСтроку() возвращает Неопределено, а не пустую строку. Пустая строка "" — это нормальная пустая строка внутри файла, на ней цикл останавливать нельзя.
📌 Что ещё полезно знать про ЧтениеТекста:
- 🔹 Пятый параметр конструктора —
МонопольныйРежим. Если файл в этот момент пишет другая программа, передайтеЛожь, иначе получите ошибку доступа. - 🔹 Разделитель строк по умолчанию — перевод строки; пары
ВК+ПСиз Windows-файлов обрабатываются корректно. - 🔹 Всегда вызывайте
Закрыть(). Пока объект жив, файл может оставаться заблокированным для удаления или перезаписи.
Чтобы файл гарантированно закрывался даже при ошибке в обработке, оборачивайте цикл в Попытка … Исключение: в ветке исключения закройте чтение и вызовите ВызватьИсключение;, чтобы ошибка не потерялась.
Кодировки UTF-8, windows-1251, OEM и KOI8-R
«Кракозябры» после чтения — самая частая жалоба. Причина одна: файл записан в одной кодировке, а 1С читает его в другой. Кодировку передают вторым параметром — значением перечисления КодировкаТекста или строкой с именем кодировки.
| Как выглядит файл | Что передать в 1С |
|---|---|
| Современная выгрузка, файл из веба, XML-подобные данные | КодировкаТекста.UTF8 |
| Блокнот Windows старых версий, выгрузки старых программ | КодировкаТекста.ANSI или "windows-1251" |
| Вывод консольных программ, DOS-форматы, файлы 1С 7.7 | КодировкаТекста.OEM или "cp866" |
| Почтовые и Unix-системы с кириллицей | "koi8-r" |
| Файл с BOM в UTF-16 | КодировкаТекста.UTF16 |
Пример с явной строковой кодировкой:
Чтение = Новый ЧтениеТекста(ИмяФайла, "koi8-r");
КодировкаТекста.ANSI означает кодировку Windows, заданную в системе. На русской Windows это windows-1251, но на сервере Linux или английской Windows результат может быть другим. Поэтому для выгрузок из чужих программ надёжнее писать имя кодировки строкой: "windows-1251".
Как понять кодировку, если её никто не назвал
- Откройте файл в Notepad++ или аналогичном редакторе — внизу окна видна определённая им кодировка.
- Если редактора нет, прочитайте первые строки поочерёдно в UTF-8 и в windows-1251 и выведите их через
Сообщить(). Где кириллица читается — та и нужна. - Посмотрите первые байты файла:
EF BB BFв начале — это метка UTF-8 (BOM),FF FE— UTF-16.
Если в строке видно абв — файл в UTF-8, а читаете вы его как windows-1251. Если ���� или аЕЖ вместо «абв» — наоборот, однобайтовый файл открыт как UTF-8.
Невидимый символ BOM в начале первой строки — частый источник «необъяснимых» ошибок: первое поле не совпадает с ожидаемым заголовком, хотя на экране всё одинаково. При явном указании КодировкаТекста.UTF8 платформа его пропускает; если же вы получаете текст другим путём, уберите символ функцией СтрЗаменить(Строка, Символ(65279), "").
Файл на компьютере пользователя, а код выполняется на сервере
В клиент-серверной базе путь C:\Обмен\ostatki.txt в серверной процедуре ищется на диске сервера 1С, а не на ПК бухгалтера. Отсюда ошибка «файл не найден», хотя файл точно лежит на рабочем столе. То же в веб-клиенте и при работе в облаке.
Правильный порядок — передать файл на сервер через временное хранилище:
- На клиенте вызвать
НачатьПомещениеФайла()— пользователь выбирает файл в диалоге. - Файл попадает во временное хранилище, клиент получает его адрес.
- На сервере достать двоичные данные и прочитать их как текст.
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
ПрочитатьНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПрочитатьНаСервере(Адрес)
Данные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
Данные.Записать(ИмяВременногоФайла);
Чтение = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.UTF8);
Строка = Чтение.ПрочитатьСтроку();
Пока Строка <> Неопределено Цикл
// разбор строки
Строка = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Для небольшого файла временный файл не нужен: ПолучитьСтрокуИзДвоичныхДанных(Данные, КодировкаТекста.UTF8) сразу вернёт текст. Для больших объёмов вариант с временным файлом и построчным чтением экономнее.
Если файл регулярно кладут в общую сетевую папку, укажите в коде UNC-путь вида \\fileserver\obmen\ostatki.txt. Учётная запись, под которой работает служба сервера 1С, должна иметь права на чтение этой папки — иначе файл «не найдётся», хотя из проводника пользователя он открывается.
COM-объекты и внешние компоненты: когда штатного мало
На Windows можно читать файлы через COM. Это нужно редко — штатные объекты справляются почти со всем, — но пригодится в двух случаях: код достался по наследству со времён 8.2 или нужна кодировка/функция, которой нет в платформе.
Scripting.FileSystemObject — построчное чтение однобайтовых файлов:
ФСО = Новый COMОбъект("Scripting.FileSystemObject");
Файл = ФСО.OpenTextFile("C:\Обмен\ostatki.txt", 1); // 1 — только чтение
Пока Не Файл.AtEndOfStream Цикл
Строка = Файл.ReadLine();
// обработка
КонецЦикла;
Файл.Close();
ADODB.Stream — понимает UTF-8 и другие кодировки через свойство Charset:
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 2; // текстовый режим
Поток.Charset = "utf-8";
Поток.Open();
Поток.LoadFromFile("C:\Обмен\ostatki.txt");
Текст = Поток.ReadText();
Поток.Close();
Ограничения COM:
- ❌ не работает на сервере 1С под Linux и в веб-клиенте;
- ❌ в серверном коде объект создаётся на сервере, под учётной записью службы 1С;
- ❌ в безопасном режиме и при включённых профилях безопасности создание COM-объектов запрещено.
Внешние компоненты (технология Native API) подключают, когда нужен особый формат: нестандартное сжатие, фиксированные бинарные заголовки внутри текста, очень быстрый разбор многогигабайтных логов. Готовую компоненту получают от разработчика вместе с макетом и подключают методами ПодключитьВнешнююКомпоненту() или асинхронными аналогами. Писать свою ради обычного TXT не имеет смысла.
Если же текст лежит не на диске, а на сайте или в API, его не нужно сохранять вручную: HTTPСоединение получает ответ, а HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8") сразу даёт строку для разбора.
Разбор строк: разделители, фиксированная ширина, числа и даты
Прочитать строку — полдела. Дальше её нужно разложить на поля. Возьмём файл с разделителем «;»:
Артикул;Наименование;Количество;Цена
A-1001;Бумага А4;25;389,50
A-1002;Скрепки 28 мм;100;42
Разбор с пропуском заголовка и накоплением в таблицу значений:
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Артикул", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
ТипЧисло = Новый ОписаниеТипов("Число");
Чтение = Новый ЧтениеТекста(ИмяФайла, "windows-1251");
Строка = Чтение.ПрочитатьСтроку(); // заголовок пропускаем
Строка = Чтение.ПрочитатьСтроку();
Пока Строка <> Неопределено Цикл
Поля = СтрРазделить(Строка, ";", Истина);
Если Поля.Количество() >= 4 Тогда
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Артикул = СокрЛП(Поля[0]);
НоваяСтрока.Наименование = СокрЛП(Поля[1]);
НоваяСтрока.Количество = ТипЧисло.ПривестиЗначение(СтрЗаменить(СокрЛП(Поля[2]), ",", "."));
НоваяСтрока.Цена = ТипЧисло.ПривестиЗначение(СтрЗаменить(СокрЛП(Поля[3]), ",", "."));
КонецЕсли;
Строка = Чтение.ПрочитатьСтроку();
КонецЦикла;
Чтение.Закрыть();
Третий параметр СтрРазделить — Истина — сохраняет пустые поля. С Ложь строка A-1003;;5;10 превратится в три элемента вместо четырёх, и колонки «съедут». ПривестиЗначение для числа не падает на мусоре — вернёт 0. Если пустое значение нужно отличать от нуля, проверяйте исходную строку отдельно.
Файл с фиксированной шириной полей (банковские и старые учётные выгрузки) разбирают функцией Сред():
Артикул = СокрЛП(Сред(Строка, 1, 10)); // позиции 1–10
Наименование = СокрЛП(Сред(Строка, 11, 40)); // позиции 11–50
Сумма = СокрЛП(Сред(Строка, 51, 12)); // позиции 51–62
Формат «Ключ=Значение» — как в файле обмена с банком 1CClientBankExchange — разбирается по первому знаку равенства:
Позиция = СтрНайти(Строка, "=");
Если Позиция > 0 Тогда
Ключ = Лев(Строка, Позиция - 1);
Значение = Сред(Строка, Позиция + 1);
КонецЕсли;
Даты в виде 15.03.2025 переводят в тип «Дата» сборкой строки ГГГГММДД: Дата(Прав(Ст, 4) + Сред(Ст, 4, 2) + Лев(Ст, 2)). Оберните это в Попытка, если файл заполняли вручную.
Скорость обработки больших файлов
Чтение само по себе быстрое. Тормозит обычно то, что делается со строкой после. Вот что реально ускоряет загрузку:
- ⚡ Не используйте
СтрПолучитьСтроку()в цикле по всему тексту. Каждый вызов заново ищет строку с начала, и время растёт квадратично. На 100 тысячах строк это минуты вместо секунд. БеритеПрочитатьСтроку()или массив изСтрРазделить. - ⚡ Не ищите элементы справочника запросом на каждую строку. Сначала соберите все артикулы в таблицу, одним запросом получите ссылки, затем сопоставьте через
Соответствие. - ⚡ Записывайте пачками. Объекты пишите в транзакциях по 500–1000 штук, а не одной транзакцией на весь файл: длинная транзакция держит блокировки и при ошибке откатывает всё.
- ⚡ Не склеивайте большую строку в цикле через
Текст = Текст + Строка. Для накопления используйте массив иСтрСоединить()или объектЗаписьТекста. - ⚡ Уводите загрузку в фон. Обработку на десятки минут запускайте фоновым заданием — интерфейс не зависнет, а прогресс в типовых конфигурациях показывают через механизм длительных операций БСП.
Перед первой загрузкой в рабочую базу прогоните обработку на копии. Ошибка в разборе колонок на 50 тысячах строк создаёт столько же испорченных документов.
Ошибки при чтении TXT и как их исправить
Если ни один вариант не подошёл, проверьте права на файл от имени той учётной записи, под которой реально выполняется код. Для серверного кода это пользователь службы 1С, а не тот, кто сидит за компьютером.
Частые вопросы
Можно ли прочитать TXT без программирования?
Файл → Открыть в клиенте 1С откроет текстовый файл в окне программы. Для загрузки данных в документы и справочники без кода не обойтись — нужна внешняя обработка.Где запустить код чтения, если нет конфигуратора?
Файл → Открыть. Для открытия нужны права на внешние обработки.