При переводе серверов приложений и кластера 1С с 32-разрядной архитектуры на 64-разрядную разработчики часто сталкиваются с критической ошибкой при взаимодействии с таблицами DBF. Процедуры обмена данными, годами работавшие через строку подключения к провайдеру VFPOLEDB.1 (Visual FoxPro OLE DB Provider), внезапно перестают функционировать при выполнении серверного кода.
Проанализируем техническую причину сбоя, выясним, почему привычный драйвер не удается запустить на сервере 1С x64, и подробно разберем все доступные варианты решения проблемы.
Драйвер VFPOLEDB был разработан корпорацией Microsoft как внутрипроцессный COM-сервер (In-Process COM DLL) исключительно в 32-разрядном варианте. Поскольку активная поддержка и разработка линейки Visual FoxPro давно прекращены, официальный 64-битный релиз этой библиотеки так и не был выпущен.
Архитектура операционных систем семейства Windows не позволяет 64-разрядному процессу (в данном случае рабочему процессу сервера 1С rphost.exe) напрямую загружать 32-разрядные библиотеки DLL в свое адресное пространство памяти. В результате при попытке инициализации объекта ADODB.Connection на стороне сервера 1С x64 возникает ошибка отсутствия зарегистрированного OLE DB провайдера.
Рассмотрим подробнее альтернативные подходы к организации обмена данными в реальном времени с поддержкой разделяемого доступа к файлам.
Одним из проверенных решений, поддерживающих 64-битную архитектуру и сохраняющих возможность работы через интерфейс ADO, является Advantage Database Server (ADS). Данный компонент предоставляет полноценный 64-разрядный провайдер Advantage OLE DB Provider, способный работать с таблицами DBF формата Visual FoxPro.
Разберем по шагам подключение к каталогу с файлами DBF при помощи Advantage OLE DB Provider:
ADS_LOCAL_SERVER и формат таблиц ADS_VFP (или ADS_CDX в зависимости от структуры ваших файлов и индексов).ADODB.Connection и выполним требуемые операции SQL.Посмотрим на пример программного кода инициализации соединения и выполнения запроса:
Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Advantage OLE DB Provider;"
+ "Data Source=C:\Exchange\DBF_Data\;"
+ "ServerType=ADS_LOCAL_SERVER;"
+ "TableType=ADS_VFP;";
Попытка
Соединение.Open(СтрокаПодключения);
Соединение.Execute("CREATE TABLE Table1 (F1 char(20), F2 char(20))");
Исключение
ЗаписьЖурналаРегистрации("Обмен DBF", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка подключения к Advantage OLE DB: " + ОписаниеОшибки());
КонецПопытки;
Важная особенность: При использовании данного провайдера обратите внимание на поведение метода Execute. В некоторых сценариях количество затронутых записей (RecordsAffected) может возвращаться равным 0, а выборка записей с учетом удаленных строк регулируется специфическими параметрами провайдера (такими как ShowDeleted). Проверяйте логику обработки результирующих наборов записей при переходе с FoxPro на ADS.
Если требуется сохранить выполнение стандартных SQL-запросов без внедрения сторонних СУБД-драйверов от сторонних разработчиков, рассмотрим применение компонента Microsoft Access Database Engine (ACE). Пакет выпускается в 64-битной версии и содержит провайдер Microsoft.ACE.OLEDB.12.0 (или более поздние версии).
Провайдер ACE поддерживает подключение к таблицам DBF через спецификацию расширенных свойств dBASE. Разберем пример формирования строки подключения:
Соединение = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;"
+ "Data Source=C:\Exchange\DBF_Data\;"
+ "Extended Properties=""dBASE IV;"";";
Попытка
Соединение.Open(СтрокаПодключения);
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = "SELECT * FROM Table1.dbf";
Выборка = Команда.Execute();
Исключение
Сообщить("Ошибка доступа к файлу DBF через ACE OLEDB: " + ОписаниеОшибки());
КонецПопытки;
Ограничение: Драйвер Microsoft ACE ориентирован на форматы dBASE IV и dBASE 5.0. Если база внешнего источника использует специфические расширенные типы полей Visual FoxPro или контейнеры базы данных (.dbc), этот провайдер может завершить обработку с ошибкой.
Проанализируем сценарий, когда в коде не требуется выполнение сложных SQL-конструкций вроде объединений таблиц или вложенных подзапросов. В таком случае наиболее стабильным и платформенно-независимым решением станет отказ от технологии OLE DB в пользу встроенного объекта XBase.
Преимущества встроенного объекта XBase:
.cdx и .ndx.Посмотрим на пример открытия таблицы с совместным доступом и обхода записей:
ФайлDBF = Новый XBase;
ФайлDBF.ТолькоЧтение = Ложь;
Попытка
// Открываем таблицу в режиме совместного доступа
ФайлDBF.ОткрытьФайл("C:\Exchange\DBF_Data\Table1.dbf", , Ложь);
Если ФайлDBF.Открыта() Тогда
ФайлDBF.Первая();
Пока Не ФайлDBF.ВКонце() Цикл
Если Не ФайлDBF.ЗаписьУдалена() Тогда
ЗначениеПоля = ФайлDBF.F1;
// Обработка данных
КонецЕсли;
ФайлDBF.Следующая();
КонецЦикла;
ФайлDBF.ЗакрытьФайл();
КонецЕсли;
Исключение
Если ФайлDBF.Открыта() Тогда
ФайлDBF.ЗакрытьФайл();
КонецЕсли;
ВызватьИсключение "Ошибка обработки XBase: " + ОписаниеОшибки();
КонецПопытки;
Если код обмена строго завязан на диалект Visual FoxPro SQL и переписывать логику невозможно, настроим изоляцию 32-разрядного провайдера средствами операционной системы через службу компонентов Windows (COM+).
Механизм Windows DLL Surrogate позволяет запускать 32-битные библиотеки внутри системного суррогатного процесса dllhost.exe. Взаимодействие между 64-битным процессом rphost.exe и 32-битным компонентом происходит через механизм межпроцессного взаимодействия (RPC/DCOM).
Разберем логику настройки:
VFPOLEDB.1.Новый COMОбъект("ProgID"). Процесс rphost.exe прозрачно взаимодействует с 32-битным окружением без ошибок несовместимости архитектур.Еще один архитектурный способ решения — вынос логики чтения DBF за пределы серверного кластера x64:
VFPOLEDB.1 продолжит работать в штатном режиме.VFPOLEDB.1 и возвращает результат серверу 1С в формате JSON или XML.Таким образом, при невозможности прямой загрузки VFPOLEDB.1 на сервере x64 оптимальным решением является переход на встроенный объект XBase, использование 64-битного провайдера Advantage OLE DB или разделение контуров обработки через вспомогательный процесс.