Чтение и запись txt-файлов во встроенном языке 1С 8.3

· 9 мин

Содержание

Открыть текстовый файл в 1С 8.3 программно можно тремя объектами: ТекстовыйДокумент (весь файл в память, удобный доступ к строке по номеру), ЧтениеТекста (потоковое чтение построчно) и ЧтениеДанных (байты и нестандартные форматы). Для файла до нескольких мегабайт хватит ТекстовыйДокумент.Прочитать(Путь, КодировкаТекста.UTF8), для больших — цикл по ЧтениеТекста.ПрочитатьСтроку().

Чаще всего код ломается не на самом чтении, а рядом: файл лежит на компьютере пользователя, а читают его на сервере, кодировка не та, или файл занят другой программой. Каждый из этих случаев решается парой строк кода, если знать, где именно он выполняется и в какой кодировке пришёл файл.

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

Платформа даёт несколько объектов, и у каждого своя ниша. Выбор зависит от размера файла и того, что с ним нужно сделать.

ОбъектКак работаетКогда братьОграничения
ТекстовыйДокументЧитает файл целиком, даёт ПолучитьСтроку(N), КоличествоСтрок(), Показать()Небольшие файлы, нужен доступ к любой строке, показ пользователюВесь текст в памяти
ЧтениеТекстаПотоковое чтение строки за строкой или порциями символовЛоги, выгрузки, CSV на сотни мегабайтТолько вперёд, назад вернуться нельзя
ЗаписьТекстаПотоковая запись, режим дозаписиЛоги, выгрузка большого объёмаТолько запись
ЧтениеДанных / ЗаписьДанныхРабота с байтами и потокамиСвои форматы, файлы со смешанным содержимымБольше кода
ФайлСвойства файла: Существует(), Размер(), ЭтоФайл()Проверки перед открытиемСодержимое не читает

💡 Если файл нужно просто показать человеку, без разбора, достаточно двух строк: прочитать в ТекстовыйДокумент и вызвать Показать("Заголовок окна"). Откроется встроенный редактор платформы.

Без программирования txt открывается через главное меню: Файл → Открыть в режиме 1С:Предприятие или в Конфигураторе. Файл откроется во встроенном текстовом редакторе — удобно, чтобы глянуть содержимое выгрузки, не выходя из программы.

Как открыть и прочитать текстовый файл: пошагово

Главное правило: код, который читает файл по пути, выполняется там, где этот путь существует. Путь C:\Выгрузка\data.txt на компьютере бухгалтера не виден серверу 1С. В клиент-серверной базе это разные машины, а в файловой — нет, поэтому код, отлаженный на файловой копии, часто «ломается» на рабочем сервере.

Шаг 1. Выбор файла на клиенте

На платформе 8.3.18 и выше удобнее всего асинхронный диалог. Он не требует модального режима и работает в тонком и веб-клиенте.

&НаКлиенте
Асинх Процедура ОткрытьФайл(Команда)

	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Фильтр = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
	Диалог.МножественныйВыбор = Ложь;

	Выбранные = Ждать Диалог.ВыбратьАсинх();
	Если Выбранные = Неопределено Тогда
		Возврат; // пользователь нажал «Отмена»
	КонецЕсли;

	Текст = Новый ТекстовыйДокумент;
	Ждать Текст.ПрочитатьАсинх(Выбранные[0], КодировкаТекста.UTF8);

	Для НомерСтроки = 1 По Текст.КоличествоСтрок() Цикл
		Строка = Текст.ПолучитьСтроку(НомерСтроки);
		// обработка строки
	КонецЦикла;

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

На платформах до 8.3.18 вместо Асинх/Ждать используют Диалог.Показать(ОписаниеОповещения) и Текст.НачатьЧтение(ОписаниеОповещения, Путь, Кодировка) с процедурой-обработчиком.

Шаг 2. Построчное чтение на сервере

Если файл уже лежит в каталоге, доступном серверу (общая папка обмена, каталог на сервере), читайте его потоком:

&НаСервереБезКонтекста
Функция ПрочитатьСтрокиФайла(ПутьКФайлу)

	Результат = Новый Массив;
	Чтение = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);

	Строка = Чтение.ПрочитатьСтроку();
	Пока Строка <> Неопределено Цикл
		Результат.Добавить(Строка);
		Строка = Чтение.ПрочитатьСтроку();
	КонецЦикла;

	Чтение.Закрыть();
	Возврат Результат;

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

