Почему метод ДобавитьСтроку в 1С 7.7 разбивает запись на несколько строк и как это исправить?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Разберем детально, почему это происходит, как обнаружить проблемные данные в информационной базе и какими способами можно исключить разрывы строк при формировании файла.

Причина возникновения проблемы

Проанализируем исходный код формирования строки:


_текстКлиенты = СоздатьОбъект("Текст");
_текстКлиенты.КодоваяСтраница(0); 
_текстКлиенты.ДобавитьСтроку(_стрКлиенты); 
_текстКлиенты.Записать(мПутьВыгрузки + "clients.csv");

Метод ДобавитьСтроку() объекта Текст помещает переданную строковую переменную в буфер без дополнительной обработки. Если внутри строковых реквизитов (например, Наименование, ПолноеНаименование или Адрес) уже содержатся невидимые управляющие символы перевода строки — Симв(10) (Line Feed, LF) или Симв(13) (Carriage Return, CR), метод Записать() воспринимает их как физическое окончание строки и переносит оставшуюся часть текста на новую позицию.

Такие символы обычно попадают в базу данных следующими путями:

  1. Копирование текстовой информации пользователями через буфер обмена из сторонних источников (веб-страниц, документов Excel, писем).
  2. Случайное нажатие клавиш Enter или Shift+Enter в многострочных полях ввода форм справочников или документов.
  3. Некорректный предыдущий импорт данных из внешних систем.

Способ 1. Построчная разборка и объединение через функции платформы

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


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

Используем данную функцию перед объединением реквизитов в строку выгрузки:


ИмяОчищенное = ОчиститьПереносыСтрок(СпрКлиенты.Наименование);
АдресОчищенный = ОчиститьПереносыСтрок(СпрКлиенты.ЮрАдрес);
_стрКлиенты = Строка(СпрКлиенты.Код) + ";" + ИмяОчищенное + ";" + АдресОчищенный;
_текстКлиенты.ДобавитьСтроку(_стрКлиенты);

Способ 2. Замена управляющих символов Симв(13) и Симв(10)

Поскольку в синтаксисе встроенного языка 1С 7.7 отсутствует встроенная функция глобального контекста для автозамены строк, напишем собственную процедуру замены недопустимых байтов Симв(10) и Симв(13) на пробелы:


Функция ЗаменитьСимвол(СтрокаТекста, ИскомыйСимвол, СимволЗамены)
    Перем Поз, ТекСтрока;
    ТекСтрока = СтрокаТекста;
    Поз = Найти(ТекСтрока, ИскомыйСимвол);
    Пока Поз > 0 Цикл
        ТекСтрока = Лев(ТекСтрока, Поз - 1) + СимволЗамены + Сред(ТекСтрока, Поз + 1);
        Поз = Найти(ТекСтрока, ИскомыйСимвол);
    КонецЦикла;
    Возврат ТекСтрока;
КонецФункции

Функция ПодготовитьСтрокуДляCSV(ИсходнаяСтрока)
    Перем Рез;
    Рез = ЗаменитьСимвол(ИсходнаяСтрока, Симв(13), " ");
    Рез = ЗаменитьСимвол(Рез, Симв(10), " ");
    Возврат СокрЛП(Рез);
КонецФункции

Способ 3. Поиск и исправление некорректных символов в справочниках базы

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


Процедура ПроверитьСправочник()
    Перем Спр, Сч, ИскСимв, ДлинаСтр, ТекНаименование;
    Спр = СоздатьОбъект("Справочник.Контрагенты");
    Спр.ВыбратьЭлементы(0);
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        Если Спр.ЭтоГруппа() = 1 Тогда
            Продолжить;
        КонецЕсли;
        
        ТекНаименование = Спр.Наименование;
        ДлинаСтр = СтрДлина(ТекНаименование);
        Для Сч = 1 По ДлинаСтр Цикл
            ИскСимв = Сред(ТекНаименование, Сч, 1);
            Если (КодСимв(ИскСимв) = 10) Или (КодСимв(ИскСимв) = 13) Тогда
                Сообщить("Найден перевод строки в элементе: " + Спр.ТекущийЭлемент() + " (Код: " + Спр.Код + ")");
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры

Рекомендации по формированию CSV-файлов

  1. Контроль разделителей: при выгрузке текстовых полей следите за тем, чтобы внутри данных не встречался символ-разделитель (например, точка с запятой ;). Если он присутствует, значение поля необходимо обрамлять двойными кавычками.
  2. Экранирование кавычек: если внутри текста содержатся двойные кавычки ", по спецификации формата CSV их следует заменять на парные двойные кавычки "".
  3. Проверка кодовой страницы: метод КодоваяСтраница(0) сохраняет файл в кодировке Windows (ANSI, CP1251). Если внешняя система требует кодировку DOS (CP866), используйте параметр КодоваяСтраница(1).
← На главную