В процессе интеграции Delphi-приложений с экосистемой 1С часто возникает необходимость прямого доступа к метаданным или структуре таблиц СУБД. Одной из специфических задач является вызов метода ПолучитьСтруктуруХраненияБазыДанных(), который позволяет сопоставить объекты метаданных 1С (справочники, документы) с реальными именами таблиц в SQL Server или PostgreSQL. Разберем подробно, как реализовать этот "квест" с использованием Delphi 11 и 1С 8.3.
Для взаимодействия с 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-соединение накладывает определенные ограничения и требует внимательности к ресурсам. Рассмотрим основные правила хорошего тона при разработке таких интеграций:
V83.ComConnector занимает одну клиентскую лицензию 1С. Если вы просто закроете приложение Delphi, сессия в 1С может "подвиснуть". Чтобы этого избежать, всегда принудительно обнуляйте переменные: Connect := Unassigned; Connection := Unassigned;.ПолучитьСтруктуруХраненияБазыДанных() может принимать массив имен метаданных в качестве параметра. Это позволит получить структуру только для нужных вам объектов.comcntr.dll. Проверить это можно командой regsvr32 от имени администратора.Несмотря на то, что использование COM кажется наиболее простым путем для Delphi-программиста, современным стандартом считается использование HTTP-сервисов. Если у вас есть возможность попросить 1С-программиста создать простой сервис, вы сможете получать те же данные в формате JSON.
Проанализируем преимущества: вам не нужно заботиться о разрядности (32/64 бит), не нужно регистрировать DLL и не нужно настраивать права DCOM. В Delphi 11 для этого удобно использовать компоненты TNetHTTPClient и стандартную библиотеку System.JSON. Это сделает ваше приложение более стабильным и независимым от версии платформы 1С на клиентской машине.
Подводя итог, можно сказать, что связка Delphi и 1С через COM остается рабочим инструментом. Используя приведенные выше примеры кода, вы сможете успешно получить структуру хранения и продолжить обработку данных в удобном для вас интерфейсе.