1С 8.3 CSV
Данные > Примеры кода 1С > 1С 8.3 CSV
В 1С 8.3 CSV формат используется для упрощенной выгрузки таблицы. В основном для синхронизации информации с сайтом, выгрузкой/загрузкой документов, прайс-листов. Это универсальный текстовый формат, служащий для типизации данных таблицы. В качестве разделителей используются спец. символы: Символы.Таб или , (запятая) или ; (точка с запятой). Как правило, в первой строчке обозначены названия колонки, во второй и далее - соответсвенно данные. Встроенного функционала для работы с CSV и 1С 8.3 не существует. Однако есть универсальные вспомогательные модели (функции) которые помогают с обработкой данных из CSV файла - например, РазложитьСтрокуВМассивПодстрок. Для работы с CSV файлами больших размеров (более 10Mb) рекомендуется использовать ADO - COMОбъект("ADODB.Connection").
Оглавление:
Чтение файла CSV в 1С 8.3:
&НаКлиенте
Процедура ЧтениеФайлаCSV()
ФайлCSV = Новый ТекстовыйДокумент;
ФайлCSV.Прочитать("D:\import_21092020.csv");
ЗагрузитьCSV(ФайлCSV);
КонецПроцедуры
Процедура ЧтениеФайлаCSV()
ФайлCSV = Новый ТекстовыйДокумент;
ФайлCSV.Прочитать("D:\import_21092020.csv");
ЗагрузитьCSV(ФайлCSV);
КонецПроцедуры
Загрузка CSV файла (в Таблицу значений) в 1С 8.3:
&НаСервере
Процедура ЗагрузитьCSV(ФайлCSV)
ТЗ = Новый ТаблицаЗначений;
// Важно! Чтобы в значениях НЕ встречался используемый разделитель
ИспользуемыйРазделитель = ";";
//*** Если есть шапка таблицы ***
ШапкаCSV = ФайлCSV.ПолучитьСтроку(1);
// Чтение и разделение на отдельные значения в массив (по разделителю)
МассивCSV = СтрРазделить(ШапкаCSV, ИспользуемыйРазделитель);
//***************************
Для Каждого СтрокаНом Из МассивCSV Цикл
// Удаляем пробелы т.к. в названии столбцов они не допускаются
ИмяБП = СтрЗаменить(СтрокаНом," ","");
ТЗ.Колонки.Добавить(ИмяБП,, СтрокаНом);
КонецЦикла;
Для НомерСтроки=2 По ФайлCSV.КоличествоСтрок() Цикл // Если без шапки, то начинаем с первой строчки
// Получаем строку по-порядку
СтрокаCSV = ФайлCSV.ПолучитьСтроку(НомерСтроки);
// Разделяем с помощью выбранного разделителя каждую строку на столбцы
МассивCSV = СтрРазделить(СтрокаCSV, ИспользуемыйРазделитель);
НоваяСтрочка= ТЗ.Добавить();// Добавляем строку в ТЗ
Для НомСтолбца= 1 По МассивCSV.Количество() Цикл
ТекЗначениеCSV = МассивCSV[НомСтолбца-1];
ИмяКолонкиCSV = ТЗ.Колонки[НомСтолбца-1].Имя;
НоваяСтрочка[ИмяКолонкиCSV] = ТекЗначениеCSV;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьCSV(ФайлCSV)
ТЗ = Новый ТаблицаЗначений;
// Важно! Чтобы в значениях НЕ встречался используемый разделитель
ИспользуемыйРазделитель = ";";
//*** Если есть шапка таблицы ***
ШапкаCSV = ФайлCSV.ПолучитьСтроку(1);
// Чтение и разделение на отдельные значения в массив (по разделителю)
МассивCSV = СтрРазделить(ШапкаCSV, ИспользуемыйРазделитель);
//***************************
Для Каждого СтрокаНом Из МассивCSV Цикл
// Удаляем пробелы т.к. в названии столбцов они не допускаются
ИмяБП = СтрЗаменить(СтрокаНом," ","");
ТЗ.Колонки.Добавить(ИмяБП,, СтрокаНом);
КонецЦикла;
Для НомерСтроки=2 По ФайлCSV.КоличествоСтрок() Цикл // Если без шапки, то начинаем с первой строчки
// Получаем строку по-порядку
СтрокаCSV = ФайлCSV.ПолучитьСтроку(НомерСтроки);
// Разделяем с помощью выбранного разделителя каждую строку на столбцы
МассивCSV = СтрРазделить(СтрокаCSV, ИспользуемыйРазделитель);
НоваяСтрочка= ТЗ.Добавить();// Добавляем строку в ТЗ
Для НомСтолбца= 1 По МассивCSV.Количество() Цикл
ТекЗначениеCSV = МассивCSV[НомСтолбца-1];
ИмяКолонкиCSV = ТЗ.Колонки[НомСтолбца-1].Имя;
НоваяСтрочка[ИмяКолонкиCSV] = ТекЗначениеCSV;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Выгрузка в файл CSV и его создание в 1С 8.3:
&НаСервере
Процедура ВыгрузкаВФайлCSVСоздание();
ИспользуемыйРазделитель = ";";
ФайлCSV="D:\import_21092020.csv";
//*** Получаем данные из запроса ***
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнутреннийПрайс.Код КАК Код,
| ВнутреннийПрайс.Наименование КАК Наименование,
| ВнутреннийПрайс.ЗакупочнаяЦена КАК ЗакупочнаяЦена,
| ВнутреннийПрайс.РозничнаяЦена КАК РозничнаяЦена,
| ВнутреннийПрайс.ОптоваяЦена КАК ОптоваяЦена
|ИЗ
| Справочник.Цены КАК ВнутреннийПрайс";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
ТЗ = РезультатЗапроса;
//**********************************
ТекстCSV=""; // Текст с учетом заголовков, разделителей и переноса строк
Для Каждого СтрокаТЗ Из ТЗ Цикл
Если ТекстCSV="" Тогда
СтрокаКол="";
КолонкиТЗ=ТЗ.Колонки;
Для Каждого Колонка Из КолонкиТЗ Цикл
СтрокаКол = "" + СтрокаКол + Колонка.Имя + ИспользуемыйРазделитель ;
КонецЦикла;
ТекстCSV = СтрокаКол + Символы.ПС;
КонецЕсли;
ТекстCSV = ТекстCSV + СтрокаТЗ.Код + ИспользуемыйРазделитель + СтрокаТЗ.Наименование
+ ИспользуемыйРазделитель + СтрокаТЗ.ЗакупочнаяЦена + ИспользуемыйРазделитель + СтрокаТЗ.РозничнаяЦена
+ ИспользуемыйРазделитель + СтрокаТЗ.ОптоваяЦена + Символы.ПС;
КонецЦикла;
КодANSI = КодировкаТекста.ANSI;
ТекстовыйФайлЗапись = Новый ЗаписьТекста(ФайлCSV, КодANSI); // Создание файла CSV
ТекстовыйФайлЗапись.ЗаписатьСтроку(ТекстCSV); // Запись информации в файл
ТекстовыйФайлЗапись.Закрыть(); // Обязательно закрываем, иначе зависает в процессе
КонецПроцедуры
Процедура ВыгрузкаВФайлCSVСоздание();
ИспользуемыйРазделитель = ";";
ФайлCSV="D:\import_21092020.csv";
//*** Получаем данные из запроса ***
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнутреннийПрайс.Код КАК Код,
| ВнутреннийПрайс.Наименование КАК Наименование,
| ВнутреннийПрайс.ЗакупочнаяЦена КАК ЗакупочнаяЦена,
| ВнутреннийПрайс.РозничнаяЦена КАК РозничнаяЦена,
| ВнутреннийПрайс.ОптоваяЦена КАК ОптоваяЦена
|ИЗ
| Справочник.Цены КАК ВнутреннийПрайс";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
ТЗ = РезультатЗапроса;
//**********************************
ТекстCSV=""; // Текст с учетом заголовков, разделителей и переноса строк
Для Каждого СтрокаТЗ Из ТЗ Цикл
Если ТекстCSV="" Тогда
СтрокаКол="";
КолонкиТЗ=ТЗ.Колонки;
Для Каждого Колонка Из КолонкиТЗ Цикл
СтрокаКол = "" + СтрокаКол + Колонка.Имя + ИспользуемыйРазделитель ;
КонецЦикла;
ТекстCSV = СтрокаКол + Символы.ПС;
КонецЕсли;
ТекстCSV = ТекстCSV + СтрокаТЗ.Код + ИспользуемыйРазделитель + СтрокаТЗ.Наименование
+ ИспользуемыйРазделитель + СтрокаТЗ.ЗакупочнаяЦена + ИспользуемыйРазделитель + СтрокаТЗ.РозничнаяЦена
+ ИспользуемыйРазделитель + СтрокаТЗ.ОптоваяЦена + Символы.ПС;
КонецЦикла;
КодANSI = КодировкаТекста.ANSI;
ТекстовыйФайлЗапись = Новый ЗаписьТекста(ФайлCSV, КодANSI); // Создание файла CSV
ТекстовыйФайлЗапись.ЗаписатьСтроку(ТекстCSV); // Запись информации в файл
ТекстовыйФайлЗапись.Закрыть(); // Обязательно закрываем, иначе зависает в процессе
КонецПроцедуры
Чтение файла CSV опционально (средствами 1С) в ТЗ в 1С 8.3:
&НаСервере
Функция ПрочитатьCSVвТЗ(ИмяФайла, ИспользуемыйРазделитель=";", ЗаголовкиИзПервойСтроки = Ложь)
Текст = Новый ЧтениеТекста(ИмяФайла);
ТЗ = Новый ТаблицаЗначений;
// Создадим колонки
ТекСтрока = Текст.ПрочитатьСтроку();
Если ТекСтрока <> Неопределено Тогда
МассивCSV = СтрРазделить(ТекСтрока, ИспользуемыйРазделитель);
ИндексКолонки = 0;
Для Каждого ИмяКолонки Из МассивCSV Цикл
ИмяКолонки = ?(ЗаголовкиИзПервойСтроки, "Кол"+ИндексКолонки, ИмяКолонки);
ТЗ.Колонки.Добавить(ИмяКолонки);
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
Если ЗаголовкиИзПервойСтроки Тогда
ТекСтрока = Текст.ПрочитатьСтроку();
КонецЕсли;
КонецЕсли;
Пока ТекСтрока <> Неопределено Цикл // строки читаются до символа перевода строки
НоваяСтрока = ТЗ.Добавить();
МассивCSV = СтрРазделить(ТекСтрока, ИспользуемыйРазделитель);
ИндексКолонки = 0;
Для Каждого СтрокаНом Из МассивCSV Цикл
НоваяСтрока[ИндексКолонки] = СтрокаНом;
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ТекСтрока = Текст.ПрочитатьСтроку();
КонецЦикла;
Возврат ТЗ;
КонецФункции
Функция ПрочитатьCSVвТЗ(ИмяФайла, ИспользуемыйРазделитель=";", ЗаголовкиИзПервойСтроки = Ложь)
Текст = Новый ЧтениеТекста(ИмяФайла);
ТЗ = Новый ТаблицаЗначений;
// Создадим колонки
ТекСтрока = Текст.ПрочитатьСтроку();
Если ТекСтрока <> Неопределено Тогда
МассивCSV = СтрРазделить(ТекСтрока, ИспользуемыйРазделитель);
ИндексКолонки = 0;
Для Каждого ИмяКолонки Из МассивCSV Цикл
ИмяКолонки = ?(ЗаголовкиИзПервойСтроки, "Кол"+ИндексКолонки, ИмяКолонки);
ТЗ.Колонки.Добавить(ИмяКолонки);
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
Если ЗаголовкиИзПервойСтроки Тогда
ТекСтрока = Текст.ПрочитатьСтроку();
КонецЕсли;
КонецЕсли;
Пока ТекСтрока <> Неопределено Цикл // строки читаются до символа перевода строки
НоваяСтрока = ТЗ.Добавить();
МассивCSV = СтрРазделить(ТекСтрока, ИспользуемыйРазделитель);
ИндексКолонки = 0;
Для Каждого СтрокаНом Из МассивCSV Цикл
НоваяСтрока[ИндексКолонки] = СтрокаНом;
ИндексКолонки = ИндексКолонки + 1;
КонецЦикла;
ТекСтрока = Текст.ПрочитатьСтроку();
КонецЦикла;
Возврат ТЗ;
КонецФункции
Чтение файла CSV через ADO (без схемы) в 1С 8.3:
&НаСервере
Процедура ЧтениеФайлаCSV_ADO(); //Для работы с CSV файлами больших размеров (свыше 10Mb)
ФайлCSV="D:\import_21092020.csv";
ПутьСоединения = "Driver={Microsoft Text Driver (*.csv)};";
ПутьСоединения = ПутьСоединения + "Dbq=" + ФайлCSV + ";";
ПутьСоединения = ПутьСоединения + "Uid=" + "Extensions=csv" + ";";
ADOConn = Новый COMОбъект("ADODB.Connection");
ADOConn.ConnectionString = ПутьСоединения;
ADOConn.Open();
ADORec = Новый COMОбъект("ADODB.Recordset");
Попытка
ADORec.Open("S_elect * from file#txt", ADOConn);
Пока ADORec.EOF() = 0 Цикл
ADOСтрока="";
Для Счетчик = 0 По ADORec.Fields.Count-1 Цикл
ADOСтрока = ADOСтрока + ";" + ADORec.Fields(Счетчик).Value;
КонецЦикла;
//Сообщить("Прочитана строка: "+ADOСтрока);
ADORec.MoveNext();
КонецЦикла;
Исключение
ADORec.Close();
ADOConn.Close();
//Предупреждение("При чтении данных в CSV произошла ошибка:"+ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ЧтениеФайлаCSV_ADO(); //Для работы с CSV файлами больших размеров (свыше 10Mb)
ФайлCSV="D:\import_21092020.csv";
ПутьСоединения = "Driver={Microsoft Text Driver (*.csv)};";
ПутьСоединения = ПутьСоединения + "Dbq=" + ФайлCSV + ";";
ПутьСоединения = ПутьСоединения + "Uid=" + "Extensions=csv" + ";";
ADOConn = Новый COMОбъект("ADODB.Connection");
ADOConn.ConnectionString = ПутьСоединения;
ADOConn.Open();
ADORec = Новый COMОбъект("ADODB.Recordset");
Попытка
ADORec.Open("S_elect * from file#txt", ADOConn);
Пока ADORec.EOF() = 0 Цикл
ADOСтрока="";
Для Счетчик = 0 По ADORec.Fields.Count-1 Цикл
ADOСтрока = ADOСтрока + ";" + ADORec.Fields(Счетчик).Value;
КонецЦикла;
//Сообщить("Прочитана строка: "+ADOСтрока);
ADORec.MoveNext();
КонецЦикла;
Исключение
ADORec.Close();
ADOConn.Close();
//Предупреждение("При чтении данных в CSV произошла ошибка:"+ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Чтение файла CSV через ADO в ТЗ в 1С 8.3:
&НаСервере
Функция ПрочитатьCSVвТЗ_ADO(ИмяФайла, Разделитель=";", ЗаголовкиИзПервойСтроки = Ложь)
ТЗ = Новый ТаблицаЗначений;
ФайлCSV = Новый Файл(ИмяФайла);
ADOConn =Новый COMОбъект("ADODB.Connection");
ADOConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ФайлCSV.Путь+";Extended Properties=""text;HDR=No;IMEX=1;FMT=Delimited""");
// Так как FMT=Delimited(;) не работает создадим schema.ini
Функция ПрочитатьCSVвТЗ_ADO(ИмяФайла, Разделитель=";", ЗаголовкиИзПервойСтроки = Ложь)
ТЗ = Новый ТаблицаЗначений;
ФайлCSV = Новый Файл(ИмяФайла);
ADOConn =Новый COMОбъект("ADODB.Connection");
ADOConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ФайлCSV.Путь+";Extended Properties=""text;HDR=No;IMEX=1;FMT=Delimited""");
// Так как FMT=Delimited(;) не работает создадим schema.ini
// https://docs.microsoft.com/en-us/sql/odbc/microsoft/schema-ini-file-text-file-driver?redirectedfrom=MSDN&view=sql-server-ver15
// https://docs.microsoft.com/en-us/sql/odbc/microsoft/text-file-format-text-file-driver?redirectedfrom=MSDN&view=sql-server-ver15
|ColNameHeader=%2
|Format=Delimited(%3)", ФайлCSV.Имя, Формат(ЗаголовкиИзПервойСтроки, "БЛ=False; БИ=True"), Разделитель);
ФайлСхемы = Новый ТекстовыйДокумент;
ФайлСхемы.УстановитьТекст(СхемаCSV);
ФайлСхемы.Записать(ФайлCSV.Путь + "Schema.ini", "CESU-8"); // UTF-8 без BOM
ADORec=Новый COMОбъект("ADODB.Recordset");
ADORec.ActiveConnection = ADOConn;
ADORec.Open("select * from "+ФайлCSV.Имя, ADOConn);
// определим имена колонок
Для НомКолонки = 0 По ADORec.Fields.Count-1 Цикл
ТЗ.Колонки.Добавить(ADORec.Fields(НомКолонки).Name);
КонецЦикла;
Сч=0;
Пока НЕ ADORec.EOF() Цикл
|Format=Delimited(%3)", ФайлCSV.Имя, Формат(ЗаголовкиИзПервойСтроки, "БЛ=False; БИ=True"), Разделитель);
ФайлСхемы = Новый ТекстовыйДокумент;
ФайлСхемы.УстановитьТекст(СхемаCSV);
ФайлСхемы.Записать(ФайлCSV.Путь + "Schema.ini", "CESU-8"); // UTF-8 без BOM
ADORec=Новый COMОбъект("ADODB.Recordset");
ADORec.ActiveConnection = ADOConn;
ADORec.Open("select * from "+ФайлCSV.Имя, ADOConn);
// определим имена колонок
Для НомКолонки = 0 По ADORec.Fields.Count-1 Цикл
ТЗ.Колонки.Добавить(ADORec.Fields(НомКолонки).Name);
КонецЦикла;
Сч=0;
Пока НЕ ADORec.EOF() Цикл
Сч=Сч+1;
НоваяСтрока = ТЗ.Добавить();
Для а=0 По ADORec.Fields.Count-1 Цикл
НоваяСтрока[а] = ADORec.Fields(а).Value;
КонецЦикла;
ADORec.MoveNext();
КонецЦикла;
ADORec.Close();
ADOConn.Close();
Возврат ТЗ;
КонецФункции
НоваяСтрока = ТЗ.Добавить();
Для а=0 По ADORec.Fields.Count-1 Цикл
НоваяСтрока[а] = ADORec.Fields(а).Value;
КонецЦикла;
ADORec.MoveNext();
КонецЦикла;
ADORec.Close();
ADOConn.Close();
Возврат ТЗ;
КонецФункции
💡 Готовые модели кода (шаблоны) с "CSV" 1С:
1
комментарий
Николай
08 фев 2022
Кто вас науxил именовать переменные?
Минус - за сокращения СтрокаНом (что значит "ном"?).
Минус за стиль именования переменных: зачем там нижнее подчеркивание, если слова в переменной уже выделены заглавной буквой?
Минус за отсутствие проверки на нулевую строку файла. Файл может быть и пустым.
Встретив такие косяки базовых вещей читать дальше желание пропало
Минус - за сокращения СтрокаНом (что значит "ном"?).
Минус за стиль именования переменных: зачем там нижнее подчеркивание, если слова в переменной уже выделены заглавной буквой?
Минус за отсутствие проверки на нулевую строку файла. Файл может быть и пустым.
Встретив такие косяки базовых вещей читать дальше желание пропало
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник