Почему при сохранении текстового файла в 1С появляются лишние символы и как правильно выгрузить данные в кодировке DOS

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

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

Выясняем причину появления символов «я╗┐»

Если при открытии текстового файла вы видите в начале символы я╗┐, это означает, что файл сохранен в кодировке UTF-8 с меткой BOM. Рассмотрим подробнее, что это такое. BOM (Byte Order Mark) — это специальный маркер последовательности байтов (три байта: EF BB BF), который 1С по умолчанию добавляет в начало файла UTF-8, чтобы другие программы могли автоматически определить кодировку.

Однако программы, ожидающие формат DOS (OEM), не знают о существовании Unicode и интерпретируют эти три байта как обычные текстовые символы. В кодировке Windows-1251 они выглядят как я╗┐, а в кодировке DOS могут выглядеть как графические символы или вызывать ошибку «Символ не из DOS-кодировки».

Проанализируем ситуацию: в платформе 1С 8.3 объект ТекстовыйДокумент при вызове метода Записать() без указания параметров по умолчанию использует именно UTF-8 с BOM. Это и становится причиной отказа в приеме файла сторонним софтом.

Решение 1: Использование метода Записать объекта ТекстовыйДокумент

Самый простой способ исправить проблему — явно указать кодировку при сохранении. В 1С для DOS-кодировки (CP866) предусмотрено системное перечисление КодировкаТекста.OEM. Рассмотрим, как должен выглядеть исправленный код:


// Вместо обычного Текст.Записать(ПутьКФайлу);
// Используем явное указание кодировки
Текст.Записать(ИмяФайла, КодировкаТекста.OEM);

В данном случае платформа 1С самостоятельно выполнит конвертацию из внутреннего Unicode в кодировку CP866 и не будет добавлять никаких маркеров BOM в начало файла. Это решит проблему в 90% случаев.

Решение 2: Использование объекта ЗаписьТекста

Если использование объекта ТекстовыйДокумент кажется недостаточно гибким, или вам нужно более тонко управлять процессом записи (например, добавлять строки по одной сразу в файл), лучше использовать объект ЗаписьТекста. Этот объект позволяет явно управлять признаком записи BOM.

Разберем по шагам, как правильно реализовать выгрузку через ЗаписьТекста:


ИмяФайла = "C:\Upload\BankData.txt";

// Создаем объект записи текста. 
// Параметры: Путь, Кодировка, РазделительСтрок, Дописывать, ПометкаПорядкаБайтов
НоваяЗапись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.OEM, Символы.ПС, Ложь, Ложь);

// Формируем строки и записываем их
Стр1 = "Первая строка данных";
Стр2 = "Вторая строка данных";

НоваяЗапись.ЗаписатьСтроку(Стр1);
НоваяЗапись.ЗаписатьСтроку(Стр2);

// Обязательно закрываем файл
НоваяЗапись.Закрыть();

Обратите внимание на последний параметр конструктора — Ложь. Это и есть управление BOM. Хотя для кодировки OEM он игнорируется, явное указание помогает избежать ошибок в будущем при переходе на UTF-8.

Решение 3: Радикальный метод через ДвоичныеДанные

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

Посмотрим на пример реализации:


// 1. Собираем весь текст в одну переменную
ВесьТекст = "Строка1" + Символы.ПС + "Строка2";

// 2. Преобразуем строку в двоичные данные, указывая нужную кодировку
ДанныеДляФайла = ПолучитьДвоичныеДанныеИзСтроки(ВесьТекст, "cp866", Ложь);

// 3. Записываем на диск
ДанныеДляФайла.Записать(ПутьКФайлу);

Этот метод гарантирует, что в файл не попадет ни одного байта, который вы не планировали туда записывать. Это самый «чистый» способ выгрузки.

Важные нюансы при работе с кодировкой DOS (OEM)

При выгрузке данных в формате DOS следует помнить о нескольких критических моментах, которые могут привести к потере данных:

  1. Ограниченный набор символов: Кодировка CP866 содержит только стандартную кириллицу, латиницу и ограниченный набор спецсимволов. Если в вашей информационной базе в именах сотрудников есть специфические символы (например, украинская «і», белорусская «ў», «длинное тире» — или «кавычки-елочки» «»), при конвертации в DOS они превратятся в знаки вопроса ?.
  2. Предварительная очистка текста: Перед записью рекомендуется программно заменить «сложные» символы на их простые аналоги.

Проанализируем пример функции для предварительной подготовки строки:


Функция ПодготовитьСтрокуДляDOS(ИсходнаяСтрока)
    
    Результат = ИсходнаяСтрока;
    
    // Заменяем типографские кавычки на обычные
    Результат = СтрЗаменить(Результат, "«", """");
    Результат = СтрЗаменить(Результат, "»", """");
    
    // Заменяем длинное тире на дефис
    Результат = СтрЗаменить(Результат, "—", "-");
    
    // Удаляем неразрывные пробелы (часто встречаются в суммах)
    Результат = СтрЗаменить(Результат, Символы.НПП, " ");
    
    Возврат Результат;
    
КонецФункции

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

Чтобы убедиться, что проблема решена, не стоит использовать стандартный Windows Блокнот (Notepad), так как он часто «интеллектуально» скрывает BOM или неправильно определяет кодировку. Мы рекомендуем следующие инструменты:

Подводя итог: для корректной выгрузки в DOS всегда используйте явное указание кодировки КодировкаТекста.OEM в методах записи. Это избавит вас от проблем с «крокозябрами» и обеспечит совместимость с внешними банковскими и государственными системами.

← На главную