Управляющий символ GS с кодом 29: откуда он в базе 1С и что с ним делать

· 10 мин

Содержание

Символ 29 в 1С — это невидимый управляющий символ GS (Group Separator, шестнадцатеричный код 0x1D). Чаще всего он попадает в базу вместе с кодами маркировки DataMatrix, а ошибка возникает при выгрузке в XML: стандарт XML 1.0 запрещает такие символы, и обмен падает на первой же строке с ним.

Типичная ситуация: склад отсканировал партию обуви, документ провёлся, а ночной обмен с бухгалтерией остановился с сообщением о недопустимом символе. В форме документа всё выглядит чисто — символ не отображается. Исправить ошибку можно тремя путями: очистить данные, закодировать значение для передачи или настроить правила обмена так, чтобы символ не уходил в файл.

Что за символ 29 и почему он мешает базе

Коды от 0 до 31 в таблице ASCII — управляющие. Они не печатаются, а служат командами. Символ 29 исторически разделял группы данных, и именно в этой роли его используют коды маркировки.

В коде DataMatrix для «Честного знака» GS стоит между группами данных: после серийного номера, перед кодом проверки и криптохвостом. Без него система маркировки не разберёт код, поэтому сам по себе символ — не мусор, а часть данных.

Проблемы начинаются, когда такая строка уходит туда, где управляющие символы запрещены.

Куда уходит строкаЧто будет с GS
XML 1.0 (обмен, выгрузки, многие форматы ЭДО)❌ запрещён даже в виде ссылки , файл невалиден
JSON✅ допустим в экранированном виде \u001d
Хранение в реквизите 1С✅ хранится без проблем, но не виден в форме
Поиск, сравнение строк⚠️ две «одинаковые» на экране строки не совпадают
Печать, этикетки⚠️ зависит от шрифта и принтера, может выйти пустой квадрат

В XML 1.0 разрешены только три управляющих символа: табуляция (9), перевод строки (10) и возврат каретки (13). Всё остальное ниже 32 — ошибка разбора. Поэтому то же самое случается с символами 1, 11, 31 и другими, но на практике в 1С чаще всего встречается именно 29.

Текст сообщения зависит от места, где сломалось. При записи файла платформа ругается на недопустимый символ в XML, при чтении принимающая сторона пишет об ошибке разбора XML с номером строки и позиции. Номер позиции — первая подсказка, где искать.

Где искать недопустимые символы: в файле и в базе

Начинать удобнее с файла обмена: там уже известна строка и позиция.

Поиск в файле

  1. Откройте файл в Notepad++.
  2. Включите отображение спецсимволов: Вид → Отображать символы → Отображать все символы. Символ 29 покажется как метка GS в рамке.
  3. Нажмите Ctrl+F, выберите режим поиска «Регулярные выражения» и ищите \x1D.
  4. Посмотрите, в каком теге стоит находка. По соседним тегам почти всегда понятно, какой объект и реквизит виноваты.

Если файл большой и редактор его не тянет, поможет PowerShell:

Select-String -Path "C:\Exchange\Message.xml" -Pattern "\x1D" | Select-Object LineNumber, Line -First 20

Команда выведет номера строк и сами строки. Чтобы найти любые запрещённые управляющие символы, а не только 29, замените шаблон на [\x00-\x08\x0B\x0C\x0E-\x1F].

Поиск в базе

В пользовательском режиме символ не видно, поэтому искать его глазами бесполезно. Нужна обработка или консоль кода. Ниже — функция, которая возвращает позицию первого запрещённого символа или 0, если строка чистая:

Функция ПозицияУправляющегоСимвола(Знач Текст) Экспорт
    Для Позиция = 1 По СтрДлина(Текст) Цикл
        Код = КодСимвола(Текст, Позиция);
        Если Код < 32 И Код <> 9 И Код <> 10 И Код <> 13 Тогда
            Возврат Позиция;
        КонецЕсли;
    КонецЦикла;
    Возврат 0;
КонецФункции

Для строковых реквизитов ограниченной длины можно сначала отобрать кандидатов запросом — так не придётся перебирать весь справочник в цикле:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Номенклатура.Ссылка,
|    Номенклатура.Артикул
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|    Номенклатура.Артикул ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%" + Символ(29) + "%");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Строка(Выборка.Ссылка));
КонецЦикла;

Реквизиты неограниченной длины (комментарии, описания) так не проверяются — их обходите выборкой и функцией выше.