ПрочитатьСтроку() возвращает Неопределено, когда файл закончился. Пустая строка в середине файла приходит как "", поэтому сравнивайте именно с Неопределено, а не с пустой строкой.

Шаг 3. Разбор строки на поля

Для файлов с разделителем (CSV, выгрузки банка, прайсы) строку режут функцией СтрРазделить:

Поля = СтрРазделить(Строка, ";", Истина);
Если Поля.Количество() >= 3 Тогда
	Артикул = СокрЛП(Поля[0]);
	Наименование = СокрЛП(Поля[1]);
	Цена = Число(СтрЗаменить(Поля[2], ",", "."));
КонецЕсли;

Третий параметр Истина сохраняет пустые поля. Без него строка 001;;150 превратится в два элемента вместо трёх, и колонки съедут.

⚠️ Число() вызывает исключение на строке вроде 150 руб.. Если источник «грязный», оберните преобразование в Попытка или чистите строку заранее.

Файл с компьютера пользователя: передача на сервер

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

&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
	Оповещение = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
	НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
	Если Результат Тогда
		ОбработатьФайлНаСервере(Адрес);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОбработатьФайлНаСервере(Адрес)

	ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
	ДвоичныеДанные.Записать(ИмяВременногоФайла);

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

	Для НомерСтроки = 1 По Текст.КоличествоСтрок() Цикл
		// создание документов, запись в регистры
	КонецЦикла;

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

Для небольшого файла временный файл можно не создавать: ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, "UTF-8") сразу вернёт текст, а СтрРазделить(Текст, Символы.ПС) разобьёт его на строки.

💡 В типовых конфигурациях на БСП есть готовые обёртки: ФайловаяСистемаКлиент.ЗагрузитьФайл и ФайловаяСистемаКлиент.СохранитьФайл. Они сами учитывают веб-клиент и расширение работы с файлами, поэтому в доработках типовых решений лучше брать их.

Запись и дозапись в текстовый файл

Записать текст можно тем же ТекстовыйДокумент или потоковым ЗаписьТекста. Первый удобен, когда вы собираете документ целиком и сохраняете один раз:

Текст = Новый ТекстовыйДокумент;
Текст.ДобавитьСтроку("Артикул;Наименование;Цена");
Текст.ДобавитьСтроку("001;Бумага А4;350");
Текст.Записать(ПутьКФайлу, КодировкаТекста.ANSI);

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

Запись = Новый ЗаписьТекста(ПутьКЛогу, КодировкаТекста.UTF8, , Истина);
Запись.ЗаписатьСтроку(Формат(ТекущаяДатаСеанса(), "ДФ='dd.MM.yyyy HH:mm:ss'") + " Загрузка завершена");
Запись.Закрыть();

Разница между методами записи:

  • 📝 ЗаписатьСтроку(Текст) — пишет текст и перевод строки;
  • ✏️ Записать(Текст) — пишет текст без перевода, следующий вызов продолжит ту же строку;
  • 🔒 Закрыть() — сбрасывает буфер на диск и освобождает файл.

Без Закрыть() хвост файла может остаться в буфере, а сам файл — занятым до конца сеанса. Вызывайте его всегда, в том числе в ветке обработки исключения.

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

Кодировки, BOM и разделители строк в 1С

Кодировку указывайте явно при каждом чтении и записи. Это одна строка кода, а без неё «кракозябры» всплывают у первого же контрагента с другой программой.

ЗначениеЧто этоГде встречается
КодировкаТекста.UTF8UTF-8Современные выгрузки, веб-сервисы, JSON, XML
КодировкаТекста.ANSIКодировка Windows по умолчанию, на русской системе — windows-1251Старые программы, банковские файлы формата 1CClientBankExchange
КодировкаТекста.OEMDOS-кодировка, на русской системе — cp866Вывод консольных утилит, bat-файлы
КодировкаТекста.UTF16UTF-16Выгрузки некоторых программ Windows
Строка "windows-1251", "koi8-r"Любая кодировка по имениКогда нужна конкретная, а не «системная»

Как узнать кодировку по виду «кракозябр»:

  • 🔤 Привет вместо «Привет» — файл в UTF-8, а читаете как windows-1251;
  • ❓ знаки � вместо русских букв — файл в windows-1251, а читаете как UTF-8;
  • 📟 ╧ЁштхЄ и похожие псевдографические символы — путаница с OEM (cp866).

BOM: когда он мешает

При записи с КодировкаТекста.UTF8 платформа ставит в начало файла метку BOM (три служебных байта). Большинство программ её понимают, но некоторые парсеры и веб-сервисы видят в начале первой строки «лишний» символ, и первое поле не совпадает с ожидаемым.

