Файлы и обмен данными в 1С

CSV в 1С: как прочитать и выгрузить файл программно

Коротко

Встроенного объекта «CSV» в платформе нет. Чтение CSV в 1С — это Новый ЧтениеТекста(ИмяФайла, Кодировка) + цикл ПрочитатьСтроку() + СтрРазделить() по разделителю. Выгрузка — Новый ЗаписьТекста(ИмяФайла, Кодировка) + ЗаписатьСтроку() с ручной склейкой полей.

Два места, где чаще всего ломается: кодировка (русский Excel ждёт cp1251 или UTF-8 с BOM) и значения с разделителем или кавычками внутри — их надо экранировать по правилам CSV, простой СтрРазделить() такие строки разбирает неверно.

Формат CSV: разделители, кавычки, кодировки

CSV — текстовый файл, где каждая строка — запись, а поля разделены символом-разделителем. Прежде чем писать код, зафиксируйте три параметра формата CSV, с которым работает 1С:

  • Разделитель. По стандарту RFC 4180 — запятая. Но русский Excel сохраняет и открывает CSV с точкой с запятой «;», потому что запятая занята под десятичный разделитель. В файлах от российских контрагентов почти всегда «;».
  • Кавычки. Если значение содержит разделитель, кавычку или перенос строки, его заключают в двойные кавычки, а кавычки внутри значения удваивают: "ООО ""Ромашка"";Москва" — это одно поле.
  • Кодировка. Исторически — windows-1251 (cp1251). Современные выгрузки — UTF-8, причём Excel корректно определяет UTF-8 только при наличии BOM-маркера в начале файла.

Всё дальнейшее — про то, как эти три параметра учесть при чтении и выгрузке CSV-файла средствами 1С 8.3.

Чтение CSV в 1С: ЧтениеТекста и СтрРазделить

Базовый способ прочитать CSV в 1С — объект ЧтениеТекста: он читает файл построчно и не тянет весь файл в память, поэтому подходит и для больших выгрузок:

Чтение = Новый ЧтениеТекста("C:\Data\import.csv", КодировкаТекста.UTF8);

СтрокаФайла = Чтение.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл

    Поля = СтрРазделить(СтрокаФайла, ";", Истина);
    // Поля[0] — артикул, Поля[1] — наименование, Поля[2] — количество

    СтрокаФайла = Чтение.ПрочитатьСтроку();
КонецЦикла;

Чтение.Закрыть();
Новый ЧтениеТекста
ИмяФайлапуть к читаемому файлу
КодировкаКодировкаТекста.UTF8, "windows-1251" и т.п.
РазделительСтрокчем разделены строки файла
КонвертируемыйРазделительСтрокво что превращать разделитель
МонопольныйРежимблокировать ли файл на время чтения

ПрочитатьСтроку() возвращает Неопределено, когда файл закончился — это и есть условие выхода из цикла. Третий параметр СтрРазделить(..., Истина) сохраняет пустые поля: строка "А-100;;5" даст массив из трёх элементов, а не из двух — для CSV с пропусками это принципиально.

Для файла в cp1251 меняется только кодировка: Новый ЧтениеТекста(ИмяФайла, "windows-1251"). Если кодировку не указать, платформа попытается определить её по BOM, а без BOM возьмёт системную — на сервере под Linux это даст кракозябры на файле cp1251, поэтому кодировку лучше задавать явно.

В Консоли кода такой разбор удобно отлаживать по шагам: попросите агента «прочитай первые 10 строк файла и покажи, как они разбиваются по ";"» — он выполнит код и покажет реальные массивы полей до того, как вы напишете полную загрузку.

Разбор строк с кавычками и разделителем внутри значений

СтрРазделить() ничего не знает про кавычки: строку А-100;"Кабель 3x1,5; бухта";12 она разрежет по всем «;», включая тот, что внутри наименования. Если в файле встречаются поля в кавычках, нужен посимвольный разбор с учётом состояния «внутри кавычек»:

