Как загрузить CSV через ADO без обрезания строк длиннее 255 символов

Программист 1С v8.3 (Обычные формы)
← На главную

При работе с внешними данными в 1С часто используется механизм ADO (ActiveX Data Objects) для чтения CSV-файлов. Однако многие разработчики сталкиваются с досадным ограничением: строки, длина которых превышает 255 символов, обрезаются при чтении. Это происходит из-за того, что драйвер Microsoft Text Driver по умолчанию интерпретирует текстовые поля как стандартные строки фиксированной длины.

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

Почему ADO обрезает данные?

Разберем ситуацию: когда вы подключаетесь к текстовому файлу через ADODB.Connection, драйвер (Jet или ACE) пытается «угадать» типы данных в каждой колонке. Для этого он анализирует первые 8 строк файла. Если в этих строках не встречается данных длиннее 255 символов, драйвер назначает колонке тип Text (аналог Varchar(255) в SQL), и все последующие данные, превышающие этот лимит, будут безвозвратно обрезаны.

Проанализируем основные способы борьбы с этим поведением.

Решение 1. Использование типа Memo в файле Schema.ini

Файл Schema.ini — это текстовый файл, который должен располагаться в той же папке, что и ваш CSV. Он позволяет жестко задать структуру файла, не полагаясь на догадки драйвера. Основная ошибка, которую совершают программисты (как и автор темы), — использование параметра Text Width. Для файлов с разделителями (Delimited) параметр Width часто игнорируется.

Чтобы драйвер перестал обрезать строки, необходимо заменить тип Text на Memo. Тип Memo позволяет считывать до 65 535 символов.

Рассмотрим пример правильного формирования Schema.ini программно в 1С:


// Формируем текст схемы данных
лТекстСхемы = "[" + лИмяФайла + "]" + Символы.ПС;
лТекстСхемы = лТекстСхемы + "ColNameHeader=True" + Символы.ПС;
лТекстСхемы = лТекстСхемы + "Format=Delimited(;)" + Символы.ПС;
лТекстСхемы = лТекстСхемы + "CharacterSet=ANSI" + Символы.ПС;

лИнд = 0;
Для Каждого лКолонка Из пТзДанные.Колонки Цикл
    лИнд = лИнд + 1;
    // Вместо Text Width используем тип Memo для длинных строк
    лТипСтрокой = ?(лКолонка.ТипЗначения.СодержитТип(Тип("Дата")), "Date", "Memo");
    лТекстСхемы = лТекстСхемы + "Col" + лИнд + "=" + лКолонка.Имя + " " + лТипСтрокой + Символы.ПС;
КонецЦикла;

лТекстовыйДокумент = Новый ТекстовыйДокумент;
лТекстовыйДокумент.УстановитьТекст(лТекстСхемы);
// Важно сохранять в кодировке ANSI
лТекстовыйДокумент.Записать(лКаталогФайла + "Schema.ini", КодировкаТекста.ANSI);

Важный момент: Файл Schema.ini должен быть строго в кодировке ANSI. Если сохранить его в UTF-8, драйвер ADO его просто «не увидит» и продолжит обрезать данные.

Решение 2. Настройка реестра Windows (TypeGuessRows)

Если вы не хотите или не можете использовать Schema.ini, можно изменить глобальное поведение драйвера через реестр. Параметр TypeGuessRows определяет количество строк, которые сканирует драйвер для определения типа данных.

Выясним, где искать этот параметр:

  1. Для 32-битных систем или старых драйверов Jet: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text
  2. Для современных 64-битных систем (драйвер ACE): HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\X.0\Access Connectivity Engine\Engines\Text (где X.0 — версия вашего Office).

Если установить значение TypeGuessRows равным 0, драйвер будет сканировать первые 16 384 строки файла перед принятием решения о типе данных. Это значительно повышает шансы на то, что длинная строка будет обнаружена и тип будет определен корректно.

Решение 3. Параметры строки соединения (IMEX=1)

Посмотрим на настройки самой строки соединения. Хотя параметр IMEX=1 чаще применяется к файлам Excel, он может влиять и на обработку текстовых файлов через OLEDB провайдер. Он включает режим работы со «смешанными данными» (Import Mode).

Пример модифицированной строки соединения:


лСоединениеАДО.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + лКаталогФайла + ";Extended Properties=""Text;HDR=YES;FMT=Delimited;IMEX=1;""";

Использование более современного провайдера Microsoft.ACE.OLEDB.12.0 вместо старого Microsoft Access Text Driver также часто помогает решить проблемы с кодировками и длиной полей.

Решение 4. Альтернативный подход через ТекстовыйДокумент

Если CSV-файл содержит сложные вложенные кавычки, переносы строк внутри полей и при этом ADO продолжает капризничать, стоит рассмотреть отказ от ADO в пользу встроенных средств 1С. Многие разработчики боятся этого пути из-за сложности парсинга, но в современных версиях платформы 8.3 это решается проще.

Проанализируем ситуацию: если в строках есть разделители внутри кавычек, простой СтрРазделить не поможет. Однако можно использовать следующий алгоритм:

  1. Прочитать файл целиком или построчно через ТекстовыйДокумент или ЧтениеТекста.
  2. Использовать специализированные функции парсинга CSV, которые учитывают кавычки.

Пример простого парсинга строки с учетом кавычек:


// Пример функции для разбора строки CSV
Функция РазобратьСтрокуCSV(Знач Стр)
    МассивРезультат = Новый Массив;
    Чтение = Новый ЧтениеТекста;
    // ... логика перебора символов с контролем флага ВнутриКавычек
    Возврат МассивРезультат;
КонецФункции

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

Подведем итог: использование ADO для загрузки CSV — это быстрый и удобный способ, если структура данных проста и стабильна. Чтобы избежать обрезания строк:

Помните, что ADO — это технология, созданная для работы с табличными данными, и она всегда будет пытаться типизировать ваш текст, что в случае с CSV не всегда желательно.

← На главную