Записать UTF-8 без BOM можно через двоичные данные — у функции есть параметр использования BOM:

ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ТекстЦеликом, "UTF-8", Ложь);
ДвоичныеДанные.Записать(ПутьКФайлу);

Переводы строк

В Windows строки разделены парой символов ВК+ПС, в Linux — одним ПС. При чтении ЧтениеТекста по умолчанию приводит разделители к Символы.ПС, поэтому строки читаются одинаково. Если сервер 1С работает на Linux, а получатель файла — программа под Windows, задайте разделитель при записи явно: Символы.ВК + Символы.ПС.

Ошибки при открытии текстового файла и как их перехватить

Любая операция с файлом может упасть: нет доступа к каталогу, файл открыт в Excel, путь указан для другой машины. Оборачивайте работу в Попытка и закрывайте файл в обеих ветках:

Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
	ВызватьИсключение СтрШаблон("Файл не найден: %1", ПутьКФайлу);
КонецЕсли;

Чтение = Неопределено;
Попытка
	Чтение = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
	Строка = Чтение.ПрочитатьСтроку();
	Пока Строка <> Неопределено Цикл
		// обработка
		Строка = Чтение.ПрочитатьСтроку();
	КонецЦикла;
	Чтение.Закрыть();
Исключение
	Если Чтение <> Неопределено Тогда
		Чтение.Закрыть();
	КонецЕсли;
	ЗаписьЖурналаРегистрации("Загрузка из txt", УровеньЖурналаРегистрации.Ошибка, , ,
		ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	ВызватьИсключение;
КонецПопытки;

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

Диагностика: выберите симптом

Большие текстовые файлы: скорость и память

Файл на 500 МБ через ТекстовыйДокумент загрузит рабочий процесс сервера и может упереться в память. Для логов и массовых выгрузок работают другие приёмы.

  1. Читайте потоком. ЧтениеТекста.ПрочитатьСтроку() держит в памяти одну строку, а не весь файл. Если строки очень длинные или их нет вовсе, Чтение.Прочитать(1000000) вернёт следующий миллион символов.
  2. Не склеивайте строки через + в цикле. Каждая склейка создаёт новую строку, и на десятках тысяч итераций время растёт лавинообразно. Собирайте части в Массив и соединяйте один раз: СтрСоединить(Части, Символы.ПС).
  3. Пишите потоком. Для выгрузки используйте ЗаписьТекста.ЗаписатьСтроку в цикле, а не накопление в ТекстовыйДокумент с последующей записью.
  4. Делите запись в базу на порции. Если по каждой строке создаётся объект, фиксируйте транзакцию, например, на каждой 1000 строк. Одна транзакция на миллион записей держит блокировки и раздувает журнал СУБД.
  5. Выносите в фоновое задание. Долгая загрузка из формы упрётся в таймаут клиента и заблокирует пользователя. В конфигурациях на БСП для этого есть модуль ДлительныеОперации.
Размер файлаЧем читатьКомментарий
До 10 МБТекстовыйДокументПросто и удобно, доступ к любой строке
10–100 МБЧтениеТекста построчноПамять не растёт, скорость стабильная
Больше 100 МБЧтениеТекста + фоновое задание + порции транзакцийИначе таймауты и блокировки

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

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

Можно ли открыть txt-файл в 1С без программирования?
Да. В главном меню выберите Файл → Открыть и укажите файл. Он откроется во встроенном текстовом редакторе, где его можно просмотреть, отредактировать и сохранить.
Как прочитать текстовый файл из макета обработки?
Добавьте в обработку макет типа «Текстовый документ» и получите его кодом: Текст = ПолучитьМакет("ИмяМакета"). Дальше работайте с ним как с обычным ТекстовыйДокумент.
Как проверить, что файл пустой, до чтения?
Создайте объект Новый Файл(Путь) и проверьте Размер(). Нулевой размер означает пустой файл; при этом файл из одной BOM-метки весит три байта и тоже фактически пуст.
Почему в веб-клиенте не работает Прочитать по пути к файлу?
Браузер не даёт сайту читать произвольные файлы с диска. Нужны асинхронные методы с диалогом выбора файла или помещение файла во временное хранилище.
Чем ЧтениеТекста отличается от ЧтениеДанных?
ЧтениеТекста работает со строками и символами в заданной кодировке. ЧтениеДанных работает с байтами: подходит для двоичных форматов и файлов, где текст перемешан с бинарными блоками.