Чтение и запись txt-файлов во встроенном языке 1С 8.3
Содержание
Открыть текстовый файл в 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С
Кодировку указывайте явно при каждом чтении и записи. Это одна строка кода, а без неё «кракозябры» всплывают у первого же контрагента с другой программой.
| Значение | Что это | Где встречается |
|---|---|---|
КодировкаТекста.UTF8 | UTF-8 | Современные выгрузки, веб-сервисы, JSON, XML |
КодировкаТекста.ANSI | Кодировка Windows по умолчанию, на русской системе — windows-1251 | Старые программы, банковские файлы формата 1CClientBankExchange |
КодировкаТекста.OEM | DOS-кодировка, на русской системе — cp866 | Вывод консольных утилит, bat-файлы |
КодировкаТекста.UTF16 | UTF-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 МБ через ТекстовыйДокумент загрузит рабочий процесс сервера и может упереться в память. Для логов и массовых выгрузок работают другие приёмы.
- Читайте потоком.
ЧтениеТекста.ПрочитатьСтроку()держит в памяти одну строку, а не весь файл. Если строки очень длинные или их нет вовсе,Чтение.Прочитать(1000000)вернёт следующий миллион символов. - Не склеивайте строки через
+в цикле. Каждая склейка создаёт новую строку, и на десятках тысяч итераций время растёт лавинообразно. Собирайте части вМассиви соединяйте один раз:СтрСоединить(Части, Символы.ПС). - Пишите потоком. Для выгрузки используйте
ЗаписьТекста.ЗаписатьСтрокув цикле, а не накопление вТекстовыйДокументс последующей записью. - Делите запись в базу на порции. Если по каждой строке создаётся объект, фиксируйте транзакцию, например, на каждой 1000 строк. Одна транзакция на миллион записей держит блокировки и раздувает журнал СУБД.
- Выносите в фоновое задание. Долгая загрузка из формы упрётся в таймаут клиента и заблокирует пользователя. В конфигурациях на БСП для этого есть модуль
ДлительныеОперации.
| Размер файла | Чем читать | Комментарий |
|---|---|---|
| До 10 МБ | ТекстовыйДокумент | Просто и удобно, доступ к любой строке |
| 10–100 МБ | ЧтениеТекста построчно | Память не растёт, скорость стабильная |
| Больше 100 МБ | ЧтениеТекста + фоновое задание + порции транзакций | Иначе таймауты и блокировки |
Границы условные: на сервере с большим объёмом памяти ТекстовыйДокумент переварит и больше, но потоковое чтение не хуже даже на маленьких файлах.
Частые вопросы
Можно ли открыть txt-файл в 1С без программирования?
Файл → Открыть и укажите файл. Он откроется во встроенном текстовом редакторе, где его можно просмотреть, отредактировать и сохранить.Как прочитать текстовый файл из макета обработки?
Текст = ПолучитьМакет("ИмяМакета"). Дальше работайте с ним как с обычным ТекстовыйДокумент.Как проверить, что файл пустой, до чтения?
Новый Файл(Путь) и проверьте Размер(). Нулевой размер означает пустой файл; при этом файл из одной BOM-метки весит три байта и тоже фактически пуст.Почему в веб-клиенте не работает Прочитать по пути к файлу?
Чем ЧтениеТекста отличается от ЧтениеДанных?
ЧтениеТекста работает со строками и символами в заданной кодировке. ЧтениеДанных работает с байтами: подходит для двоичных форматов и файлов, где текст перемешан с бинарными блоками.