Как решить проблемы при подключении к СУБД Access из 1С: устраняем ошибки поиска источника данных и незарегистрированного класса ADODB.Command

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

При переносе обработок 1С, взаимодействующих с файловыми базами данных Microsoft Access (форматы .mdb и .accdb), с локального компьютера разработчика на промышленный сервер под управлением 64-разрядных операционных систем (таких как Windows Server 2008 R2 или Windows Server 2012/2016), специалисты часто сталкиваются со специфическими ошибками. Две самые распространенные из них: отсутствие или несовместимость OLE DB / ODBC драйверов (сообщение «Источник данных не найден и не указан драйвер, используемый по умолчанию») и сбой активации COM-объектов (сообщение «Класс не зарегистрирован» при создании ADODB.Command).

В этой статье мы подробно разберем природу возникновения этих ошибок, проанализируем влияние разрядности процессов на работу драйверов баз данных и пошагово настроим стабильное подключение к файлам СУБД Access из среды 1С.

Анализ исходной ситуации: почему возникают сбои при работе с Access в 1С

Рассмотрим типичный сценарий. На локальном компьютере программиста (например, под управлением Windows 7) обработка 1С успешно подключается к файлу базы данных СУБД Access и выбирает из нее данные. Однако при запуске этой же обработки на сервере под управлением Windows Server 2008 R2 выполнение кода прерывается на строке открытия соединения:

Connection.Open(СтрокаПодключения);

Система возвращает исключение: «Произошла исключительная ситуация (Microsoft OLE DB Provider for ODBC Drivers): [Microsoft][Диспетчер драйверов ODBC] Источник данных не найден и не указан драйвер, используемый по умолчанию».

Выясним главную причину этого сбоя. Она кроется в конфликте разрядности (битности) операционной системы, платформы 1С и установленных в системе драйверов баз данных. На 64-битных операционных системах сосуществуют две изолированные среды исполнения программ:

  1. 64-битная среда (x64) — исполняемые файлы хранятся в C:\Program Files, системные библиотеки в C:\Windows\System32.
  2. 32-битная среда (x86) — исполняемые файлы находятся в C:\Program Files (x86), а системные библиотеки — в папке C:\Windows\SysWOW64.

Если код 1С выполняется в 32-битном процессе (например, запущен 32-битный тонкий клиент или база работает в файловом режиме под управлением 32-битной платформы), то операционная система разрешает загружать только 32-битные COM-объекты и драйверы. Если же код выполняется на стороне 64-битного сервера приложений 1С (например, в фоновом задании или при вызове серверного метода &НаСервере), то операционная система потребует исключительно 64-битные версии драйверов.

Шаг 1: Правильная настройка строки подключения без использования ODBC

Очень часто разработчики используют устаревший способ подключения через драйверы ODBC. Строка подключения при этом выглядит следующим образом:


СтрокаПодключения = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + ФайлБазы;

Использование диспетчера драйверов ODBC на серверах крайне не рекомендуется, так как оно требует ручной настройки источников данных (DSN) внутри операционной системы и часто приводит к путанице из-за существования двух разных утилит конфигурирования: 64-битной (odbcad32.exe в папке System32) и 32-битной (в папке SysWOW64).

Для стабильной работы с файлами СУБД Access мы перейдем на использование технологии OLE DB. Вместо драйверов ODBC мы применим специализированные провайдеры (поставщики данных). Проанализируем два основных варианта:

  1. Microsoft.Jet.OLEDB.4.0 — классический движок баз данных Jet. Он предназначен для работы исключительно со старым форматом файлов .mdb (Access 97-2003). Важно помнить: этот провайдер является строго 32-битным. В 64-битных процессах он физически отсутствует и работать не будет.
  2. Microsoft.ACE.OLEDB.12.0 (или более новые версии — 15.0, 16.0) — современный движок Access Database Engine (ACE). Он поддерживает как старый формат файлов .mdb, так и новый .accdb. Провайдер ACE поставляется как в 32-битной, так и в 64-битной редакциях, что делает его универсальным решением для серверов.

Сформируем корректную строку подключения с использованием провайдера ACE:


СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ФайлБазы + ";Persist Security Info=False;";

Шаг 2: Диагностика провайдеров OLE DB с помощью файлов данных связи (UDL)

Чтобы понять, какие именно OLE DB провайдеры установлены в вашей операционной системе и доступны для платформы 1С, проведем простой и надежный эксперимент с помощью технологических файлов связи данных (файлов с расширением .udl).

Разберем этот процесс по шагам:

  1. Создайте на сервере пустой текстовый файл и назовите его, например, test_connection.udl.
  2. Запустите платформу 1С:Предприятие в режиме «Конфигуратор» или «Предприятие».
  3. В главном меню 1С выберите пункт Файл -> Открыть.
  4. В открывшемся диалоговом окне выбора файла установите тип файлов «Все файлы (*.*)», найдите ваш файл test_connection.udl, нажмите на него правой кнопкой мыши и выберите пункт Свойства.
  5. Перед вами откроется системное окно настройки свойств связи данных Windows. Перейдите на вкладку «Поставщик данных» (Providers).

Поскольку вы открыли этот диалог из-под запущенного процесса 1С, вы увидите ровно тот набор OLE DB провайдеров, который доступен платформе вашей разрядности в данный момент.

Попробуйте выбрать поочередно поставщиков Microsoft Jet 4.0 OLE DB Provider или Microsoft Office 12.0 Access Database Engine OLE DB Provider, перейдите на вкладку «Соединение» (Connection), укажите путь к вашему файлу базы данных Access и нажмите кнопку «Проверить соединение».

После успешной проверки закройте окно, сохранив изменения. Откройте файл test_connection.udl обычным текстовым редактором (например, Блокнотом). Внутри файла вы увидите готовую, протестированную и гарантированно рабочую строку подключения, которую можно скопировать прямо в модуль 1С.

Шаг 3: Сосуществование 32-битных и 64-битных драйверов на одном сервере

Если при тестировании связи выяснилось, что в 32-битной 1С провайдер работает успешно, а при выполнении регламентного задания на сервере 1С x64 возникает ошибка инициализации поставщика данных, вам необходимо установить 64-битную версию компонента Microsoft Access Database Engine.

Однако здесь системные администраторы часто сталкиваются с защитным поведением инсталляторов Microsoft: если на сервере уже установлен 32-битный пакет Microsoft Office, то установщик 64-битного ACE OLE DB заблокирует инсталляцию, выдав ошибку несовместимости.

Чтобы обойти это искусственное ограничение и установить драйверы обеих разрядностей на один сервер, выполните установку через командную строку с ключом пассивного режима:

  1. Скачайте необходимый дистрибутив (например, AccessDatabaseEngine_X64.exe).
  2. Откройте командную строку Windows от имени Администратора.
  3. Запустите установку программы со специальным ключом: C:\PathToFolder\AccessDatabaseEngine_X64.exe /passive

Ключ /passive заставляет программу установки пропустить проверку конфликтующих версий MS Office и корректно развернуть 64-битные библиотеки OLE DB в операционной системе.

Шаг 4: Устранение ошибки «Класс не зарегистрирован» для ADODB.Command

Когда вы успешно подключились к базе данных, вы можете столкнуться со следующей проблемой при попытке создать объект для выполнения параметризованных запросов:

Command = Новый COMОбъект("ADODB.Command");

Платформа возвращает ошибку: «Произошла исключительная ситуация (0x80040154): Класс не зарегистрирован».

Проанализируем причину. В операционных системах Windows Server 2008 R2 и Windows 7 после установки некоторых обновлений (в частности, связанных с пакетами обновления SP1) ломается совместимость интерфейсов ADO (ActiveX Data Objects). Microsoft изменила уникальные GUID идентификаторы классов ADO в системном реестре (подробнее проблема описана в статье базы знаний Microsoft KB2517589).

Для исправления этой проблемы необходимо вручную перерегистрировать ключевую библиотеку ADO (msado15.dll) в реестре операционной системы. Крайне важно сделать это с учетом разрядности вашего приложения 1С.

Если ваш код 1С выполняется в 32-битном процессе (файловая база, 32-битный клиент):

  1. Откройте командную строку от имени Администратора.
  2. Выполните команду регистрации библиотеки из каталога поддержки 32-битных приложений SysWOW64:
    
    C:\Windows\SysWOW64\regsvr32.exe "C:\Program Files (x86)\Common Files\System\ado\msado15.dll"
    

Если ваш код выполняется в 64-битном процессе (на стороне 64-битного сервера приложений 1С):

  1. Откройте командную строку от имени Администратора.
  2. Выполните команду регистрации библиотеки из каталога System32:
    
    C:\Windows\System32\regsvr32.exe "C:\Program Files\Common Files\System\ado\msado15.dll"
    

После успешной регистрации библиотеки в системном реестре вы увидите подтверждающее окно утилиты regsvr32, и создание COM-объекта ADODB.Command в коде 1С заработает в штатном режиме.

Шаг 5: Альтернативные методы выполнения запросов без ADODB.Command

Рассмотрим более изящное и стабильное программистское решение. В среде 1С для извлечения данных из СУБД Access вовсе не обязательно создавать объект ADODB.Command. От этого класса можно полностью отказаться, что сделает ваш код более отказоустойчивым и независимым от тонкостей обновления операционных систем.

Разберем два эффективных альтернативных метода получения данных.

Метод 1: Прямое выполнение запроса через объект ADODB.Connection

Сам объект открытого соединения умеет выполнять SQL-запросы напрямую через свой метод Execute(). Данный метод сразу возвращает готовый объект набора записей (Recordset).

Посмотрим на практический пример реализации этого метода:


ФайлБазы = "C:\Database\sprut.mdb";
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ФайлБазы + ";Persist Security Info=False;";

Connection = Новый COMОбъект("ADODB.Connection");

Попытка
    Connection.Open(СтрокаПодключения);
Исключение
    ВызватьИсключение "Не удалось установить связь с СУБД Access. Описание ошибки: " + ОписаниеОшибки();
КонецПопытки;

// Текст запроса к таблице Access
ТекстЗапроса = "SELECT Kod, Name, Quantity FROM Goods WHERE Quantity > 0";

Попытка
    // Выполняем запрос напрямую через объект соединения
    RecordSet = Connection.Execute(ТекстЗапроса);
Исключение
    Connection.Close();
    ВызватьИсключение "Ошибка выполнения SQL-запроса: " + ОписаниеОшибки();
КонецПопытки;

// Обрабатываем полученные записи в цикле
Пока НЕ RecordSet.EOF Цикл
    
    ТоварКод = RecordSet.Fields("Kod").Value;
    ТоварИмя = RecordSet.Fields("Name").Value;
    ТоварКол = RecordSet.Fields("Quantity").Value;
    
    Сообщить(Шаблон("Код: %1, Название: %2, Остаток: %3", ТоварКод, ТоварИмя, ТоварКол));
    
    // Переходим к следующей строке выборки
    RecordSet.MoveNext();
    
    // Предотвращаем зависание интерфейса при больших объемах данных
    ОбработкаПрерыванияПользователя();
    
КонецЦикла;

// Закрываем ресурсы
RecordSet.Close();
Connection.Close();

Метод 2: Использование объекта Recordset с передачей активного соединения

Второй способ заключается в явном создании объекта ADODB.Recordset. Мы можем открыть его, передав SQL-запрос и уже открытый объект соединения Connection в качестве параметров метода Open().

Проанализируем этот программный код:


ФайлБазы = "C:\Database\sprut.mdb";
СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ФайлБазы + ";";

Connection = Новый COMОбъект("ADODB.Connection");

Попытка
    Connection.Open(СтрокаПодключения);
Исключение
    ВызватьИсключение "Ошибка открытия базы данных Access: " + ОписаниеОшибки();
КонецПопытки;

// Создаем объект набора записей
RecordSet = Новый COMОбъект("ADODB.Recordset");
ТекстЗапроса = "SELECT * FROM Users";

Попытка
    // Параметры метода Open:
    // 1. Текст SQL-запроса или имя таблицы
    // 2. Объект активного соединения Connection
    // 3. CursorType (1 - adOpenKeyset, позволяет перемещаться по записям вперед и назад)
    // 4. LockType (3 - adLockOptimistic, оптимистичная блокировка данных)
    RecordSet.Open(ТекстЗапроса, Connection, 1, 3);
Исключение
    Connection.Close();
    ВызватьИсключение "Не удалось открыть таблицу: " + ОписаниеОшибки();
КонецПопытки;

Пока НЕ RecordSet.EOF Цикл
    
    ИмяПользователя = RecordSet.Fields("UserName").Value;
    Сообщить("Пользователь из базы Access: " + ИмяПользователя);
    
    RecordSet.MoveNext();
    ОбработкаПрерыванияПользователя();
    
КонецЦикла;

RecordSet.Close();
Connection.Close();

Оба представленных программных решения полностью исключают использование нестабильного класса ADODB.Command. Они работают напрямую с провайдерами OLE DB, обеспечивая высокую скорость чтения данных и обратную совместимость с любыми версиями операционных систем Windows.

← На главную