Функция РазобратьСтрокуCSV(Знач СтрокаCSV, Знач Разделитель = ";")

    Результат  = Новый Массив;
    Значение   = "";
    ВКавычках  = Ложь;
    Длина      = СтрДлина(СтрокаCSV);

    Индекс = 1;
    Пока Индекс <= Длина Цикл
        Символ = Сред(СтрокаCSV, Индекс, 1);

        Если Символ = """" Тогда
            Если ВКавычках И Сред(СтрокаCSV, Индекс + 1, 1) = """" Тогда
                Значение = Значение + """"; // удвоенная кавычка -> одна
                Индекс = Индекс + 1;
            Иначе
                ВКавычках = НЕ ВКавычках;
            КонецЕсли;
        ИначеЕсли Символ = Разделитель И НЕ ВКавычках Тогда
            Результат.Добавить(Значение);
            Значение = "";
        Иначе
            Значение = Значение + Символ;
        КонецЕсли;

        Индекс = Индекс + 1;
    КонецЦикла;

    Результат.Добавить(Значение);
    Возврат Результат;

КонецФункции

Функция реализует правила RFC 4180: разделитель внутри кавычек — часть значения, удвоенная кавычка — экранированная кавычка. Правило выбора простое: файл гарантированно без кавычек — хватит СтрРазделить(); файл из Excel или от внешней системы — разбирайте этой функцией, Excel заключает в кавычки любое поле с разделителем внутри.

Как загрузить CSV в таблицу значений

Типовая задача — загрузить CSV в 1С в таблицу значений: первая строка файла становится колонками, остальные — строками таблицы:

Функция ЗагрузитьCSVвТаблицу(Знач ИмяФайла, Знач Разделитель = ";", Знач Кодировка = "UTF-8")

    Чтение  = Новый ЧтениеТекста(ИмяФайла, Кодировка);
    Таблица = Новый ТаблицаЗначений;

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

    Заголовки = РазобратьСтрокуCSV(СтрокаЗаголовка, Разделитель);
    Для Каждого Заголовок Из Заголовки Цикл
        Таблица.Колонки.Добавить(СокрЛП(Заголовок));
    КонецЦикла;

    // Данные
    СтрокаФайла = Чтение.ПрочитатьСтроку();
    Пока СтрокаФайла <> Неопределено Цикл
        Поля = РазобратьСтрокуCSV(СтрокаФайла, Разделитель);
        НоваяСтрока = Таблица.Добавить();
        Для Индекс = 0 По Мин(Поля.ВГраница(), Таблица.Колонки.Количество() - 1) Цикл
            НоваяСтрока[Индекс] = Поля[Индекс];
        КонецЦикла;
        СтрокаФайла = Чтение.ПрочитатьСтроку();
    КонецЦикла;

    Чтение.Закрыть();
    Возврат Таблица;

КонецФункции

Все значения попадают в таблицу строками — CSV не хранит типы. Числа, даты и ссылки приводите отдельным проходом: числа — через СтрЗаменить(Значение, ",", ".") и Число(), номенклатуру — поиском по артикулу или коду.

Выгрузка CSV из 1С: ЗаписьТекста

Выгрузка в CSV — зеркальная задача: объект ЗаписьТекста пишет файл построчно, поля склеиваются разделителем вручную:

Запись = Новый ЗаписьТекста("C:\Data\export.csv", "UTF-8");

Запись.ЗаписатьСтроку("Артикул;Наименование;Остаток");
Запись.ЗаписатьСтроку("А-100;Кабель ВВГ 3x1,5;120");
Запись.ЗаписатьСтроку("А-101;""Розетка ""Legrand"" белая"";35");

Запись.Закрыть();
Новый ЗаписьТекста
ИмяФайлапуть к создаваемому файлу
Кодировка"UTF-8", "windows-1251", КодировкаТекста.UTF8
РазделительСтрокразделитель строк в файле
ДописыватьИстина — дописать в конец файла
КонвертируемыйРазделительСтроккакой разделитель конвертировать

Экранирование значений вынесите в функцию — она оборачивает в кавычки только те поля, где есть разделитель, кавычка или перенос строки:

Функция ПодготовитьЗначениеCSV(Знач Значение, Знач Разделитель = ";")
    Результат = Строка(Значение);
    Если СтрНайти(Результат, Разделитель) > 0
        Или СтрНайти(Результат, """") > 0
        Или СтрНайти(Результат, Символы.ПС) > 0 Тогда
        Результат = """" + СтрЗаменить(Результат, """", """""") + """";
    КонецЕсли;
    Возврат Результат;
