При обмене данными между различными системами (например, выгрузка из сторонней программы Юнико в 1С:Бухгалтерия 3.0) через формат DBF, разработчики часто сталкиваются с проблемой некорректного отображения кириллицы. Символы превращаются в нечитаемый набор знаков («кракозябры»). Ситуация осложняется, когда на локальном компьютере программиста загрузка проходит успешно, а на рабочем сервере те же самые файлы считываются некорректно. Разберем детально причины этого поведения и способы решения проблемы.
Проанализируем ситуацию: почему один и тот же файл и одна и та же обработка дают разный результат? Основная причина кроется в том, как операционная система интерпретирует кодировку файлов, не содержащих явного указания на используемую таблицу символов. В формате DBF традиционно используются две кодировки: OEM (CP866) — стандарт DOS, и ANSI (Windows-1251) — стандарт Windows.
Рассмотрим ключевые факторы, влияющие на процесс чтения:
1С:Предприятие.ADO или ODBC, настройки драйвера в реестре сервера могут принудительно переопределять кодировку.USR1CV8, настройки профиля которой могут быть не инициализированы или установлены в English по умолчанию.Первым делом проверим настройки операционной системы на сервере, где запущена служба 1С. Даже если визуально в Windows выбран русский интерфейс, параметры для работы с ANSI/OEM могут быть настроены неверно. Пройдем по шагам:
XBase и DBF.Если настройки были изменены, обязательно перезагрузим сервер, чтобы изменения вступили в силу для всех системных служб.
Если системные настройки в порядке, а проблема сохраняется, проанализируем код обработки загрузки. В 1С для работы с DBF используется объект XBase. У этого объекта есть свойство Кодировка, которое может принимать значения КодировкаXBase.OEM или КодировкаXBase.ANSI. Выясним, какая кодировка используется в исходных файлах, открыв их через текстовый редактор, умеющий определять кодовые страницы (например, Notepad++), и установим ее явно.
Рассмотрим пример кода для загрузки с явным указанием кодировки:
// Инициализируем объект для работы с DBF
ФайлDBF = Новый XBase;
// Важно: пробуем переключить кодировку, если получаем кракозябры
// Если файл из DOS-системы (Юнико часто выгружает в ней), используем OEM
ФайлDBF.Кодировка = КодировкаXBase.OEM;
// Если файл создан в Windows-приложении, используем ANSI
// ФайлDBF.Кодировка = КодировкаXBase.ANSI;
ФайлDBF.ОткрытьФайл(ПутьКФайлу);
Если ФайлDBF.Открыта() Тогда
Пока ФайлDBF.Следующая() Цикл
Наименование = ФайлDBF.NAME; // Здесь получаем строку
// Дополнительная проверка на пустые значения
Если ПустаяСтрока(Наименование) Тогда
Продолжить;
КонецЕсли;
// Логика создания номенклатуры...
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
КонецЕсли;
Часто сторонние программы формируют DBF некорректно, не прописывая идентификатор языкового драйвера. В этом случае 1С не может автоматически определить кодировку. Рассмотрим способ программного исправления 29-го байта файла непосредственно перед загрузкой. Для русской кодировки CP866 (OEM) этот байт должен иметь значение 0x26 (в десятичной системе — 38).
Выполним процедуру «лечения» файла:
Процедура ИсправитьЗаголовокDBF(ПутьКФайлу)
// Открываем файл как двоичные данные
Файл = Новый Файл(ПутьКФайлу);
Если Не Файл.Существует() Тогда
Возврат;
КонецЕсли;
ДвоичныеДанные = Новый ЗаписьДанных(ПутьКФайлу, , , Ложь);
// Переходим к 29-му байту (смещение 29)
ДвоичныеДанные.Перейти(29);
// Записываем код 38 (соответствует CP866)
ДвоичныеДанные.ЗаписатьБайт(38);
ДвоичныеДанные.Закрыть();
КонецПроцедуры
Использование этой процедуры перед вызовом ФайлDBF.ОткрытьФайл() гарантирует, что драйвер XBase поймет, в какой кодировке представлены данные.
Иногда стандартный объект XBase не справляется с особенностями формата файла. В таких случаях разберем альтернативный метод загрузки через ADO. Этот способ позволяет более гибко настраивать параметры подключения, включая кодовую страницу.
Проанализируем пример подключения через провайдер Microsoft.Jet.OLEDB:
Connection = Новый COMОбъект("ADODB.Connection");
// Указываем путь к папке с файлом в свойстве Data Source
PathToFolder = "C:\ImportData\";
FileName = "Nomen.dbf";
// В строке соединения указываем Extended Properties с кодировкой
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + PathToFolder + ";Extended Properties=""DBASE IV;CodePage=866;""";
Попытка
Connection.Open(ConnectionString);
Recordset = Connection.Execute("SELECT * FROM " + FileName);
Пока Не Recordset.EOF Цикл
Наименование = Recordset.Fields("NAME").Value;
// Обработка данных...
Recordset.MoveNext();
КонецЦикла;
Connection.Close();
Исключение
Сообщить("Ошибка подключения: " + ОписаниеОшибки());
КонецПопытки;
Если на локальном компьютере все работает корректно, а на сервере — нет, это часто связано с реестром Windows. Драйверы Jet или ACE используют ветку реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Xbase. Параметр DataCodePage там может быть установлен в ANSI на сервере и в OEM на локальном ПК.
Рекомендация: Для стабильной работы на сервере всегда стремитесь использовать универсальные методы чтения (через двоичные данные или явную перекодировку), которые не зависят от системных настроек конкретной машины.
Посмотрим, как можно прочитать файл как текст, если мы точно знаем, что это DBF в формате OEM, но заголовки повреждены:
// Пример использования ЧтениеТекста с явной кодировкой
Чтение = Новый ЧтениеТекста(ПутьКФайлу, "CP866");
// Однако для DBF этот метод сложен, так как файл бинарный.
// Поэтому лучше использовать перекодировку строк вручную через таблицу соответствия
// или вышеописанные методы с исправлением заголовка.
Подводя итог, для устранения «кракозябр» при загрузке номенклатуры на сервере, мы рекомендуем следующий алгоритм действий:
XBase внутри обработки (OEM или ANSI).CodePage в строке подключения.Соблюдение этих шагов позволит добиться идентичного поведения программы как на тестовой базе, так и в серверной среде заказчика.