Как из Delphi подключиться к 1С 8.3 и получить структуру хранения базы данных?

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

В процессе интеграции Delphi-приложений с экосистемой 1С часто возникает необходимость прямого доступа к метаданным или структуре таблиц СУБД. Одной из специфических задач является вызов метода ПолучитьСтруктуруХраненияБазыДанных(), который позволяет сопоставить объекты метаданных 1С (справочники, документы) с реальными именами таблиц в SQL Server или PostgreSQL. Разберем подробно, как реализовать этот "квест" с использованием Delphi 11 и 1С 8.3.

Основы подключения через COM-интерфейс

Для взаимодействия с 1С из внешней среды чаще всего используется механизм COM-соединения. Проанализируем ситуацию: нам необходимо создать объект V83.ComConnector, установить связь с базой и вызвать требуемый метод. Рассмотрим базовый алгоритм инициализации соединения.

Прежде всего, в Delphi необходимо объявить переменные типа OleVariant для работы с COM-объектами. Пример инициализации выглядит следующим образом:


var
  Connection, Connect: OleVariant;
begin
  Connection := CreateOleObject('V83.ComConnector');
  // Строка соединения для клиент-серверного варианта
  Connect := Connection.Connect('Srvr="MyServer"; Ref="MyBase"; Usr="Admin"; pwd="123";');
  
  if VarIsEmpty(Connect) then
    raise Exception.Create('Не удалось установить соединение с 1С');
end;

Важный нюанс: Если вы используете Delphi 11 и компилируете проект под 64-битную платформу (Win64), а на компьютере установлена 32-битная версия клиента 1С, вы получите ошибку "Класс не зарегистрирован". Выясним причину: COM-объекты разных разрядностей не могут напрямую взаимодействовать. Решением будет либо переключение проекта в Delphi на Target Platform Win32, либо регистрация библиотеки comcntr.dll в службе компонентов Windows (COM+).

Вызов метода ПолучитьСтруктуруХраненияБазыДанных

После успешного подключения мы получаем доступ к глобальному контексту 1С. Метод ПолучитьСтруктуруХраненияБазыДанных() возвращает объект типа ТаблицаЗначений. Рассмотрим подробнее, как обработать этот объект в Delphi.

Каждая строка этой таблицы содержит информацию о конкретной таблице базы данных. Нам интересны такие поля, как ИмяТаблицыХранения, ИмяТаблицы, Метаданные и Назначение. Проанализируем полный пример кода для извлечения этих данных:


procedure TForm1.Get1SStructure;
var
  Connect, Connection: OleVariant;
  DBStructure: OleVariant;
  RowCount: Integer;
  i: Integer;
  CurrentRow: OleVariant;
  TableName, StorageName, MetadataPath: String;
begin
  Connection := CreateOleObject('V83.ComConnector');
  Connect := Connection.Connect('Srvr="localhost"; Ref="TradeDB"; Usr="Admin"; pwd="";');

  // Вызываем метод 1С
  DBStructure := Connect.ПолучитьСтруктуруХраненияБазыДанных();
  
  // Получаем количество строк в ТаблицеЗначений
  RowCount := DBStructure.Количество();
  
  for i := 0 to RowCount - 1 do
  begin
    // Получаем строку по индексу
    CurrentRow := DBStructure.Получить(i);
    
    // Читаем свойства строки
    StorageName := CurrentRow.ИмяТаблицыХранения; // Имя в SQL (например, _Reference25)
    TableName := CurrentRow.ИмяТаблицы;         // Имя в 1С
    MetadataPath := CurrentRow.Метаданные;       // Путь (например, Справочник.Номенклатура)
    
    // Здесь можно добавить данные в StringGrid или VirtualTree
    AddToMyGrid(StorageName, TableName, MetadataPath);
  end;
end;

Обработка вложенных данных: Поля и Индексы

Метод ПолучитьСтруктуруХраненияБазыДанных() возвращает не просто плоскую таблицу. В каждой строке колонки Поля и Индексы сами являются коллекциями (вложенными таблицами значений). Выясним, как "дотянуться" до них.

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


var
  TableFields, FieldRow: OleVariant;
  f: Integer;
begin
  TableFields := CurrentRow.Поля; // Это тоже ТаблицаЗначений
  for f := 0 to TableFields.Количество() - 1 do
  begin
    FieldRow := TableFields.Получить(f);
    // Доступ к свойствам поля
    // FieldRow.ИмяПоля, FieldRow.ИмяПоляХранения, FieldRow.ТипДанных
  end;
end;

Такой подход позволяет сформировать полную карту базы данных прямо внутри вашего Delphi-приложения.

Оптимизация и управление ресурсами

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

  1. Освобождение лицензий: Каждое созданное соединение через V83.ComConnector занимает одну клиентскую лицензию 1С. Если вы просто закроете приложение Delphi, сессия в 1С может "подвиснуть". Чтобы этого избежать, всегда принудительно обнуляйте переменные: Connect := Unassigned; Connection := Unassigned;.
  2. Скорость работы: Получение структуры всей базы данных — операция тяжелая. Если база большая (например, 1С:ERP), метод может выполняться долго. Посмотрим на возможность оптимизации: метод ПолучитьСтруктуруХраненияБазыДанных() может принимать массив имен метаданных в качестве параметра. Это позволит получить структуру только для нужных вам объектов.
  3. Регистрация библиотеки: Если вы планируете развертывать приложение на других компьютерах, убедитесь, что там зарегистрирована библиотека comcntr.dll. Проверить это можно командой regsvr32 от имени администратора.

Альтернативные пути (HTTP и JSON)

Несмотря на то, что использование COM кажется наиболее простым путем для Delphi-программиста, современным стандартом считается использование HTTP-сервисов. Если у вас есть возможность попросить 1С-программиста создать простой сервис, вы сможете получать те же данные в формате JSON.

Проанализируем преимущества: вам не нужно заботиться о разрядности (32/64 бит), не нужно регистрировать DLL и не нужно настраивать права DCOM. В Delphi 11 для этого удобно использовать компоненты TNetHTTPClient и стандартную библиотеку System.JSON. Это сделает ваше приложение более стабильным и независимым от версии платформы 1С на клиентской машине.

Подводя итог, можно сказать, что связка Delphi и 1С через COM остается рабочим инструментом. Используя приведенные выше примеры кода, вы сможете успешно получить структуру хранения и продолжить обработку данных в удобном для вас интерфейсе.

← На главную