При интеграции 1С с другими приложениями или сайтами встает задача организации обмена данными в каком-либо формате. Один из таких форматов — CSV (Сomma-Separated Values). Этот формат предназначен для организации данных в табличной форме, при этом разделителями колонок могут выступать запятые (,), точки с запятой (;) или знаки табуляции (в 1С — Символ.Таб).
Встроенных процедур для чтения файлов CSV у платформы 1С:Предприятие нет. Но в интернете существует большое количество статей, предлагающих варианты программного кода для работы с такими файлами. Суть этих методик сводится к следующему:
- производится выбор файла на диске и его чтение;
- с помощью встроенной в большинство типовых конфигураций функции РазложитьСтрокуВМассивПодстрок() выполняется выделение колонок в шапке таблицы и в строках;
- строки записываются в таблицу значений или используются иным способом.
Процедуру выбора файла на диске мы опустим, а код для чтения CSV выглядит так:
Таблица = новый ТаблицаЗначений;
// чтение
ЗагружаемыйФайл = Новый ТекстовыйДокумент;
ЗагружаемыйФайл.Прочитать(ИмяФайла); // ИмяФайла - путь к файлу на диске
//Формируем шапку таблицы. Шапка по умолчанию первая строчка
Шапка = ЗагружаемыйФайл.ПолучитьСтрoку(1);
//раскладываем стрoку в массив Разделителем колонок в данном случае является точка с запятой
МассивКол = РазложитьСтрокуВМассивПодстрок(Шапка, ";");
//генерируем столбцы
Для Каждого ИмяСтолбца Из МассивКол Цикл
ИмяБезПробелов = СтрЗаменить(ИмяСтолбца," ",""); // убираем из имени пробелы
Таблица.Колонки.Добавить(ИмяБезПробелов,,ИмяСтолбца);
КонецЦикла;
Для НомерСтроки=2 по ЗагружаемыйФайл.КоличествоСтрок() Цикл
// получить стрoку с указанным номером и преобразуем её в массив
Строка = ЗагружаемыйФайл.ПолучитьСтроку(НомерСтроки);
МассивКол = РазложитьСтрокуВМассивПодстрок(Строка,Разделитель);
НоваяСтрочка= Таблица.Добавить();
Для НомерСтолбца= 1 по МассивКол.Количество() Цикл //заполняем строчку значениями
ТекущееЗначение = МассивКол[НомерСтолбца-1];
ИмяКолонки = Таблица.Колонки[НомерСтолбца-1].Имя;
НоваяСтрочка[ИмяКолонки] = ТекущееЗначение;
КонецЦикла;
КонецЦикла;
Данный метод позаимствован с сайта programmist1s.ru.
Однако, этот метод работает не со всеми файлами CSV, т.к. имеет некоторые ограничения:
- файл CSV не должен иметь знаков разделителя внутри колонок;
- внутри колонок не должно быть знаков переноса строки.
Нам же попался файл, который все это имеет, поэтому пришлось отказаться от использования стандартной функции РазложитьСтрокуВМассивПодстрок() и написать вместо нее свою. Сразу оговорюсь, что функция писалась под конкретный файл CSV (он был предоставлен заказчиком), поэтому мы с радостью учтем ваши замечания и дополнения.
Итак, наш файл CSV имеет внутри колонок символы переноса строки и знаки разделителя (в нашем случае это «;»), колонки с этими символами заключены в кавычки и Excel эту конструкцию воспринимает правильно. В «нормальном» виде в файле присутствует только первая строка заголовков колонок. Этим мы и воспользуемся.
Источник=новый ТекстовыйДокумент;
Источник.Прочитать(ИмяФайла); // ИмяФайла - путь к файлу на диске
// Определяем количество колонок по шапке таблицы, для этого исползуем
// стандартную процедуру РазложитьСтрокуВМассивПодстрок
КоличествоКолонок=СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Источник.ПолучитьСтроку(1), ";").Количество();
// Читаем данные файла, шапку можно отсечь потом
МассивКол = ПрочитатьCSV(Источник.ПолучитьТекст(),";", КоличествоКолонок);
Для каждого Товар из МассивКол Цикл
//переменная МассивКол содержит массив строк таблицы из файла CSV.
//Каждый элемент массива в свою очередь представляет массив колонок.
// В этом цикле можно сделать все необходимое с полученными данными.
КонецЦикла;
КонецПроцедуры
Функция ПрочитатьCSV(Знач Строка, Разделитель, КоличествоКолонок)
Результат = Новый Массив; // массив строк
Скобка=ЛОЖЬ;
Начало=1;
Колонка=0;
СтрокаФайла=новый Массив; // массив колонок в строке
для Позиция=1 по СтрДлина(Строка) Цикл // обходим файл посимвольно
Символ=Сред(Строка, Позиция, 1);
//если встречается кавычка, фиксируем ее открытие, прекращаем итерацию и продолжаем цикл.
Если Символ="""" И Скобка=Ложь Тогда
Скобка=Истина;
Продолжить;
//Если встречается закрывающаяся кавычка, фиксируем ее закрытие и тоже продолжаем цикл
ИначеЕсли Символ="""" И Скобка=Истина ТОгда
Скобка=Ложь;
Продолжить;
КонецЕсли;
//Если встречается разделитель или перенос строки вне кавычек,
//вносим информацию в массив
Если (Символ=Разделитель ИЛИ Символ=Символы.ПС) И Скобка=Ложь Тогда
Конец=Позиция;
Колонка=Колонка+1;
СтрокаФайла.Добавить(Сред(Строка, Начало, Конец-Начало));
//Если набралось количество колонок, равное их количеству в шапке, записываем всю строку
//в массив и переходим к следующей
Если Колонка=КоличествоКолонок Тогда
Результат.Добавить(СтрокаФайла);
СтрокаФайла=Новый Массив;
Колонка=0;
КонецЕсли;
Начало=Позиция+1;
КонецЕсли;
КонецЦикла;
//Удаляем шапку таблицы из массива строк
Результат.Удалить(0);
Возврат Результат;
КонецФункции
Если Вам необходимо наладить обмен с 1С в формате CSV, обращайтесь, наши специалисты выполнят эту работу в кратчайшие сроки.
Для больших csv файлов этот метод будет работать вечность, если вообще не умрет. Подобные вещи по-хорошему надо делать через ADO, правда про это мало кто знает.
Действительно, с очень большими файлами это может работать долго. Будем благодарны, если вы напишете в комментарии свой вариант обработки CSV.
Очень вам благодарен, попался так же не типовой CSV. Не хотел мучиться и очень быстро наткнулся на вшу статью, парсит на УРА!!!
Спасибо, котики <3