Почему искажается кодировка DBF при загрузке на SQL-сервере 1С и как это исправить?

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

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

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

Архитектура процессов: почему в файловой базе всё работает, а на сервере SQL — нет?

Для того чтобы понять корень проблемы, проанализируем разницу в архитектуре выполнения кода между файловым и клиент-серверным вариантами работы 1С:

  1. Файловый режим (или запуск на клиенте): Вся логика чтения файла выполняется непосредственно в контексте сессии текущего пользователя Windows. Если у вас на компьютере установлена русская локаль и операционная система настроена корректно, то системные функции Windows без труда декодируют DOS-символы (CP866) или ANSI-символы (CP1251) в Юникод.
  2. Клиент-серверный режим (SQL): В этом режиме код чтения DBF (особенно если он выполняется в фоновом задании, в серверном модуле или в регламентной процедуре) выполняется внутри процесса rphost на стороне сервера приложений 1С. Этот процесс запускается от имени специальной системной учетной записи (например, USR1CV8 или NetworkService).

По умолчанию у служебных учетных записей Windows нет полноценного интерактивного профиля пользователя. Они используют региональные настройки «по умолчанию» (System Locale). Если операционная система сервера изначально была англоязычной (что крайне распространено для дистрибутивов Windows Server), или если при первоначальной настройке системы параметры русской локализации не были скопированы для системных профилей, служба 1С будет использовать американскую кодовую страницу (CP1252 для ANSI и CP437/CP850 для OEM/DOS). Как результат — русские буквы при чтении превращаются в хаотичный набор символов.

Почему явное указание кодировки OEM в коде 1С не решает проблему?

Часто разработчики пытаются решить проблему «в лоб», прописывая кодировку в коде 1С до или после открытия файла:


ФайлDBF = Новый XBase;
ФайлDBF.Кодировка = КодировкаXBase.OEM;
ФайлDBF.ОткрытьФайл(ПутьКФайлу);

Однако на сервере SQL это действие не приносит результата. Дело в том, что встроенный объект 1С XBase не содержит в себе собственных жестко зашитых таблиц перекодирования для всех устаревших страниц. Для конвертации символов DOS (CP866) в Юникод он обращается к стандартным функциям Windows API.

Если в окружении процесса rphost системной OEM-кодировкой по умолчанию назначена латиница (например, CP850), то операционная система выполняет трансляцию байтов именно по латинской таблице. Платформа 1С получает от ОС уже искаженные данные, и никакие дальнейшие манипуляции со свойством Кодировка исправить этот результат уже не могут.

Решение 1. Копирование региональных настроек во все системные профили (Основной метод)

Самый простой и правильный путь решения проблемы на уровне операционной системы — это корректная настройка локали для всех пользователей, включая системные службы Windows Server. Разберем этот процесс по шагам:

  1. Зайдем на сервер под учетной записью Администратора.
  2. Откроем Панель управления (Control Panel) и перейдем в раздел Региональные стандарты (Region).
  3. Перейдем на вкладку Дополнительно (Administrative).
  4. В разделе "Язык программ, не поддерживающих Юникод" (Language for non-Unicode programs) нажмем кнопку Изменить локаль системы (Change system locale) и убедимся, что там выбран Русский (Россия). Если нет — установим его.
  5. В верхней части этой же вкладки "Дополнительно" найдем раздел "Экран приветствия и учетные записи новых пользователей" (Welcome screen and new user accounts) и нажмем кнопку Копировать параметры (Copy settings).
  6. В открывшемся окне в самом низу установим две важнейшие галочки:
    • Экран приветствия и системные учетные записи (Welcome screen and system accounts) — это применит настройки русской локали для службы 1С;
    • Новые учетные записи пользователей (New user accounts).
  7. Нажмем ОК, применим изменения и выполним обязательную перезагрузку сервера.

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

Решение 2. Точечное перенаправление кодовых страниц через реестр Windows

Если по соображениям безопасности или корпоративным стандартам вам запрещено глобально менять локаль сервера или копировать параметры на экран приветствия, можно прибегнуть к «точечной» настройке через системный реестр. Мы можем заставить Windows принудительно сопоставлять запросы к латинским таблицам с кириллическими файлами перекодировки.

