Почему при выгрузке из 1С 7.7 в Frontol в конце строк появляются лишние пробелы и как это исправить

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

При организации обмена данными между 1С:Предприятием 7.7 и кассовым программным обеспечением (например, Frontol или другие продукты Атол) разработчики часто сталкиваются со странным поведением системы: в сформированном текстовом файле в конце строк появляются лишние пробелы. Эти пробелы не видны в отладчике 1С, их не удаляет функция СокрЛП(), и они могут возникать хаотично — в одних строках они есть, в других нет.

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

Выясняем причину: особенности объекта Текст

Проблема кроется не в ошибке программного кода разработчика, а в особенностях реализации встроенного объекта Текст в платформе 1С 7.7. Рассмотрим основные причины:

  1. Выравнивание блоков памяти: При записи файла методом Записать() движок 1С 7.7 может дополнять строки пробелами до определенной кратности байт (часто до 4-х байт или четного числа). Это связано с низкоуровневыми механизмами оптимизации работы с памятью в старых версиях Windows, под которые проектировалась платформа.
  2. Буферизация: Объект Текст накапливает строки во внутреннем буфере. При сбросе этого буфера на диск иногда происходит некорректное заполнение остатка "пустого" места в блоке символами пробела.
  3. Символы конца строки: Иногда то, что воспринимается как пробелы, является результатом интерпретации текстовым редактором невидимых символов CR (возврат каретки) и LF (перевод строки). Однако в случае с 1С 7.7 чаще всего речь идет именно о реальных символах пробела (код 32).

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

Решение №1: Использование Scripting.FileSystemObject (FSO)

Наиболее простым и эффективным способом обойти ограничения объекта Текст является использование системного объекта Windows Scripting.FileSystemObject. Он позволяет записывать данные напрямую в поток файла, минуя механизмы выравнивания 1С.

Разберем пример кода для реализации этого метода:


// Создаем объект для работы с файловой системой
Попытка
    fso = СоздатьОбъект("Scripting.FileSystemObject");
Исключение
    Сообщить("Не удалось создать объект FSO! Проверьте права доступа.");
    Возврат;
КонецПопытки;

// Создаем текстовый файл (ПутьКФайлу, Перезаписывать, Кодировка: 0 - ASCII, -1 - Unicode)
// Для Frontol обычно требуется Windows-1251 (ASCII)
ИмяФайла = КаталогОбмена + ИмяФайлаТоваров;
file = fso.CreateTextFile(ИмяФайла, -1, 0);

СписокТоваров.ВыбратьСтроки();
Пока СписокТоваров.ПолучитьСтроку() = 1 Цикл
    // Формируем строку по формату Атол
    СтрЗагрузки = "36943;;Товар;Товар;495.00;6.000;0;0,1,1,1,1;0;;;;1;1.000;;8206;1;6;;;;0;1;0;0;200172;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0;0;;2;;;;;;;;;";
    
    // Записываем строку без лишних добавлений
    file.WriteLine(СокрЛП(СтрЗагрузки));
КонецЦикла;

// Обязательно закрываем файл для очистки буферов системы
file.Close();

Преимущество этого метода: Метод WriteLine записывает ровно ту последовательность символов, которую вы передали, добавляя только стандартный символ переноса строки в конце. Лишние пробелы "от платформы" здесь не появятся.

Решение №2: Использование ADODB.Stream для полного контроля

Если вам требуется еще более тонкий контроль (например, если Frontol требует специфическую кодировку UTF-8 без BOM или Windows-1251 без каких-либо отклонений), рекомендуется использовать объект ADODB.Stream. Этот метод гарантирует запись "байт в байт".

Проанализируем шаги реализации через ADO:


Stream = СоздатьОбъект("ADODB.Stream");
Stream.Type = 2; // Тип - текстовый
Stream.Charset = "windows-1251"; // Явно задаем кодировку
Stream.Open();

СписокТоваров.ВыбратьСтроки();
Пока СписокТоваров.ПолучитьСтроку() = 1 Цикл
    СтрЗагрузки = СформироватьСтрокуДляФронтола(); // Ваша функция формирования
    Stream.WriteText(СокрЛП(СтрЗагрузки), 1); // 1 - признак добавления переноса строки
КонецЦикла;

Stream.SaveToFile(КаталогОбмена + ИмяФайлаТоваров, 2); // 2 - перезаписать существующий
Stream.Close();

Этот способ считается "золотым стандартом" при выгрузке данных из старых версий 1С, так как он полностью изолирует процесс записи от внутренних алгоритмов V77.EXE.

Как проверить результат?

После того как мы внедрили один из предложенных методов, важно убедиться в отсутствии пробелов. Мы рекомендуем использовать специализированные текстовые редакторы (например, Notepad++), так как обычный "Блокнот" может скрывать многие детали.

Выполните следующие действия для проверки:

  1. Откройте полученный файл в Notepad++.
  2. В верхнем меню выберите Вид -> Отображение символов -> Отображать все символы.
  3. Внимательно посмотрите на конец каждой строки. Пробелы будут отображаться маленькими оранжевыми точками. Сразу за последним символом точки (разделителя ;) должны идти символы CR и LF.
  4. Если между последней точкой с запятой и символом CRLF нет других знаков — проблема успешно решена.

Рекомендации по визуальному контролю в 1С

Если вы все же хотите использовать штатный объект Текст и пытаетесь понять, на каком этапе возникают пробелы, используйте метод Показать(). Это позволит открыть сформированный текстовый объект во встроенном редакторе 1С еще до его записи на диск. Если в редакторе 1С пробелов нет, а в файле на диске они есть — значит, их добавляет именно метод Записать(), и переход на FSO или ADO является единственным верным выходом.

Важный нюанс: Для кассового ПО Frontol лишние пробелы после последнего разделителя обычно не критичны, но они могут привести к непредсказуемым ошибкам, если пробел попадет в поле с наименованием или артикулом. Чистота файла обмена — залог стабильной работы кассового узла.

← На главную