Как выгрузить данные на монгольском языке из 1С в DBF или текстовый формат без появления знаков вопроса?

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

При выгрузке данных в формат DBF разработчики часто сталкиваются с неприятной проблемой: вместо специфических символов национальных алфавитов (например, монгольского или казахского) в результирующем файле отображаются знаки вопроса (?). Проанализируем причины этой проблемы и подробно разберем несколько способов ее решения.

Выясняем причину проблемы: почему появляются знаки вопроса?

Для работы с файлами DBF в платформе 1С используется встроенный объект XBase. Свойство этого объекта Кодировка принимает только значения из перечисления КодировкаXBase.ANSI или КодировкаXBase.OEM. Исторически формат DBF (dBase III/IV) ориентирован на использование однобайтовых кодовых страниц и не поддерживает Юникод (UTF-8) на уровне своей спецификации.

Монгольская кириллица содержит уникальные буквы, которых нет в стандартном русском алфавите: это символы Ө, ө, Ү, ү. При выгрузке данных в стандартной русскоязычной кодировке Windows-1251 (ANSI) или CP866 (OEM) платформа 1С не находит соответствия для этих специфических букв в кодовой таблице и автоматически заменяет их знаками вопроса. Ситуация усугубляется, если на сервере или компьютере, где выполняется выгрузка, установлена стандартная русская локаль операционной системы для программ, не поддерживающих Юникод (System Locale).

Рассмотрим стандартный пример кода, который приводит к искажению монгольского текста:


НовыйФайл = Новый XBase;
НовыйФайл.Кодировка = КодировкаXBase.OEM; // Использование OEM кодировки (CP866)
НовыйФайл.Поля.Добавить("REG", "S", 100);  // Регистратор
НовыйФайл.Поля.Добавить("NOMERSTR", "N", 9); // Номер строки
НовыйФайл.Поля.Добавить("ACTIVE", "L" );    // Активность
НовыйФайл.Поля.Добавить("PERIOD", "D");     // Период
НовыйФайл.Поля.Добавить("REG1", "S", 100);  // Регистратор1
НовыйФайл.Поля.Добавить("ORG", "S", 5);     // Организация
Путь = "C:\file.DBF";
НовыйФайл.СоздатьФайл(Путь);
НовыйФайл.Записать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    НовыйФайл.Добавить();
    НовыйФайл.REG = Строка(ВыборкаДетальныеЗаписи.Регистратор);
    НовыйФайл.NOMERSTR = ВыборкаДетальныеЗаписи.НомерСтроки;
    НовыйФайл.ACTIVE = ВыборкаДетальныеЗаписи.Активность;
    НовыйФайл.PERIOD = ВыборкаДетальныеЗаписи.Период1;
    НовыйФайл.REG1 = ВыборкаДетальныеЗаписи.Регистратор1;
    НовыйФайл.ORG = ВыборкаДетальныеЗаписи.Организация;
КонецЦикла;
НовыйФайл.ЗакрытьФайл();

Решение 1. Переход на современный формат обмена (CSV в UTF-8)

Если со стороны принимающей системы нет жесткого требования использовать устаревший формат DBF, лучшим решением будет переход на выгрузку в CSV. Этот текстовый формат позволяет сохранять данные с разделителями в кодировке UTF-8, которая полностью поддерживает любые национальные алфавиты без потери качества.

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


ПутьКФайлу = "C:\file.csv";
// Создаем объект ЗаписьТекста с явным указанием кодировки UTF-8
ФайлТекст = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);

