Казалось бы, чего тут рассказывать, но когда я столкнулся с задачей загрузки csv в 1С, то обнаружил, что нигде - ни в функциях глобального контекста, ни в интернете нет подходящего метода чтения, который учитывал бы все нюансы.
Обычно предлагается что-то вроде СтрРазделить(СтрокаCsv, ",") - тогда мы не учитываем запятые, которые являются частью значения.
Например: имеем структуру Имя,Возраст,Адрес - 3 колонки
и кортеж "Иван",25,"Город Санкт-Петербург, улица Маршала Блюхера 5 литера ""А"""
Разделив эту строку просто по запятой, получим:
"Иван" | 25 | Город Санкт-Петербург | улица Маршала Блюхера 5 литера ""А"" - 4 значения и лишние кавычки.
Решение проблемы:
1. Последовательное чтение
Можно посимвольно читать и анализировать строку согласно правилам csv:
Поэтому есть второй, в 3 раза более быстрый вариант.
2. Регулярные выражения
Можно выполнять ту же процедуру, используя регулярные выражения - но тогда вам потребуется версия платформы 8.23, либо виндовый сервер, позволяющий использовать COM-объект vb.
Полноценная функция преобразования csv файла в таблицу значений выглядит примерно так:
Функция ФайлCSVВТаблицуЗначений(АдресФайлаВХ, Разделитель = ",", ДопПараметры = Неопределено) Экспорт
ДД = ПолучитьИзВременногоХранилища(АдресФайлаВХ);
Поток = ДД.ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеТекста(Поток);
Если ЗначениеЗаполнено(ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДопПараметры, "Шапка", Неопределено)) Тогда
Шапка = ДопПараметры.Шапка;
Иначе
Шапка = Чтение.ПрочитатьСтроку();
КонецЕсли;
МассивКолонок = РазложитьСрокуCSVВМассивподстрок(Шапка, Разделитель);
ТЗ = Новый ТаблицаЗначений;
КвСтроки = Новый КвалификаторыСтроки(999);
КвЧисла = Новый КвалификаторыЧисла(25, 2);
КвДаты = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя);
ТипОбщий = Новый ОписаниеТипов("Строка, Число, Дата, Булево", КвЧисла, КвСтроки, КвДаты);
Для каждого Колонка Из МассивКолонок Цикл
Если ЗначениеЗаполнено(Колонка) Тогда
КолонкаТехИмя = СтроковыеФункцииКлиентСервер.ЗаменитьОдниСимволыДругими(""", !@#$%^&*()*-+=/\", Колонка, "");
ТЗ.Колонки.Добавить(КолонкаТехИмя, ТипОбщий, Колонка);
КонецЕсли;
КонецЦикла;
КоличествоКолонок = ТЗ.Колонки.Количество();
СчетОшибок = 0;
РегулярноеВыражение = РегулярноеВыражениеДляCSV(Разделитель);
ЧтениеПродолжается = Истина;
Пока ЧтениеПродолжается Цикл
Строка = Чтение.ПрочитатьСтроку();
Если Строка <> Неопределено Тогда
МассивЗначений = РазложитьСтрокуCSVВМассивПодстрок_Регулярка(Строка, РегулярноеВыражение);
Если МассивЗначений.Количество() <> КоличествоКолонок Тогда
СчетОшибок = СчетОшибок + 1;
ЗаписьЖурналаРегистрации("Не удалось разобрать csv строку!", УровеньЖурналаРегистрации.Предупреждение, ,, Строка);
Продолжить;
КонецЕсли;
НовСтр = ТЗ.Добавить();
Для НомКол = 0 По КоличествоКолонок - 1 Цикл
НовСтр[НомКол] = МассивЗначений[НомКол];
КонецЦикла;
Иначе
ЧтениеПродолжается = Ложь;
Поток.Закрыть();
КонецЕсли;
КонецЦикла;
Возврат ТЗ;
КонецФункции // ()
На этом у меня, собственно, все)
Если интересно, могу также поделиться функционалом для дальнейшей загрузки прочитанных данных в регистры или справочники.