Часто в практике программирования мы сталкиваемся с задачей загрузки данных из файлов формата CSV. Обычно для разделения ячеек используется запятая или точка с запятой. Но что делать, если сам разделитель встречается внутри текста ячейки? Стандартная функция СтрРазделить в таких случаях отрабатывает некорректно, разбивая одну колонку на несколько. Разберем по шагам, как правильно решать эту задачу в 1С.
Прежде чем писать код, давайте выясним причину такого поведения и посмотрим на общепринятые стандарты. Формат CSV имеет четкие правила описания данных:
Таким образом, если значение содержит точку с запятой, в файле это будет выглядеть примерно так: "текст; продолжение текста", 123, "описание". Стандартный метод 1С ТабличныйДокумент.Прочитать() на сложных файлах часто дает сбои, поэтому рассмотрим надежные альтернативные методы.
Правильный разбор сложных файлов CSV — это не простое использование функции СтрРазделить, а построение алгоритма, известного как конечный автомат. Разберем подробнее, как это работает.
Суть конечного автомата заключается в посимвольном чтении строки. Автомат может находиться в нескольких состояниях (например: «чтение обычного текста», «чтение текста внутри кавычек»). Мы читаем каждый символ и на основе текущего состояния принимаем решение:
"" на "), если нет — выходим из состояния «внутри кавычек».Также конечный автомат позволяет решить проблему многострочных значений. Если открывающая кавычка не была закрыта до конца строки, мы продолжаем чтение следующих строк из файла с помощью ЧтениеТекста.ПрочитатьСтроку(), пока не встретим закрывающую кавычку.
Если файл большого объема (более 10 Мб) или мы не хотим писать сложный алгоритм конечного автомата, рассмотрим использование COM-объектов. В среде Windows мы можем прочитать CSV-файл как обычную базу данных через провайдер Microsoft Access Text Driver.
Создадим подключение с помощью COMОбъект("ADODB.Connection"). При таком подходе драйвер операционной системы берет на себя всю тяжелую работу: он сам понимает стандарты RFC 4180, корректно распознает кавычки, переводы строк и разделители внутри текста. Это работает быстрее посимвольного чтения, хотя и привязывает наше решение к платформе Windows.
Проанализируем еще один элегантный способ — использование регулярных выражений через COMОбъект("VBScript.RegExp"). Вместо циклов и множества проверок, мы можем составить паттерн, который за одну операцию разобьет строку правильно.
Регулярное выражение можно настроить так, чтобы оно искало точку с запятой, за которой следует четное количество кавычек (что означает, что мы находимся вне строкового литерала). Это позволяет быстро получить нужный массив значений без сложных алгоритмов на внутреннем языке 1С.
Для ускорения разработки иногда применяют упрощенный подход с предварительной заменой символов. Разберем по шагам этот алгоритм:
// 1. Читаем строку из файла
СтрокаФайла = ЧтениеТекста.ПрочитатьСтроку();
// 2. Ищем экранированные разделители (например, точку с запятой внутри кавычек)
// и временно меняем их на уникальный набор символов, которого точно нет в тексте
СтрокаФайла = СтрЗаменить(СтрокаФайла, """;""", "#$&^");
// 3. Теперь можно безопасно разделить строку стандартным методом
МассивКолонок = СтрРазделить(СтрокаФайла, ";");
// 4. Проходим по массиву и возвращаем символы обратно, заодно убирая служебные кавычки
Для Индекс = 0 По МассивКолонок.ВГраница() Цикл
ТекущееЗначение = МассивКолонок[Индекс];
ТекущееЗначение = СтрЗаменить(ТекущееЗначение, "#$&^", ";");
// Дальнейшая обработка и очистка кавычек
КонецЦикла;
Этот метод работает быстрее, чем посимвольный конечный автомат, если нужно быстро разделить строку на подстроки по ;, а затем проанализировать только те фрагменты, которые были излишне разбиты или содержали кавычки.
Мы выяснили причину ошибок при чтении CSV и рассмотрели несколько рабочих подходов. Выбор метода зависит от ваших задач: для максимальной кроссплатформенности и надежности используйте конечный автомат, для скорости и файлов огромного размера — ADODB, а для быстрых доработок — предварительную замену символов или RegExp. Применяйте эти решения на практике, и ваши интеграции будут работать стабильно!