// Записываем строку заголовков полей
СтрокаЗаголовка = "REG;NOMERSTR;ACTIVE;PERIOD;REG1;ORG";
ФайлТекст.ЗаписатьСтроку(СтрокаЗаголовка);

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    // Формируем текстовые представления полей
    ТекстREG = СтрЗаменить(Строка(ВыборкаДетальныеЗаписи.Регистратор), ";", " "); // Исключаем разделители
    ТекстNOMERSTR = Формат(ВыборкаДетальныеЗаписи.НомерСтроки, "ЧГ=0");
    ТекстACTIVE = ?(ВыборкаДетальныеЗаписи.Активность, "1", "0");
    ТекстPERIOD = Формат(ВыборкаДетальныеЗаписи.Период1, "ДФ=dd.MM.yyyy");
    ТекстREG1 = СтрЗаменить(Строка(ВыборкаДетальныеЗаписи.Регистратор1), ";", " ");
    ТекстORG = Строка(ВыборкаДетальныеЗаписи.Организация);
    
    // Собираем строку данных с разделителем-точкой с запятой
    ТекущаяСтрока = ТекстREG + ";" + ТекстNOMERSTR + ";" + ТекстACTIVE + ";" + ТекстPERIOD + ";" + ТекстREG1 + ";" + ТекстORG;
    ФайлТекст.ЗаписатьСтроку(ТекущаяСтрока);
КонецЦикла;

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

Такой подход полностью решает проблему с кодировками: монгольские символы сохраняются в первозданном виде и будут корректно считаны любой современной программой (например, Microsoft Excel).

Решение 2. Изменение региональных настроек операционной системы (для DBF)

Если выгрузка в DBF строго обязательна, нам необходимо заставить платформу 1С использовать расширенную кодовую страницу Windows-1251 при записи ANSI-файлов. Для этого на сервере 1С (или на локальном ПК, где выполняется обработка) нужно изменить системную локаль ОС:

  1. Откройте Панель управления Windows и перейдите в раздел Региональные стандарты (Region).
  2. Перейдите на вкладку Дополнительно (Administrative).
  3. В группе параметров Язык программ, не поддерживающих Юникод (Language for non-Unicode programs) нажмите кнопку Изменить язык системы (Change system locale).
  4. Выберите из списка Монгольский (кириллица, Монголия) или Казахский (Казахстан).
  5. Нажмите ОК и перезагрузите операционную систему.

После перезагрузки 1С при создании DBF с кодировкой КодировкаXBase.ANSI задействует кодовую страницу с расширенным набором кириллицы. Специфические символы монгольского языка запишутся корректно.

Решение 3. Программная подмена символов байт-кодами из расширенной таблицы Windows-1251

В расширенной версии кодировки Windows-1251 специфические монгольские буквы занимают определенные байтовые позиции. Если системная локаль не настроена на монгольский язык, мы можем программно заменить Unicode-символы на соответствующие им байт-коды перед передачей данных в объект XBase. Для этого используется встроенная функция 1С Симв().

Определим соответствие кодов:

Реализуем вспомогательную функцию для подготовки строковых данных:


Функция КонвертироватьМонгольскийДляDBF(Знач ИсходныйТекст) Экспорт
    Результат = ИсходныйТекст;
    Результат = СтрЗаменить(Результат, "Ө", Симв(165));
    Результат = СтрЗаменить(Результат, "ө", Симв(180));
    Результат = СтрЗаменить(Результат, "Ү", Симв(175));
    Результат = СтрЗаменить(Результат, "ү", Симв(191));
    Возврат Результат;
КонецФункции

Перед записью значений в поля файла DBF пропускайте все строки через эту функцию:


НовыйФайл.REG = КонвертироватьМонгольскийДляDBF(Строка(ВыборкаДетальныеЗаписи.Регистратор));

Важное примечание: Чтобы принимающая программа (например, Excel или специализированный просмотрщик DBF) смогла прочитать эти символы без искажений, на стороне получателя также должен использоваться шрифт и региональные настройки, поддерживающие расширенную кириллицу.

Решение 4. Выгрузка в формат XLSX или XML/JSON

Помимо CSV, существуют другие современные форматы обмена данными, которые поддерживают Юникод "из коробки" и полностью исключают появление знаков вопроса:

  1. Формат XLSX: Вы можете сформировать данные в объект 1С ТабличныйДокумент и сохранить его на диск методом ТабличныйДокумент.Записать("Путь", ТипФайлаТабличногоДокумента.XLSX).
  2. Форматы XML или JSON: Используйте высокопроизводительные встроенные объекты платформы ЗаписьXML или ЗаписьJSON, которые работают в кодировке UTF-8 по умолчанию.
← На главную