Почему CSV-файл, созданный в 1С, не загружается в «Честный знак», хотя он идентичен файлу из блокнота?

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

При работе с системой маркировки «Честный знак» (ГИС МТ) программисты часто сталкиваются с ситуацией, когда файл, сформированный программно, отклоняется системой без видимых причин. При этом визуально и даже при побайтовом сравнении файл кажется идентичным тому, что создан вручную в текстовом редакторе. В этой статье мы разберем основные причины такого поведения, начиная от самых тривиальных и заканчивая глубокими техническими нюансами работы платформы 1С с файловой системой и кодировками.

Регистр расширения файла: .csv против .CSV

Разберем ситуацию, которая стала решением в обсуждаемой теме. Несмотря на то, что для операционной системы Windows регистр символов в расширении файла зачастую не имеет значения, веб-сервисы и загрузчики систем мониторинга могут быть построены на базе Linux-стека, где регистр критичен. Проанализируем, как это влияет на загрузку: если система ожидает строго расширение в нижнем регистре .csv, то файл с расширением .CSV может быть проигнорирован или распознан как файл неизвестного типа.

Практический совет: При программном формировании имени файла в 1С всегда принудительно приводите расширение к нижнему регистру. Рассмотрим пример кода:


ИмяФайла = "upload_codes_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd");
ПолноеИмя = ПутьККаталогу + ИмяФайла + ".csv"; // Используем нижний регистр
// Или через функцию НРег, если расширение приходит из настроек
Расширение = ".CSV";
ПолноеИмя = ПутьККаталогу + ИмяФайла + НРег(Расширение);

Проблема невидимых байтов: метка BOM (Byte Order Mark)

Одной из самых коварных проблем при создании текстовых файлов в 1С является автоматическое добавление метки BOM. При использовании кодировки КодировкаТекста.UTF8 платформа 1С добавляет в самое начало файла три байта (EF BB BF). Многие системы обработки данных, включая компоненты ГИС МТ, могут не ожидать этих байтов и воспринимать их как мусор в начале первой строки, что делает первый код маркировки в файле нечитаемым.

Выясним причину, почему обычные программы сравнения их не видят: большинство текстовых редакторов (и даже некоторые простые HEX-утилиты) скрывают BOM, считая его служебной информацией. Чтобы создать «чистый» файл без BOM в 1С, рекомендуется использовать кодировку "CESU-8" или записывать данные через двоичный поток. Рассмотрим, как это сделать правильно:


// Способ 1: Использование кодировки CESU-8 (записывает UTF-8 без BOM)
ЗаписьТекста = Новый ЗаписьТекста(ПолноеИмя, "CESU-8");
ЗаписьТекста.ЗаписатьСтроку(ДанныеКодаМаркировки);
ЗаписьТекста.Закрыть();

// Способ 2: Использование объекта ПотокВПамяти для полного контроля
ДанныеСтрокой = "200415404461";
Поток = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(Поток, КодировкаТекста.UTF8, ПорядокБайтов.BigEndian, Ложь); // Ложь - не писать BOM
ЗаписьДанных.ЗаписатьСтроку(ДанныеСтрокой);
ЗаписьДанных.Закрыть();
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
ДвоичныеДанные.Записать(ПолноеИмя);

Символы перевода строки: CR, LF и особенности 1С

Проанализируем структуру переноса строк. В разных операционных системах используются разные стандарты: в Windows это пара символов CR (возврат каретки) + LF (перевод строки), в Linux — только LF. Система «Честный знак» чаще всего ожидает стандарт Windows. При использовании метода ДобавитьСтроку() в объекте ТекстовыйДокумент, 1С может использовать системный разделитель, который зависит от среды выполнения (сервер на Linux или клиент на Windows).

Чтобы гарантировать корректность, разберем способ принудительной установки разделителя:


Текст = Новый ТекстовыйДокумент;
Текст.ДобавитьСтроку("Код1");
Текст.ДобавитьСтроку("Код2");
// Принудительно задаем разделитель строк перед записью
Текст.Записать(ПолноеИмя, КодировкаТекста.UTF8, Символы.ВК + Символы.ПС);

Если вы копируете текст из других источников, убедитесь, что в нем нет «квадратиков» или лишних символов ПС, которые могут вставляться платформой 1С при определенных манипуляциях со строками. Посмотрите на пример очистки строки перед записью:


ЧистаяСтрока = СтрЗаменить(ИсходнаяСтрока, Символы.ПС, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ВК, "");
// Теперь записываем строку с нужным нам разделителем

Спецсимволы в кодах маркировки (GS1 разделитель)

Коды маркировки DataMatrix содержат специальный непечатный символ GS (Group Separator), имеющий код ASCII 29. При программной сборке кода (склеивании GTIN, серийного номера и «криптохвоста») этот символ часто теряется или заменяется на пробел. Визуально в блокноте файл будет выглядеть правильно, но валидатор «Честного знака» его не примет.

Разберем, как правильно вставить этот символ в строку 1С:


СимволGS = Символ(29);
КодДляЗаписи = "01" + GTIN + "21" + СерийныйНомер + СимволGS + "91" + Ключ + СимволGS + "92" + Подпись;

Важно помнить, что если вы открываете такой файл в обычном блокноте и пересохраняете его, блокнот может «вырезать» непечатные символы или заменить их, что делает файл работоспособным (если система ГИС МТ допускает отсутствие GS в определенных типах документов) или, наоборот, окончательно его портит.

Права доступа и блокировка файла процессом

Иногда проблема заключается не в содержимом файла, а в его доступности для веб-браузера в момент загрузки. Если в коде 1С объект ЗаписьТекста или Файл не был закрыт явно (через Закрыть()), операционная система может удерживать блокировку на чтение. В этом случае файл может отображаться в папке, но при попытке загрузить его на сайт система выдаст ошибку доступа или «пустой» контент.

Алгоритм проверки прав и блокировок:

  1. Всегда используйте блок Попытка...Исключение при работе с файлами.
  2. Убедитесь, что после метода Записать() вызывается метод Закрыть().
  3. Проверьте владельца файла: если файл создан сервером 1С (пользователем USR1CV8), а загрузку выполняет обычный пользователь через браузер, прав на чтение может быть недостаточно (хотя это редкость для временных каталогов).

Итоговый чек-лист для отладки

Если ваш файл по-прежнему не загружается, выполните следующие действия:

  1. Проверьте расширение — оно должно быть строго в нижнем регистре .csv.
  2. Откройте файл в HEX-редакторе и убедитесь, что первые три байта — это данные вашего кода, а не EF BB BF.
  3. Проверьте кодировку — строго UTF-8 (без BOM).
  4. Убедитесь, что в конце строк стоят символы 0D 0A (CRLF).
  5. Проверьте наличие символа Символ(29), если он предусмотрен форматом кода.

Использование этих методов позволит вам создавать полностью совместимые файлы для системы «Честный знак», избегая «загадочных» ситуаций, когда программный код выдает внешне правильный, но фактически невалидный результат.

← На главную