Как удалить лишние символы перевода строки при выгрузке данных в CSV из 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При выгрузке данных из 1С в формат CSV (или любой другой текстовый формат) разработчики часто сталкиваются с проблемой появления лишних пустых строк в конце файла. Это может стать критической ошибкой, если принимающая сторона (например, банковский терминал, веб-сервис или складская система) ожидает строго структурированные данные и не умеет игнорировать пустые строки. Рассмотрим подробно причины возникновения этой проблемы и разберем несколько эффективных способов её решения.

Анализ причины возникновения лишних строк

Проанализируем ситуацию, описанную в теме. Разработчик формирует текстовую строку внутри цикла, добавляя Символы.ПС (перевод строки) после каждой записи. В конце формирования используется объект ЗаписьТекста и его метод ЗаписатьСтроку(). Выясним, почему в итоге в конце файла появляются два перевода строки.

Во-первых, метод ЗаписатьСтроку(Текст) в 1С работает следующим образом: он записывает переданную строку в файл и автоматически добавляет к ней системный символ перевода строки (CRLF или LF). Если переменная Текст уже содержит в конце символ Символы.ПС, добавленный вручную в цикле, то в итоговом файле мы получим два идущих подряд переноса.

Во-вторых, логика условий внутри цикла часто дает сбои при определении "последней итерации", особенно если в выборке присутствуют условия Продолжить, которые нарушают ожидаемый счетчик записей.

Способ 1. Использование метода Записать() вместо ЗаписатьСтроку()

Это самый простой и быстрый способ исправить ситуацию, если вы уже сформировали строку целиком. Метод Записать() записывает данные в файл "как есть", не добавляя ничего от себя. Рассмотрим пример корректировки кода:


Кодировка = КодировкаТекста.UTF8;
ТекстовыйФайлЗапись = Новый ЗаписьТекста(ИмяФайла, Кодировка);

// Вместо ТекстовыйФайлЗапись.ЗаписатьСтроку(Текст);
// Используем:
ТекстовыйФайлЗапись.Записать(Текст); 

ТекстовыйФайлЗапись.Закрыть();

При таком подходе, если вы контролируете добавление Символы.ПС внутри своего алгоритма формирования переменной Текст, в конце файла будет ровно столько переносов, сколько вы добавили сами. Чтобы убрать последний перенос, можно воспользоваться функцией СокрП(), которая удалит все пробелы и символы перевода строки в конце текста.

Способ 2. Оптимизация сборки строки через Массив (Best Practice)

Рассмотрим более профессиональный и производительный метод. Сложение строк через оператор "+" (конкатенация) в цикле — это плохая практика для 1С. При каждом сложении создается новая копия всей строки в памяти, что на больших объемах данных (тысячи строк) приводит к существенному замедлению системы.

Вместо этого мы рекомендуем использовать массив строк и метод СтрСоединить(). Этот метод автоматически вставляет разделитель между элементами массива, но не добавляет его после последнего элемента. Проанализируем пример кода:


МассивРезультат = Новый Массив;

Пока Выборка.Следующий() Цикл
    // Проверки данных
    Если Выборка.Количество <= 0 Или ПустаяСтрока(Выборка.Номенклатура.Артикул) Тогда
        Продолжить;
    КонецЕсли;

    // Формируем строку одной записи
    ТекущаяСтрока = СокрЛП(Выборка.Номенклатура.Артикул) + ";" + Выборка.Количество;
    МассивРезультат.Добавить(ТекущаяСтрока);
КонецЦикла;

// Соединяем все строки через перевод строки
ИтоговыйТекст = СтрСоединить(МассивРезультат, Символы.ПС);

// Записываем файл без лишних переносов
Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
Запись.Записать(ИтоговыйТекст);
Запись.Закрыть();

Преимущества этого метода:

  1. Высокая скорость работы с памятью.
  2. Отсутствие необходимости проверять, является ли текущая итерация цикла последней.
  3. Гарантированное отсутствие лишнего перевода строки в самом конце файла.

Способ 3. Использование специализированного объекта ЗаписьCSV

Если вы работаете на платформе 8.3.6 и выше, самым правильным решением будет использование встроенного объекта ЗаписьCSV. Этот объект берет на себя все сложности форматирования, включая экранирование кавычек и управление разделителями строк.

Разберем, как это работает:


ПараметрыЗаписи = Новый ПараметрыЗаписиCSV(Символы.ПС, ";", """");
ЗаписьCSV = Новый ЗаписьCSV;
ЗаписьCSV.Открыть(ИмяФайла, КодировкаТекста.UTF8, ПараметрыЗаписи);

// Записываем заголовок
ЗаписьCSV.ЗаписатьСтроку("Артикул;Свободный остаток");

Пока Выборка.Следующий() Цикл
    // Логика фильтрации...
    
    // Объект сам сформирует строку и добавит нужные разделители
    МассивДанных = Новый Массив;
    МассивДанных.Добавить(СокрЛП(Выборка.Номенклатура.Артикул));
    МассивДанных.Добавить(Выборка.Количество);
    
    ЗаписьCSV.ЗаписатьСтроку(МассивДанных);
КонецЦикла;

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

Использование ЗаписьCSV не только решает проблему с переносами строк, но и защищает ваш файл от "развала" структуры, если, например, в артикуле случайно окажется точка с запятой или кавычка. Платформа автоматически заключит такие поля в кавычки согласно стандарту RFC 4180.

Важные нюансы: Кодировка и BOM

Проанализируем еще один скрытый фактор. При использовании кодировки КодировкаТекста.UTF8 1С может добавлять в начало файла метку BOM (Byte Order Mark). Некоторые системы загрузки воспринимают эти три байта в начале первой строки как мусор или некорректный артикул.

Если ваша принимающая система жалуется на первую строку, попробуйте явно указать использование UTF-8 без BOM. В современных версиях платформы это делается при создании объекта ЗаписьТекста или ЗаписьCSV путем выбора соответствующего уточнения в параметрах кодировки.

Заключение

Подведем итог. Чтобы избежать появления лишних пустых строк в конце файла, следуйте трем правилам:

← На главную