Если в файле обмена символ стоит внутри кода маркировки — это нормальный GS, а не порча. Удалять его из базы нельзя, нужно менять способ передачи (раздел ниже).

Диагностика: выберите симптом

Как очистить данные от управляющих символов

Метод зависит от того, что это за строка. Мусор удаляем, код маркировки упаковываем.

СпособКогда подходитРиски
Удалить GS через СтрЗаменитьНаименования, артикулы, комментарииИспортит код маркировки, если применить к нему
Удалить все символы ниже 32, кроме 9, 10, 13Массовая чистка текста после загрузкиПропадут переносы, если их кодировали иначе
Кодировать строку в Base64Коды маркировки, любые данные, где важен каждый байтПринимающая сторона должна раскодировать
Заменить GS на условный знакРучные выгрузки, отчёты для людейЗнак может встретиться в данных, обратная замена неоднозначна

Удаление одного символа

Самый короткий вариант для заведомо «мусорных» полей:

Объект.Наименование = СтрЗаменить(Объект.Наименование, Символ(29), "");

Удаление всех запрещённых символов

Функция пригодится, если в данных встречается не только 29, но и другие управляющие коды:

Функция БезУправляющихСимволов(Знач Текст) Экспорт
    Части = Новый Массив;
    Для Позиция = 1 По СтрДлина(Текст) Цикл
        Код = КодСимвола(Текст, Позиция);
        Если Код < 32 И Код <> 9 И Код <> 10 И Код <> 13 Тогда
            Продолжить;
        КонецЕсли;
        Части.Добавить(Сред(Текст, Позиция, 1));
    КонецЦикла;
    Возврат СтрСоединить(Части, "");
КонецФункции

СтрСоединить доступна с платформы 8.3.6. На длинных текстах сборка через массив работает заметно быстрее, чем склейка строки в цикле.

Упаковка кода маркировки в Base64

Если код нужно передать целиком, кодируйте его и раскодируйте на приёме:

// при выгрузке
КодДляПередачи = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(КодМаркировки));

// при загрузке
КодМаркировки = ПолучитьСтрокуИзДвоичныхДанных(Base64Значение(КодДляПередачи));

В строке Base64 только латиница, цифры и знаки +, /, =, поэтому XML её принимает. Код после раскодирования совпадает с исходным до байта, GS на месте.

Массовую чистку реквизитов делайте только после резервной копии базы и сначала на копии: если в выборку случайно попадут коды маркировки, восстановить удалённые GS уже не получится.

Правила обмена и проверка данных до записи

Очистка — разовое лечение. Чтобы ошибка не вернулась, ставьте фильтр на входе и на выходе.

На выходе: правила обмена

  • 🔄 В обменах по правилам конвертации чистку ставят в обработчик, который выполняется перед выгрузкой свойства или объекта. Для полей с кодами маркировки — упаковку в Base64 и обратное преобразование в правилах приёма.
  • 🧩 В типовых обменах через формат EnterpriseData правила менять в самой конфигурации не стоит: при обновлении изменения потеряются. Обработчики выносите в расширение.
  • 📄 В своих выгрузках через ЗаписьXML прогоняйте каждую строку через функцию очистки или упаковки перед ЗаписатьТекст.

В типовых конфигурациях на БСП есть готовые служебные функции для поиска и удаления недопустимых символов XML в общем модуле ОбщегоНазначенияКлиентСервер. Перед использованием откройте модуль в конфигураторе и проверьте точное имя и параметры в вашем релизе.

На входе: проверка при записи

Надёжнее всего не пускать мусор в базу. В расширении создайте подписку на событие ПередЗаписью для нужных справочников и документов и чистите в ней строковые реквизиты — наименование, артикул, комментарий. Коды маркировки в эту подписку не включайте.

Мягкий вариант — не чистить молча, а останавливать запись с сообщением, в каком поле найден символ. Так пользователь увидит, откуда пришёл мусор, и перестанет копировать данные тем же способом.

Профилактика при загрузке из Excel, сайтов и сканеров

Символ 29 почти никогда не набирают руками. У него три основных источника.

Сканер штрихкодов

Сканер в режиме эмуляции клавиатуры передаёт символы как нажатия клавиш. GS в этом режиме соответствует сочетанию Ctrl+], и дальше всё зависит от раскладки и программы, в которую идёт ввод:

  • ❌ GS теряется — код маркировки становится невалидным, система маркировки его не примет;
  • ❌ GS превращается в другой символ — код не совпадает с кодом из УПД поставщика;
  • ⚠️ GS попадает в поле поиска или наименования, где ему не место.