КонецФункции

Про BOM: при выгрузке в кодировке "UTF-8" через конструктор с именем файла платформа сама пишет BOM-маркер в начало — именно такой файл русский Excel открывает без кракозябр. Если принимающая система требует UTF-8 без BOM, используйте вариант конструктора с потоком: Новый ЗаписьТекста(Поток, "UTF-8", , , Ложь) — пятый параметр ЗаписатьBOM отключает маркер.

Выгрузить результат запроса в CSV-файл

Практический сценарий «1С выгрузить CSV» почти всегда сводится к цепочке: запрос → таблица значений → цикл записи. Пример — остатки номенклатуры в CSV-файл с разделителем «;»:

Запрос = Новый Запрос(
    "ВЫБРАТЬ
    |   Остатки.Номенклатура.Артикул КАК Артикул,
    |   Остатки.Номенклатура.Наименование КАК Наименование,
    |   Остатки.КоличествоОстаток КАК Остаток
    |ИЗ
    |   РегистрНакопления.ТоварыНаСкладах.Остатки() КАК Остатки");

Таблица = Запрос.Выполнить().Выгрузить();

Запись = Новый ЗаписьТекста("C:\Data\ostatki.csv", "UTF-8");
Запись.ЗаписатьСтроку("Артикул;Наименование;Остаток");

Для Каждого СтрокаТаблицы Из Таблица Цикл
    Запись.ЗаписатьСтроку(
        ПодготовитьЗначениеCSV(СтрокаТаблицы.Артикул) + ";"
        + ПодготовитьЗначениеCSV(СтрокаТаблицы.Наименование) + ";"
        + Формат(СтрокаТаблицы.Остаток, "ЧРД=,; ЧГ=0"));
КонецЦикла;

Запись.Закрыть();

Обратите внимание на числовую колонку: Формат() с ЧРД=, задаёт запятую как десятичный разделитель (под русский Excel), а ЧГ=0 убирает группировку разрядов — иначе в файл попадёт неразрывный пробел внутри числа. Если файл пойдёт в систему, которая ждёт точку, ставьте ЧРД=. — но тогда разделителем полей может быть запятая.

Такую выгрузку агент Консоли кода собирает целиком по одной формулировке: «выгрузи остатки по складу Основной в CSV с разделителем ";" и UTF-8» — он напишет запрос под вашу конфигурацию, выполнит его и отдаст готовый файл.

Чтение CSV через ТекстовыйДокумент

Альтернатива для небольших файлов — объект ТекстовыйДокумент: он загружает файл целиком и даёт доступ к строкам по номеру, что удобно, когда нужен произвольный доступ (например, сначала посчитать строки, потом обработать):

Документ = Новый ТекстовыйДокумент;
Документ.Прочитать("C:\Data\import.csv", КодировкаТекста.UTF8);

Для НомерСтроки = 2 По Документ.КоличествоСтрок() Цикл // 1-я строка — шапка
    Поля = СтрРазделить(Документ.ПолучитьСтроку(НомерСтроки), ";", Истина);
    // обработка полей
КонецЦикла;
Прочитать
ИмяФайлапуть к читаемому файлу
ТипФайлакодировка файла (КодировкаТекста.UTF8, "windows-1251")
РазделительСтрокразделитель строк в файле

Минус — весь файл сидит в памяти: на CSV в сотни мегабайт ТекстовыйДокумент не годится, берите потоковое ЧтениеТекста. Ещё нюанс: нумерация строк здесь с единицы, а КоличествоСтрок() возвращает число строк — удобно для прогресса обработки.

Частые ошибки при работе с CSV в 1С

  • Excel открывает выгрузку кракозябрами. Файл записан в UTF-8 без BOM. Лечится выгрузкой через Новый ЗаписьТекста(ИмяФайла, "UTF-8") (BOM добавится автоматически) или кодировкой "windows-1251".
  • Не та кодировка при чтении. Файл в cp1251 прочитан как UTF-8 (или наоборот) — в значениях мусор. Кодировку в ЧтениеТекста задавайте явно, автоопределение работает только при наличии BOM.
  • Запятая vs точка с запятой. Код ждёт «;», а файл пришёл с «,» — весь разбор превращается в одно поле. Проверяйте первую строку файла до цикла и делайте разделитель параметром, а не константой.
  • СтрРазделить на файле с кавычками. Поле "Кабель 3x1,5; бухта" разрежется по «;» внутри значения. Для таких файлов — только посимвольный разбор с учётом кавычек (см. выше).
  • Числа с разделителем дробной части. Число("1,5") в серверном контексте упадёт — сначала СтрЗаменить(Значение, ",", "."). В обратную сторону: Строка(1234,5) даст неразрывный пробел в группах разрядов — в CSV пишите числа через Формат(..., "ЧГ=0").
  • Файл не закрыт. Забытый Закрыть() у ЗаписьТекста — и файл остаётся заблокированным до сборки мусора, а хвост буфера может не доехать до диска. Закрывайте в том же методе, где открыли.

Частые вопросы про CSV в 1С

В какой кодировке выгружать CSV из 1С, чтобы Excel открыл его корректно?

Русский Excel корректно открывает cp1251 ("windows-1251") и UTF-8 с BOM. При выгрузке через Новый ЗаписьТекста(ИмяФайла, "UTF-8") BOM записывается автоматически — этого достаточно. UTF-8 без BOM Excel по двойному клику откроет кракозябрами.

Почему СтрРазделить неправильно разбирает CSV-файл?

СтрРазделить режет строку по всем вхождениям разделителя и не учитывает кавычки. Если поле содержит разделитель внутри кавычек ("Кабель 3x1,5; бухта"), оно развалится на части. Для таких файлов нужен посимвольный разбор с флагом «внутри кавычек».

Какой разделитель использовать в CSV для 1С — запятую или точку с запятой?

Для обмена с русским Excel и российскими системами — точку с запятой: запятая занята под десятичный разделитель чисел. Запятую по RFC 4180 используют для западных API и сервисов. В коде делайте разделитель параметром, чтобы не переписывать обработку.

Тарифы

ИИ Консоль кода 1С

Лайт

Бесплатно
≈ 1,5 млн токенов

Для ознакомления с возможностями

  • Все функции бесплатно на 2 дня +2 дня за подписку на Telegram или Max
  • Полный набор инструментов без урезаний
  • Без ввода карты
Начать бесплатно

Старт

1990 руб. в месяц
≈ 10 млн токенов

Для индивидуального использования

Выбрать тариф

Продвинутый

Популярный выбор
3990 руб. в месяц
≈ 25 млн токенов

Для интенсивного использования или команд

  • До 15 конфигураций
  • Встроенный агент запросов 1С
  • Свои подписки Codex, Claude и любые OpenAI-совместимые
  • Внешние обработки без Конфигуратора
  • Приоритетная техническая поддержка
Выбрать тариф