При переносе баз данных 1С из файлового режима в клиент-серверный вариант (на MS SQL Server или PostgreSQL) разработчики часто сталкиваются с неприятным сюрпризом. Корректно работавший ранее импорт данных из DBF-файлов начинает загружать «кракозябры» или иероглифы вместо понятного русского текста. При этом на файловой базе (даже запущенной локально на том же самом сервере под Windows Server) всё считывается отлично. Сегодня мы детально разберем, почему возникает эта проблема, как она связана с системными процессами операционной системы, и изучим все существующие способы её решения — от системной настройки Windows до программного изменения заголовков файлов «на лету».
Главная причина кроется в архитектуре работы платформы 1С:Предприятие. Когда мы выполняем код чтения DBF на клиенте (в файловом режиме или в интерактивном режиме тонкого клиента), процесс 1cv8.exe запущен под учетной записью текущего активного пользователя Windows. У этого пользователя в операционной системе, как правило, настроена полноценная русская локаль.
Однако, когда аналогичный код выполняется на стороне сервера (например, в регламентном задании, фоновом процессе или при явном вызове серверной процедуры), чтением файла занимается служба сервера 1С:Предприятие (процесс rphost.exe). По умолчанию эта служба часто работает под специальной изолированной системной учетной записью (например, USR1CV8 или LocalSystem). Окружение этой учетной записи не имеет доступа к настройкам вашего текущего пользователя-администратора. Региональные параметры (включая кодировку для программ, не поддерживающих Юникод) для неё часто установлены по умолчанию в западноевропейские стандарты (латиницу). В результате операционная система при чтении OEM-файла подменяет русскую кодировку CP866 на стандартную латинскую, что и приводит к появлению нечитаемых символов.
Рассмотрим самый надежный способ исправления ситуации на уровне операционной системы Windows Server. Нам необходимо принудительно скопировать настройки русской локали для системных учетных записей, под которыми крутится служба сервера 1С.
Разберем этот процесс по шагам:
Важный нюанс: в некоторых версиях Windows Server после первого копирования параметров текущий язык для программ без поддержки Юникода может самопроизвольно сброситься на английский. Если это произошло, зайдите в настройки повторно, верните «Русский», еще раз нажмите кнопку копирования параметров и снова перезагрузите сервер. Этот трюк гарантирует, что служба сервера 1С получит правильные таблицы сопоставления символов.
Если у вас нет прав администратора на сервере или вы не хотите менять глобальные региональные настройки операционной системы (например, если на сервере работают другие критичные англоязычные сервисы), существует элегантное программное решение. Проблема часто возникает из-за того, что в самом DBF-файле не прописан идентификатор кодовой страницы (байт 29 равен 0x00). В этом случае движок XBase пытается определить кодировку самостоятельно на основе локали ОС, что на сервере приводит к сбою.
Мы можем принудительно перезаписать байт кодовой страницы в заголовке файла перед его открытием средствами 1С. Проанализируем пример кода:
Процедура УстановитьКодировкуВЗаголовкеDBF(ПутьКФайлу, ТипКодировки) Экспорт
// ТипКодировки: "ANSI" (запишем 201 / 0xC9) или "OEM" (запишем 101 / 0x65)
БайтКодировки = ?(ВРег(ТипКодировки) = "ANSI", 201, 101);
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если Не ФайлНаДиске.Существует() Тогда
Возврат;
КонецЕсли;
// Открываем файл как двоичные данные для чтения и записи
ФайлДанных = Новый ФайлДанных(ПутьКФайлу, РежимОткрытияФайла.Открыть, ДоступКФайлу.ЧтениеИЗапись);
// Байт кодовой страницы находится на позиции 29 (смещение 29 от начала файла)
// Сдвигаем позицию записи на 29-й байт
ФайлДанных.УстановитьПозицию(29);
// Создаем буфер для одного байта и записываем значение
Буфер = Новый БуферОбмена(1);
Буфер[0] = БайтКодировки;
ФайлДанных.Записать(Буфер, 0, 1);
ФайлДанных.Закрыть();
КонецПроцедуры
После вызова этой процедуры вы можете спокойно открывать DBF-файл стандартным объектом XBase. Платформа гарантированно прочитает данные в нужной кодировке (OEM или ANSI), независимо от региональных настроек сервера!
Если стандартный встроенный объект XBase на стороне сервера продолжает выдавать ошибку, мы можем задействовать внешние драйверы баз данных через COM-соединение. Это позволяет жестко зафиксировать кодировку в самой строке подключения к источнику данных.
Рассмотрим пример чтения файла через провайдер VFPOLEDB (драйвер Visual FoxPro):
ПутьККаталогу = "C:\DBFFiles\";
ИмяФайла = "data.dbf";
Connection = Новый COMОбъект("ADODB.Connection");
Recordset = Новый COMОбъект("ADODB.Recordset");
// Задаем строку подключения с явным указанием кодовой страницы CodePage=1251 (ANSI) или CodePage=866 (OEM)
СтрокаПодключения = "Provider=VFPOLEDB.1;Data Source=" + ПутьККаталогу + ";Collating Sequence=MACHINE;CodePage=1251;";
Попытка
Connection.Open(СтрокаПодключения);
// Выполняем SQL-запрос к файлу как к таблице базы данных
Recordset.Open("SELECT * FROM [" + ИмяФайла + "]", Connection);
Пока Recordset.EOF() = 0 Цикл
// Считываем значения полей
ЗначениеПоля = Recordset.Fields("CLIENTNAME").Value;
// Выполняем дальнейшую обработку данных...
Recordset.MoveNext();
КонецЦикла;
Recordset.Close();
Connection.Close();
Исключение
Сообщить("Ошибка чтения DBF через ADO: " + ОписаниеОшибки());
КонецПопытки;
Если процесс загрузки DBF инициируется пользователем интерактивно в режиме тонкого или толстого клиента, мы можем полностью обойти серверные ограничения, перенеся парсинг файла на клиентскую машину.
Реализуем следующую схему работы:
XBase и считывает данные из файла.Массив структур или ТаблицаЗначений).Этот архитектурный подход полностью устраняет зависимость вашего прикладного решения от настроек реестра и локали операционной системы Windows Server.
Для администраторов крупных серверных систем существует радикальный способ решения проблемы «кракозябр» на англоязычных версиях ОС. Мы можем принудительно заставить операционную систему интерпретировать европейские кодировки через призму кириллицы.
Для этого выполним следующие действия:
regedit в строке «Выполнить»).HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage.1250 (Восточно-европейская) и 1252 (Западно-европейская).c_1252.nls) на кириллический файл c_1251.nls.После этой настройки любые низкоуровневые системные вызовы старых приложений и драйверов к стандартной латинице будут автоматически перенаправляться на кириллическую кодовую страницу.
Если для доступа к файлам DBF ваша система использует классические драйверы Microsoft Jet, может помочь изменение настроек реестра, управляющих поведением xBase-движка по умолчанию.
Перейдите в ветку реестра:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\xBase
Найдите параметр, отвечающий за выбор кодовой страницы по умолчанию, и замените значение OEM на ANSI (или наоборот, в зависимости от реального формата поставляемого вам файла DBF).
Мы подробно разобрали причины сбоя кодировки при переносе кода чтения DBF на сервер 1С и изучили комплекс мер по устранению этой проблемы. Если вы обладаете полным доступом к администрированию Windows Server, оптимальным решением будет Решение 1 (копирование региональных параметров для системных служб). Если сервер находится в облаке или у вас ограничены права доступа, используйте Решение 2 (программное изменение заголовка DBF через двоичные данные) или Решение 4 (чтение данных на клиенте с последующей передачей на сервер). Применение этих методик позволит вам раз и навсегда автоматизировать импорт файлов без риска получить нечитаемые символы в базе данных!