Для реализации этого метода выполним следующие шаги:

  1. Откроем редактор реестра (выполним команду regedit).
  2. Перейдем к ветке реестра:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
  3. Найдем и отредактируем следующие строковые параметры, указав для них новые значения:
    • Параметр 1250 — установим значение c_1251.nls
    • Параметр 1252 (дефолтная латиница Windows) — установим значение c_1251.nls
    • Параметр 850 (дефолтная OEM-кодировка DOS) — установим значение c_866.nls
    • Параметр 437 — установим значение c_866.nls
  4. Перезагрузим сервер для вступления изменений в силу.

После этого любые системные запросы на декодирование латинских страниц будут автоматически перенаправляться на кириллические таблицы ANSI (CP1251) и DOS (CP866).

Решение 3. Проверка и исправление заголовка DBF-файла (Байт LDID)

Иногда кодировка отображается неверно из-за структуры самого загружаемого DBF-файла. В заголовке любого DBF-файла, в его 29-м байте, хранится специальный маркер — Language Driver ID (LDID), который указывает программам, какую кодировку использовать при чтении.

Проанализируем возможные значения этого байта:

Если внешняя программа выгружает файлы с нулевым 29-м байтом, рекомендуется либо настроить эту программу на корректную запись LDID, либо воспользоваться специализированными утилитами (например, DBF Commander) для автоматического прописывания корректного языкового драйвера в заголовок файла перед его отправкой в 1С.

Решение 4. Настройка драйверов ADODB / OLE DB для работы с DBF

Если в вашем решении загрузка DBF-файлов реализована не через встроенный объект XBase, а посредством внешних COM-объектов (Microsoft Jet OLEDB или Access Connectivity Engine), то настройки кодировки регулируются другими ключами реестра.

Параметры работы этих драйверов с DBF-файлами находятся по следующему пути (для 64-битных систем):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Xbase (или в аналогичной ветке Wow6432Node для 32-битных процессов).

В этой ветке найдем строковый параметр DataCodePage. По умолчанию он может иметь значение OEM. Чтобы избежать проблем с системной кодировкой, мы можем принудительно установить его в значение ANSI или явно определить используемую кодовую страницу прямо в строке подключения ADO, добавив параметры:

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Folder;Extended Properties=""DBASE IV;CharacterSet=CP866;"""

Решение 5. Кроссплатформенный подход: побайтовое чтение DBF (Рекомендуемый метод)

В современных реалиях сервер 1С часто работает под управлением операционных систем семейства Linux, где манипуляции с реестром Windows неприменимы. Чтобы сделать ваш код загрузки DBF абсолютно стабильным, независимым от настроек операционной системы, прав пользователей и используемой СУБД, настоятельно рекомендуется отказаться от использования стандартного объекта XBase и COM-объектов на сервере.

Вместо этого мы можем читать DBF-файл как двоичные данные и самостоятельно парсить его структуру. Так как формат DBF строго документирован, это не представляет большой сложности. При конвертации считанных байтовых массивов в строки 1С мы можем жестко задать нужную кодировку без оглядки на операционную систему.

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


// Открываем DBF-файл как поток двоичных данных
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
ПотокЧтения = ДвоичныеДанныеФайла.ОткрытьПотокДляЧтения();

// Пример чтения заголовка и побайтового разбора данных:
// Мы можем читать блоки байт и конвертировать их в строки с жестким указанием кодировки
ИмяКодировки = "cp866"; // Гарантирует корректное чтение DOS-кодировки даже на Linux

// Для конвертации буфера байт в строку используем метод ПолучитьСтрокуИзБуфераОбмена
// ТекстСтроки = ПолучитьСтрокуИзБуфера(БуферБайт, ИмяКодировки);

ПотокЧтения.Закрыть();

Этот метод работает полностью в оперативной памяти сервера 1С, гарантирует 100% предсказуемый результат и избавляет системных администраторов от необходимости тонкой настройки локали и реестра операционной системы сервера.

← На главную