Для работы с маркировкой сканер лучше подключить через драйвер в разделе подключаемого оборудования 1С, в режиме COM или USB HID-POS, если модель его поддерживает. В инструкции к сканеру есть настройка передачи GS — проверьте, что она включена.

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

Excel и выгрузки с маркетплейсов

При копировании таблиц из личных кабинетов маркетплейсов, PDF и веб-страниц вместе с текстом приходят невидимые символы. В Excel они не видны, в 1С тоже, а в XML срабатывают.

  • 🧹 В обработке загрузки чистите каждую ячейку функцией БезУправляющихСимволов до записи в справочник.
  • 🔍 В самом Excel проверить ячейку можно формулой =ДЛСТР(A2) — если длина больше видимого числа знаков, внутри есть лишнее.
  • 📥 Файлы CSV и TXT загружайте программно, а не через буфер обмена.

Внешние системы через API

JSON от внешних сервисов легально содержит \u001d, и 1С при чтении превратит его в настоящий символ 29. Если эти данные потом уходят в XML, ошибка всплывёт уже у вас. Решение то же — чистить или упаковывать на границе.

Проверка, что GS больше не вернётся
Выполнено: 0 / 5

Чем символ 29 грозит скорости и целостности данных

На производительность сам символ не влияет: это один знак в строке, индексы и запросы работают как обычно. Вред от него в другом — в рассогласовании данных.

  • 🔁 Дубли. Номенклатура «Ботинки 42» и «Ботинки 42» с GS в конце для базы — разные элементы. Контроль уникальности их пропустит, а пользователь не поймёт, почему у товара два остатка.
  • 🔎 Поиск. Поиск по артикулу или штрихкоду не найдёт запись, если GS есть в одной из строк и нет в другой.
  • 📏 Длина реквизита. Код маркировки с разделителями длиннее на 1-2 символа. Если реквизит строкой ограниченной длины добавлен в доработке, хвост кода обрежется при записи без предупреждения.
  • 🚫 Остановка обмена. Одна запись с символом 29 блокирует весь пакет. Пока её не исправят, в узел-получатель не уходят и все остальные изменения, а очередь растёт.
  • ✅ Маркировка. Удалённый GS в коде маркировки — это уже испорченные данные: код не пройдёт проверку при продаже или выводе из оборота.

Если обмен стоит давно, после исправления данных не ждите расписания: запустите обмен вручную и убедитесь, что пакет ушёл целиком. Иначе следующая ошибка в той же очереди останется незамеченной до утра.

Если ошибка не уходит

Бывает, что символ 29 вычистили, а обмен всё равно падает.

  1. Посмотрите номер позиции в новом сообщении. Если он другой, в данных есть ещё одна запись с запрещённым символом — возможно, с другим кодом. Ищите шаблоном [\x00-\x08\x0B\x0C\x0E-\x1F].
  2. Проверьте табличные части. Чаще всего чистят реквизиты шапки и забывают про строки документа, где и лежат коды маркировки.
  3. Проверьте зарегистрированные изменения. Пакет мог сформироваться до исправления. После чистки данных объект нужно перезаписать, чтобы изменение снова зарегистрировалось к выгрузке.
  4. Проверьте сторону получателя. Если ошибка разбора возникает у получателя на файле, который у вас проходит проверку, он может читать файл в другой кодировке или по более строгой схеме.
Можно ли удалить GS из кода маркировки, чтобы обмен прошёл?
Нет. Без разделителя код не пройдёт проверку в системе маркировки. Код нужно упаковать для передачи, а не обрезать.
Почему в форме 1С символа не видно, а обмен на него ругается?
Управляющие символы не отображаются в полях ввода. Строка выглядит обычной, но в XML-файл символ попадает как есть и делает файл невалидным.
Влияет ли символ 29 на поиск по штрихкоду?
Да. Если в базе штрихкод сохранён с GS, а сканер передаёт его без разделителя (или наоборот), поиск не найдёт товар. Формат хранения и формат ввода должны совпадать.
Помогут ли тестирование и исправление информационной базы?
Нет. Для платформы такая строка корректна, структурной ошибки в базе нет. Исправляют сами данные или способ их выгрузки.
Бывают ли похожие ошибки с другими кодами?
Да, любой управляющий символ с кодом ниже 32, кроме 9, 10 и 13, ломает XML 1.0 так же. Чаще других, кроме 29, встречаются символы 1, 11 и 12 из скопированного текста.