Как прочитать CSV-файл в кодировке UTF-8 и перекодировать его с помощью ADODB.Stream в 1С

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При работе в 1С (особенно в версии 7.7) программисты часто сталкиваются с двумя критическими проблемами при обработке внешних файлов: ограничением стандартного объекта Текст на размер файла (не более 64 Кб) и некорректным отображением современных кодировок, таких как UTF-8. Стандартные средства платформы могут выдавать "кракозябры" вместо текста. В этой статье мы подробно разберем, как использовать внешний компонент ADODB.Stream для гибкой работы с файлами, изменения кодировок и обработки больших объемов данных.

Почему стандартный объект Текст не подходит?

Стандартный объект 1С Текст ограничен системными настройками Windows (обычно это ANSI/Windows-1251). Если вам нужно прочитать CSV-файл, выгруженный из веб-сайта или другой современной системы в формате UTF-8, вы неизбежно столкнетесь с проблемой искажения символов. Кроме того, лимит в 64 Кб делает его бесполезным для объемных прайс-листов или логов. Рассмотрим альтернативный путь через ADODB.Stream.

Шаг 1: Инициализация ADODB.Stream и чтение файла

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


Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 2; // Указываем, что работаем с текстовыми данными
Стрим.Charset = "utf-8"; // Устанавливаем исходную кодировку файла
Стрим.Open();
Стрим.LoadFromFile("C:\data\orders.csv"); // Загружаем данные

В данном примере мы используем свойство Type = 2, что соответствует текстовому режиму. Если установить Type = 1, объект будет работать с бинарными данными, что полезно для копирования файлов без изменения их содержимого.

Шаг 2: Построчное чтение данных

Одной из главных проблем является вопрос: читает ли ADODB.Stream файл целиком или по строкам? По умолчанию метод ReadText без параметров считывает весь поток. Однако для обработки CSV-файлов нам крайне важно двигаться по строкам. Выясним, как это реализовать.

Для построчного чтения в метод ReadText необходимо передать параметр -2 (константа adReadLine). Разберем цикл обработки файла:


Пока Стрим.EOS = 0 Цикл
    ТекущаяСтрока = Стрим.ReadText(-2);
    // Здесь выполняем разбор строки (парсинг CSV)
    Сообщить(ТекущаяСтрока);
КонецЦикла;

Обратите внимание на свойство EOS (End of Stream). Это логический признак конца потока. В отличие от привычного EOF, в объекте Stream используется именно EOS. Метод ReadText(-2) автоматически определяет конец строки по символам переноса (CR/LF).

Шаг 3: Перекодировка и сохранение в другой файл

Часто задача стоит не просто прочитать файл, а сконвертировать его из одной кодировки в другую (например, из UTF-8 в Windows-1251) для последующей обработки штатными средствами 1С. Рассмотрим наиболее надежный метод с использованием двух потоков — входного и выходного.


// Настраиваем входной поток (откуда читаем)
Stream_in = СоздатьОбъект("Adodb.Stream");
Stream_in.Type = 2;
Stream_in.Charset = "utf-8";
Stream_in.Open();
Stream_in.LoadFromFile("C:\source.csv");

// Настраиваем выходной поток (куда пишем)
Stream_out = СоздатьОбъект("Adodb.Stream");
Stream_out.Type = 2;
Stream_out.Charset = "windows-1251";
Stream_out.Open();

// Переносим данные
Пока Stream_in.EOS = 0 Цикл
    ТекстСтроки = Stream_in.ReadText(-2);
    Stream_out.WriteText(ТекстСтроки, 1); // 1 означает добавление разделителя строк
КонецЦикла;

// Сохраняем результат
Stream_out.SaveToFile("C:\result_ansi.txt", 2); // 2 - перезаписать файл, если он существует
Stream_in.Close();
Stream_out.Close();

Важный момент: при записи методом WriteText второй параметр определяет, нужно ли добавлять символ переноса строки. Значение 1 (adWriteLine) добавляет разделитель, значение 0 (adWriteChar) пишет текст "как есть".

Проблема BOM (Byte Order Mark) при работе с UTF-8

Проанализируем технический нюанс: при сохранении файла в кодировке UTF-8 через ADODB.Stream, Windows автоматически добавляет в начало файла три специальных байта (BOM). Это может быть проблемой, если файл в дальнейшем должен обрабатываться системами, которые не поддерживают BOM (например, некоторыми Linux-сервисами или скриптами). Если вам нужен "чистый" UTF-8, файл обычно пересохраняется в бинарном режиме, пропуская первые три байта, но в рамках задач 1С 7.7 это требуется редко.

Использование FileSystemObject как альтернатива для записи

Рассмотрим ситуацию из практики: если вам нужно не просто сохранить весь файл, а дописывать строки в лог или выводить их выборочно, можно комбинировать ADODB.Stream для чтения и Scripting.FileSystemObject (FSO) для записи. Это позволяет гибко управлять созданием файлов. Посмотрим на пример совместной работы:


fso = СоздатьОбъект("Scripting.FileSystemObject");
ИмяФайлаЛога = "C:\OutText.txt";
// 2 - запись, 1 - создать если нет, -2 - системная кодировка
file = fso.OpenTextFile(ИмяФайлаЛога, 2, 1, -2);

Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 2;
Стрим.Charset = "utf-8";
Стрим.Open();
Стрим.LoadFromFile("C:\input.csv");

Пока Стрим.EOS = 0 Цикл
    Стр = Стрим.ReadText(-2);
    file.WriteLine(Стр); // Записываем строку через FSO
КонецЦикла;

file.Close();
Стрим.Close();

Выводы и рекомендации

Подведем итоги нашего анализа работы с ADODB.Stream:

  1. Обход ограничений: Использование этого объекта — единственный надежный способ работать с текстовыми файлами объемом более 64 Кб в старых версиях 1С.
  2. Гибкость кодировок: Вы можете явно задавать Charset, что решает проблему некорректного отображения кириллицы в UTF-8, UTF-16 и других форматах.
  3. Построчная обработка: Всегда используйте параметр -2 в методе ReadText для работы с CSV, чтобы не перегружать память загрузкой всего файла целиком в одну переменную.
  4. Безопасность: Не забывайте закрывать потоки методом Close() после завершения работы, чтобы освободить системные ресурсы и снять блокировку с файлов.

Применение ADODB.Stream делает интеграцию 1С с внешними системами более стабильной и профессиональной, позволяя корректно обрабатывать данные в любых современных форматах.

← На главную