Почему серверная процедура 1С работает с MySQL, если драйвер установлен только на клиенте?

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

В практике разработчика 1С нередко возникают ситуации, которые на первый взгляд кажутся «магией» или техническим парадоксом. Одна из таких ситуаций — успешное выполнение серверного кода, взаимодействующего с внешней базой данных через ODBC, в то время как нужный драйвер, по заверениям администратора, на сервере не установлен. Разберем подробно, почему это происходит, как работают директивы компиляции и как правильно выстроить архитектуру получения данных из сторонних источников.

Анализ ситуации: иллюзия отсутствия драйвера

Рассмотрим сценарий: база работает в клиент-серверном варианте (например, на PostgreSQL), используется тонкий клиент. Разработчик пишет функцию получения данных из MySQL с директивой &НаСервере. На клиентском компьютере драйвер MySQL точно есть, а на сервере в списке «Администрирование — Источники данных ODBC» он отсутствует. Тем не менее, код успешно отрабатывает.

Первое, что нам необходимо сделать — это развеять миф о том, что серверный код может магическим образом «дотянуться» до библиотек клиента. В клиент-серверной архитектуре код &НаСервере исполняется строго в процессе rphost на стороне сервера приложений. Если соединение с MySQL устанавливается, значит, драйвер на сервере физически присутствует. Основная причина, по которой его не видно в оснастке — различие в разрядности (Bitness).

Проанализируем этот технический нюанс. В ОС Windows существуют две разные оснастки для управления источниками данных ODBC:

  1. 32-битная (находится в C:\Windows\SysWOW64\odbcad32.exe).
  2. 64-битная (находится в C:\Windows\System32\odbcad32.exe).

Если сервер 1С:Предприятие 64-битный, то для работы через COMObject("ADODB.Connection") ему требуется 64-битный драйвер MySQL. Если же драйвер был установлен как 32-битный, 64-битный сервер его не увидит, и наоборот. Зачастую разработчики проверяют только одну оснастку, в то время как драйвер может быть зарегистрирован в системе и доступен для программного вызова по его точному имени (Driver Name) в строке соединения, даже без создания системного DSN (Data Source Name).

Влияние файлового режима и контекста формы

Выясним еще одну возможную причину «чуда». Рассмотрим работу в файловом режиме. В файловой базе данных понятия «сервер» и «клиент» разделены лишь логически. Весь код, даже помеченный директивой &НаСервере, фактически исполняется в рамках одного процесса 1cv8.exe на машине пользователя. Если автор тестировал решение на локальной копии базы, то использование клиентского драйвера в серверной процедуре — это нормальное поведение платформы.

Однако, если база строго клиент-серверная, важно обратить внимание на контекст формы. При вызове серверной процедуры из модуля формы 1С передает все данные формы на сервер. Но это не передает клиентские библиотеки. Если данные из MySQL получаются внутри процедуры &НаСервере, они проходят через сетевой стек серверной машины. Если бы библиотеки libmysql.dll или соответствующего ODBC-коннектора не было в системных путях сервера, система выдала бы ошибку «Class not registered» или «Драйвер не найден».

Правильная архитектура получения данных

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

Рекомендуется разделять получение данных и формирование печатных форм. Рассмотрим шаги реализации:

  1. Получаем сырые данные из внешней базы на стороне, где это гарантированно доступно (например, &НаКлиенте, если драйвер есть только там).
  2. Передаем полученную структуру или таблицу значений на сервер.
  3. На сервере производим трансформацию объекта формы в объект метаданных (обработку) для использования всех возможностей макетов.

Посмотрим на пример кода, реализующий передачу управления в модуль объекта для формирования отчета:


&НаСервере
Процедура СформироватьОтчетНаСервере(ДанныеИзMySQL)
    // Преобразуем данные формы в объект обработки
    ЭтаОбработка = РеквизитФормыВЗначение("Объект");
    
    // Вызываем экспортную процедуру из модуля объекта
    ТабДок = ЭтаОбработка.СформироватьОтчет(ДанныеИзMySQL);
    
    // Возвращаем результат в реквизит формы
    ЗначениеВРеквизитФормы(ЭтаОбработка, "Объект");
КонецПроцедуры

В модуле объекта обработки при этом должна располагаться функция, принимающая данные и работающая с макетом:


Функция СформироватьОтчет(ДанныеДляОтчета) Экспорт
    ТабДок = Новый ТабличныйДокумент;
    Макет = ПолучитьМакет("МакетПечатнойФормы");
    
    // Логика заполнения макета данными из параметра ДанныеДляОтчета
    // ...
    
    Возврат ТабДок;
КонецФункции

Использование внешних источников данных

Современная платформа 1С (начиная с версии 8.3) предлагает более элегантный способ интеграции с MySQL — объект метаданных «Внешние источники данных». Рассмотрим подробнее преимущества этого метода:

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

Выводы и рекомендации

Проанализировав ситуацию, можно сделать следующие выводы:

  1. Чудес не бывает: если &НаСервере работает с ODBC, значит драйвер на сервере есть. Проверьте обе версии odbcad32.exe (32 и 64 бита).
  2. Проверьте права доступа: служба, от имени которой запущен сервер 1С (обычно usr1cv8), должна иметь права на чтение соответствующих веток реестра и доступ к библиотекам драйвера.
  3. Старайтесь уходить от использования COMObject в пользу Внешних источников данных. Это делает код чище, а систему — производительнее.
  4. Если архитектура требует получения данных именно на клиенте, всегда используйте передачу этих данных на сервер через параметры процедур, не пытаясь совместить несовместимые контексты в одной функции.

Таким образом, понимание того, где физически исполняется ваш код и как система видит установленные драйверы, позволяет избежать долгих «танцев с бубном» и создавать надежные интеграционные решения.

← На главную