При интеграции 1С с кассовым программным обеспечением Frontol 5/6 для загрузки маркетинговых акций и скидок (команды загрузки маркетинговых мероприятий) требуется формировать текстовые пакеты данных. В соответствии со спецификацией формата обмена Frontol, значения внутри одного поля (например, перечень кодов товаров, участвующих в акции) должны разделяться специальным типографским маркером списка — точкой (символ Bullet «•»).
При попытке напрямую скопировать этот символ в код модуля или макет разработчики часто сталкиваются с тем, что вместо ожидаемого разделителя в строке и результирующем файле появляются пробелы или некорректные знаки. Разберем по шагам, почему возникает эта проблема, как работает кодирование символов в платформе 1С:Предприятие и как правильно сформировать строку обмена.
Проанализируем ситуацию, возникающую при формировании строки. Ошибки при вставке символа «•» происходят по двум основным причинам:
Символ() принимает в качестве параметра строго числовой код (тип Число). Если разработчик вызывает конструкцию вида Символ("8226"), платформа выполняет некорректное приведение типа, что приводит к формированию невалидного символа или пустого значения.0x2022, что в десятичной системе соответствует числу 8226. В то же время в стандартной однобайтовой кодовой странице Windows-1251 этот же глиф кодируется байтом 0x95 (в десятичной системе — 149). Попытка вызвать Символ(149) внутри 1С приведет к созданию управляющего непечатного символа Unicode, а не визуального маркера.Рассмотрим базовый вариант решения задачи с использованием явного указания десятичного Unicode-кода символа. Передаем в функцию Символ() целочисленное значение 8226:
// Формирование разделителя списка Frontol
Разделитель = Символ(8226);
// Конкатенация строки
СтрокаТоваров = "";
Для Каждого ТекКод Из МассивКодов Цикл
Если ЗначениеЗаполнено(СтрокаТоваров) Тогда
СтрокаТоваров = СтрокаТоваров + Разделитель + ТекКод;
Иначе
СтрокаТоваров = ТекКод;
КонецЕсли;
КонецЦикла;
Обратите внимание: параметр функции указывается без кавычек как числовой литерал.
Если в маркетинговой акции участвует большое количество позиций, последовательная конкатенация строк через оператор + в цикле приводит к нерациональному выделению оперативной памяти. Оптимизируем алгоритм с помощью встроенной функции СтрСоединить():
// Заполняем массив кодов товаров для акции
МассивКодов = Новый Массив;
МассивКодов.Добавить("2142");
МассивКодов.Добавить("886142");
МассивКодов.Добавить("885142");
МассивКодов.Добавить("884142");
// Объединяем массив в строку с разделителем Bullet
СтрокаТоваров = СтрСоединить(МассивКодов, Символ(8226));
Такой подход делает код компактным, защищает от появления лишних разделителей в начале или конце строки и выполняется значительно быстрее при больших объемах данных.
Выясним причину, по которой кассовое ПО может отклонить сформированный файл, даже если в памяти 1С строка сформирована корректно. Текстовый протокол обмена Frontol по умолчанию ожидает файл в однобайтовой кодировке Windows-1251 (ANSI).
Разберем правила сохранения файла выгрузки:
ЗаписьТекста или метода Записать() объекта ТекстовыйДокумент необходимо явно указывать кодировку КодировкаТекста.ANSI (или строковый идентификатор "windows-1251").Символ(8226) в один байт со значением 0x95 (149), который и ожидает парсер Frontol.0xE2 0x80 0xA2, что нарушит структуру полей протокола обмена.Посмотрим на пример корректной записи файла выгрузки:
ПутьКФайлу = "C:\Frontol\Exchange\goods.txt";
Запись = Новый ЗаписьТекста;
// Указываем кодировку ANSI для корректной трансляции спецсимволов
Запись.Открыть(ПутьКФайлу, КодировкаТекста.ANSI);
// Формируем и записываем команду загрузки акции
СтрокаКоманды = "$$$ADDMARKETINGEVENTS" + Символы.ПС + СтрокаТоваров;
Запись.ЗаписатьСтроку(СтрокаКоманды);
Запись.Закрыть();
Для контроля корректности выгрузки рекомендуется открыть созданный файл в шестнадцатеричном (HEX) редакторе: между кодами товаров должен находиться единичный байт со значением 95.