Мельница данных- Руководство разработчика для построителя запросов  (раздел целиком)  (24.07.2021)
Руководство разработчика для построителя запросов

1. Информация о приложении
Приложение QueryBuilder представляет собой документ-ориентированное MDI-проиложение.
Документом является запрос. Запросы сохраняются в файле с расширением .MQR. Файлы запросов представляют собой xml-документы определенной структуры. Для доступа к данным БД приложение использует провайдеры данных - библиотеки объектов, реализующих опубликованные интерфейсы. Идентификатор использованного для построения запроса провайдера сохраняется в файле запроса. Если открыть файл с провайдером, не соответствующим текущему, будет выдано предупреждение.

2. Требования к провайдеру

Интерфейсы провайдера описаны в библиотеке типов файла QueryBuilder.exe и в файле QueryBuilder_TLB.pas. Собственно, объект-провайдер реализует Интерфейс IInfoProvider. Каждый CoClass, реализующий указанный интерфейс, прописывается в ветке реестра HKLM\Software\QueryBuilder\Providers добавлением параметра, имя которого определяет наименование провайдера, а значение - CLSID провайдера.

Метаданные (информация о таблицах, полях и типах данных) предоставляются в виде именованных элементов, то есть каждый из них реализует интерфейс INamedItemInfo


2.1. Интерфейс IInfoProvider
Провайдер реализует интерфейс
  IInfoProvider = interface(IUnknown)
    ['{64F8072B-7250-4C57-BA8E-D018C7B72CC7}']
    function Get_TableCount: Integer; safecall;
    function Get_Table(Index: Integer): ITableInfo; safecall;
    function Perform(const SQL: WideString): IDataSet; safecall;
    procedure Connect(const DataBase: WideString; 
      const UserName: WideString; 
      const Password: WideString); safecall;
    function Get_CLSID: TGUID; safecall;
    function Get_DateLiteral: WideString; safecall;
    function Get_TimeLiteral: WideString; safecall;
    function Get_DateTimeLiteral: WideString; safecall;
  end; 
  • функция Get_CLSID возвращает GUID класса-провайдера.
  • процедура Connect осуществляет соединение с БД.
  • функция Get_TableCount возвращает количество таблиц, доступ к которым предоставляется провайдером.
  • функция Get_Table возвращает ссылку на информацию о таблице с номером Index. Ссылка на интерфейс ITableInfo или интерфейс ITableInfo2
  • функция Perform принимает текст сформированного SQL-запроса и возвращает ссылку на набор данных. Набор данных реализует интерфейс IDataSet.
  • функция Get_DateLiteral возвращает строку, определяющую способ включения в запрос литерала типа "Дата".
  • функция Get_TimeLiteral возвращает строку, определяющую способ включения в запрос литерала типа "Время".
  • функция Get_DateTimeLiteralвозвращает строку, определяющую способ включения в запрос литерала типа "Дата со временем".

2.2. Интерфейс IDataSet
Набор данных реализует интерфейс
   IDataSet = interface(IUnknown)
    ['{3CED7395-8482-4EF6-8A15-7744348063C2}']
    function Get_FieldCount: Integer; safecall;
    function Get_FieldName(Index: Integer): WideString; safecall;
    function Get_Field(FieldIndex: OleVariant): OleVariant; safecall;
    procedure Next; safecall;
    function Eof: WordBool; safecall;
  end;
Набор данных представляет собой однонаправленный курсор, каждая строка которого является набором именованных и нумерованных полей.
  • процедура Next осуществляет переход к следующей записи курсора.
  • функция Eof возвращает True в случае достижения конца курсора.
  • функция Get_FieldCount возвращает количество полей в строке курсора.
  • функция Get_FieldName возвращает имя поля с номером Index.
  • функция Get_Field возвращает значение поля, имя или номер которого задан параметром (если строка, то имя, если число, то номер). Допустимо возвращать значение Null для пустых полей.

2.3. Интерфейс INamedItemInfo
Каждый элемент метаданных (таблица, поле, тип) обязательно реализует интерфейс
  INamedItemInfo = interface(IUnknown)
    ['{14894363-28DA-4E71-B0BC-9C5CE811BC8F}']
    function Get_Name: WideString; safecall;
    function Get_Caption: WideString; safecall;
    function Get_ID: WideString; safecall;
  end;

Именованный элемент имеет имя, наименование и идентификатор. Имя используется для именования сущности в сформированном SQL-запросе, идентификатор необходим для идентификации сущности в рамках провайдера, таблицы и типы данных имеют глобальное пространство идентификаторов, поля имеют уникальные идентификаторы в пределах последовательности наследуемых таблиц. Никаких ограничений на значения идентификаторов, кроме уникальности, не накладывается.

  • функция Get_Name возвращает имя сущности.
  • функция Get_Caption возвращает наименование сущности.
  • функция Get_ID возвращает идентификатор сущности.

2.4. Интерфейс ITableInfo
Информация о таблице представляется объектом через интерфейс (наследник INamedItemInfo )
  ITableInfo = interface(INamedItemInfo)
    ['{3FC1998A-9031-4936-82B5-8CAA2219085E}']
    function Get_FieldCount: Integer; safecall;
    function Get_Field(Index: Integer): IFieldInfo; safecall;
    function Get_PrimaryKey: IFieldInfo; safecall;
    function Get_Uplink: IFieldInfo; safecall;
    function Get_Parent: ITableInfo; safecall;
  end;
  • функция Get_FieldCount возвращает количество полей в таблице.
  • функция Get_Field возвращает ссылку на поле с номером Index. Ссылка на интерфейс IFieldInfo
  • функция Get_PrimaryKey возвращает ссылку на поле, являющееся первичным ключем. Это поле должно быть задано.
  • функция Get_Uplink возвращает ссылку на поле, осуществляющее иерархическую связь между записями таблицы. Если это поле задано, записи отображаются в виде иерархии.
  • функция Get_Parent возвращает ссылку на родительскую таблицу. Дочерняя таблица связана с родительской первичными ключами, т. е. соотношением 1:1. Если таблица не имеет родительской, возвращается nil.

2.4.1. Интерфейс ITableInfo2
Для таблиц, имеющих полиморфные ссылки, реализуется интерфейс (наследник ITableInfo )
  ITableInfo2 = interface(ITableInfo)
    ['{9DF4C8AC-1DA2-4E7B-BF44-7EDD7A269418}']
    function Get_PolymorphCount: Integer; safecall;
    function Get_PolymorphTable(Index: Integer): ITableInfo; safecall;
    function Get_PolymorphField(Index: Integer): IFieldInfo; safecall;
  end; 
Полиморфной ссылкой является, например, ссылка, физически размещенная в родительской таблице, указывающая на свою запись. Реализация этого интерфейса не является обязательной.
  • функция Get_PolymorphCount возвращает количество полиморфных ссылок.
  • функция Get_PolymorphTable возвращает ссылку на таблицу, на которую указывает полиморфная ссылка номер Index.
  • функция Get_PolymorphTable возвращает ссылку на поле, реализующее полиморфную ссылку номер Index. Это поле должно иметь тип dtReference, информация о его типе должна реализовать интерфейс IReferenceInfo. Значение, возвращаемое функцией Get_TargetTable этого интерфейса в данном случае не имеет значения и игнорируется.

2.4.2. Интерфейс ITableInfo3
Для таблиц, при запросах к которым требуется наложение дополнительных условий отбора, реализуется интерфейс (наследник ITableInfo )
  ITableInfo3 = interface(ITableInfo)
    ['{3FB73AA9-010C-48DA-81C7-E1DCFE2E6136}']
    function GetPersistentClause(const Alias: WideString): WideString; safecall;
    function GetPreConditionsCount: Integer; safecall;
    function GetPreConditionCaption(Index: Integer): WideString; safecall;
    function GetPreConditionCategory(Index: Integer): WideString; safecall;
    function Get_ActivePreCondition(Index: Integer): WordBool; safecall;
    procedure Set_ActivePreCondition(Index: Integer; Value: WordBool); safecall;
    function GetPreConditionParamsCount(Index: Integer): Integer; safecall;
    function GetPreConditionParam(Index: Integer; PreConditionIndex: Integer): IOptionInfo; safecall;
  end;
  • функция GetPersistentClause возвращает выражение дополнительного условия отбора. Алиас таблицы передается в параметре Alias.

2.5. Интерфейс IFieldInfo
Информация о поле поставляется объектом, реализующим интерфейс (наследник INamedItemInfo )
  IFieldInfo = interface(INamedItemInfo)
    ['{19054DAD-8D35-4B39-8EB7-FD3254BD2934}']
    function Get_TypeInfo: ITypeInfo; safecall;
    function Get_DisplayMode: TDisplayMode; safecall;
  end;
  • функция Get_DisplayMode возвращает роль поля при показе таблицы. Возможные значения (тип TDisplayMode):
    • dmAlways - поле является ключевым, всегда показывается
    • dmNever - поле является служебным (первичным ключем, например). Никогда не показывается.
    • dmOnDemand - поле является обычным информационным, показывается по требованию пользователя.
  • функция Get_TypeInfo возвращает ссылку на информацию о типе данных поля. Возвращаете ссылку на один из интерфейсов-наследников интерфейса ITypeInfo

2.6. Интерфейс ITypeInfo
Информация о типах полей поставляется в виде набора объектов, каждый из которых реализует интерфейс (наследник INamedItemInfo )
  ITypeInfo = interface(INamedItemInfo)
    ['{2B6A5E20-3C36-4574-89DB-7C873A5C4A00}']
    function Get_Required: WordBool; safecall;
    function Get_SimpleType: TSimpleType; safecall;
  end;
Информация о конкретном типе передается при помощи реализации одного из наследников этого интерфейса.
  • функция Get_Required возвращает True, если значение поля обязательно для задания.
  • функция Get_SimpleType возвращает информацию о простом типе данных. В зависимости от возвращаемого значения объект должен также реализовывать один из интерфейсов конкретных типов (см. далее). Возможные значения (тип TSimpleType ):

2.6.1. Интерфейс ITypeInfo2
Информация о предоставляемых провайдером дополнительных возможностях фильтрации (наследник интерфейса ITypeInfo)
  ITypeInfo2 = interface(ITypeInfo)
    ['{77F58BDF-F01C-40F3-B193-1027AD8C4EDA}']
    function GetSpecialFilterCount: Integer; safecall;
    function GetSpecialFilterText(Index: Integer): WideString; safecall;
    function EditSpecialFilter(Index: Integer; var Filter: WideString): WordBool; safecall;
  end;
  • функция GetSpecialFilterCount возвращает количество дополнительных элементов списка, выпадающего при выборе фильтра по колонке.
  • функция GetSpecialFilterText возвращает текст дополнительного элемента списка, выпадающего при выборе фильтра по колонке, с номером Index.
  • функция EditSpecialFilter вызывается в момент выбора пользователем дополнительного элемента списка, выпадающего при выборе фильтра по колонке, с номером Index. Значение выражения фильтра передается и возвращается в параметре Filter. Функция возвращает True в случае, если выражение, возвращенное в параметре Filter нужно применить для фильтрации столбца запроса, False - в противном случае.

2.6.2. Интерфейс IStringInfo
Информация о строковом типе (наследник интерфейса ITypeInfo)
  IStringInfo = interface(ITypeInfo)
    ['{74AC4C03-E803-421B-B30D-1A2D2C49827F}']
    function Get_Length: Integer; safecall;
  end;
  • функция Get_Length возвращает максимальную длину строки.

2.6.3. Интерфейс IIntegerInfo
Информация о целочисленном типе (наследник интерфейса ITypeInfo)
  IIntegerInfo = interface(ITypeInfo)
    ['{9003B25E-926D-42AE-A907-813DF3A8343E}']
    function Get_MaxValue: Integer; safecall;
    function Get_MaxValueUsed: WordBool; safecall;
    function Get_MinValue: Integer; safecall;
    function Get_MinValueUsed: WordBool; safecall;
  end;
  • функция Get_MaxValueUsed возвращает True, если значение имеет верхнюю границу.
  • функция Get_MaxValue возвращает верхнюю границу значения, если есть.
  • функция Get_MinValueUsed возвращает True, если значение имеет нижнюю границу.
  • функция Get_MinValue возвращает нижнюю границу значения, если есть.

2.6.4. Интерфейс IFloatInfo
Информация о вещественном типе (наследник интерфейса ITypeInfo )
  IFloatInfo = interface(ITypeInfo)
    ['{E9B56C6D-47DC-4AB9-9E80-6EEF77708704}']
    function Get_MaxValue: Double; safecall;
    function Get_MaxValueUsed: WordBool; safecall;
    function Get_MinValue: Double; safecall;
    function Get_MinValueUsed: WordBool; safecall;
    function Get_Precision: Integer; safecall;
    function Get_Scale: Integer; safecall;
  end;
  • функция Get_MaxValueUsed возвращает True, если значение имеет верхнюю границу.
  • функция Get_MaxValue возвращает верхнюю границу значения, если есть.
  • функция Get_MinValueUsed возвращает True, если значение имеет нижнюю границу.
  • функция Get_MinValue возвращает нижнюю границу значения, если есть.
  • функция Get_Precision возвращает максимальное количество значащих десятичных цифр в значении.
  • функция Get_Scale возвращает максимальное количество десятичных цифр после запятой.

2.6.5. Интерфейс IDateInfo
Информация о типе "Дата" (без времени) (наследник интерфейса ITypeInfo )
  IDateInfo = interface(ITypeInfo)
    ['{DA392510-105F-4655-9A38-18ECA2FBEB97}']
  end;
Не имеет методов.

2.6.6. Интерфейс ITimeInfo
Информация о типе "Время" (без даты) (наследник интерфейса ITypeInfo )
  ITimeInfo = interface(ITypeInfo)
    ['{D7067CAC-67A5-41DB-8D95-40409D8658AB}']
  end;
Не имеет методов.

2.6.7. Интерфейс IDateTimeInfo
Информация о типе "Дата со времемем" (наследник интерфейса ITypeInfo )
  IDateTimeInfo = interface(ITypeInfo)
    ['{7F5CC8F9-8CE1-4DB7-8932-884EF3BAB538}']
  end;
Не имеет методов.

2.6.8. Интерфейс IBooleanInfo
Информация о логическом типе (наследник интерфейса ITypeInfo )
  IBooleanInfo = interface(ITypeInfo)
    ['{8256EDF9-8613-4970-850C-50047839D6BF}']
    function Get_TrueValue: WideString; safecall;
    function Get_FalseValue: WideString; safecall;
  end;
  • функция Get_TrueValue возвращает отображаемую строку для значения True (например, "Да").
  • функция Get_FalseValue возвращает отображаемую строку для значения False (например, "Нет").

2.6.9. Интерфейс IEnumerationInfo
Информация о перечислимом типе (наследник интерфейса ITypeInfo )
  IEnumerationInfo = interface(ITypeInfo)
    ['{B58A3F23-1AAC-4420-ADFF-B23B9938A994}']
    function Get_ItemCount: Integer; safecall;
    function Get_Item(Index: Integer): IEnumerationItem; safecall;
  end;
Перечислимый тип определяет набор значений, которые может принимать поле. Значения в таблице трактуются как равные имени элемента перечисления.
  • функция Get_ItemCount возвращает количество элементов перечисления.
  • функция Get_Item возвращает ссылку на элемент перечисления с номером Index, реализующий интерфейс IEnumerationItem

2.6.10. Интерфейс IReferenceInfo
Информация о типе "ссылка" (наследник интерфейса ITypeInfo )
  IReferenceInfo = interface(ITypeInfo)
    ['{309C8CB1-4A1C-4E58-BC3F-D1AF27861A8F}']
    function Get_TargetTable: ITableInfo; safecall;
  end;
  • функция Get_TargetTable возвращает ссылку на таблицу, с которой осуществляется связь. Возвращается ссылка на интерфейс ITableInfo

2.6.11. Интерфейс IBlobInfo
Информация о типе "больших двоичных объектов" (наследник интерфейса ITypeInfo )
  IBlobInfo = interface(ITypeInfo)
    ['{3905C9C4-EAEB-4844-BB55-3F524F1F3FAC}']
    function Get_SubType: TBlobSubType; safecall;
  end;
  • функция Get_SubType возвращает подтип большого двоичного объекта. Одно из следующих значений (тип TBlobSubType ):
    • bsText - текст
    • bsImage - изображение
    • bsBinary - двоичные данные

2.7. Интерфейс IEnumerationItem
Информация об элементе перечисления (наследник INamedItemInfo )
  IEnumerationItem = interface(INamedItemInfo)
    ['{6953507C-D477-4B8D-9443-A9E5FE7137ED}']
    function Get_Position: Integer; safecall;
  end;
Значения в таблице трактуются как равные имени элемента перечисления.
  • функция Get_Position возвращает позицию элемента перечисления.

3. Использование провайдера БД Парус8

3.1. Использование пользовательских приложений.
Библиотека ParusInfoProvider.dll содержит реализацию провайдера для БД Парус8. Провайдер реализует, в дополнение к обязательным, интерфейс, позволяющий управлять им посредством механизма "Пользовательских приложений":
  IParusProvider = interface(IDispatch)
    ['{4864AE99-80E6-4FC6-9DB0-EAB248F72362}']
    procedure Connect(const Database: WideString;
      const UserName: WideString; 
      const Password: WideString); safecall;
    property QueryObject: OleVariant;
    property StoredProcObject: OleVariant;
  end;
Объект-провайдер может установить связь с БД либо самостоятельно с использованием переданных в метод Connect параметров соединения, либо с помощью объектов Query и StoredProc , предоставляемых системой Парус8 для использования в пользовательских приложениях. В свою очередь, созданный провайдер с установленным соединением может быть передан в метод Execute объекта QueryBuilder.Application . Вторым параметром может быть передано значение, представляющее структуру запроса. Это может быть либо строка с указанием имени файла, либо объект, реализующий интерфейс IStream (например, MSXML.DOMDocument ), либо строка, представляющая собой xml-документ. Все средства манипуляции структурой и поведением запроса предоставляются на уровне работы с xml-документом, описывающим запрос.
        Пример скрипта пользовательского приложения на DelphiScript

procedure QueryBuilderTest;
var
  LApplication: OleVarint;
  LProvider: OleVarint;
  LDocument: OleVariant;
begin
  //описание структуры запроса. Из BLOB, из файла, из строки - откуда угодно
  LDocument := CreateOleObject('MSXML.DOMDocument');
  //LDocument реализует IXMLDOMDocument и IStream
  LDocument.loadXML('<Query Provider="{B3079C97-6EBC-43EB-880F-58F094B322B0}">' +
    '<Item Type="Table" Table="AGNLIST" Alias="MAIN" TableAlias="MAIN">'  +
      '<Item ColumnIndex="0" Type="Field" Field="AGNABBR" Table="AGNLIST" ' + 
        'Alias="MAIN_AGNABBR" TableAlias="MAIN"/>' +
      '<Item ColumnIndex="1" Type="Field" Field="VERSION" Table="AGNLIST" ' + 
        'Alias="MAIN_VERSION" TableAlias="MAIN"/>' +
    '</Item>' +
  '</Query>');

  //Скрытие дерева структуры
  LDocument.documentElement.setAttribute('TreeWidth', 0);

  //Наложение условий отбора на колонку
  LDocument.selectSingleNode('/*/Item/Item[@Field="AGNABBR" and @Table="AGNLIST"]').
    setAttribute('ColumnFilter', 'Б*');

  //Переименование колонки
  LDocument.selectSingleNode('/*/Item/Item[@Field="VERSION" and @Table="AGNLIST"]').
    setAttribute('Caption', 'Версия');


  //создание провайдера и передача ему объектов для соединения с БД
  LProvider := CreateOleObject('ParusInfoProvider.ParusProvider');
  LProvider.QueryObject := Query;
  LProvider.StoredProcObject := StoredProc;

  //создание и использование объекта-приложения QueryBuilder
  LApplication := CreateOleObject('QueryBuilder.Application');

  //В качестве второго параметра передается ОБЪЕКТ, через 
  //   IStream содержащий структуру запроса
  LApplication.Execute(LProvider, LDocument);
  LApplication.Visible := True;

  //Ожидание завершения работы с приложением
  repeat
    Application.ProcessMessages;
  until not LApplication.Visible;

end;

Интерфейс автоматизации поддерживает также метод для автоматического применения шаблона для переноса в Excel.
        Допустим, .MQR-файл, описывающий запрос, содержащий шаблон с именем "Простой Перенос" загружен в раздел "Модули пользовательских приложений" с мнемокодом "QueryData". Для этого необходимо создать модуль пользовательского приложения с типом "COM-сервер" или "Надстройка Excel" и загрузить из файла .MQR-файл. Проверки соответствия формата загружаемого файла заявленному типу модуля пользовательского приложения Парус не производит, что позволяет воспользоваться этим трюком. Тогда:
procedure QueryBuilderTemplateTest;
var
  LApplication: OleVarint;
  LProvider: OleVarint;
  S: string;
begin
  Query.SQL.Text := 'select BMODULE from V_UAMODULES where SCODE = :CODE';
  //мнемокод модуля пользовательского приложения, содержащего
  //загруженный .MQR-файл
  Query.ParamByName('CODE').Value := 'QueryData';
  Query.Open;
  S := Query.FieldByName('BMODULE').AsString;
  Query.Close;

 //создание провайдера и передача ему объектов для соединения с БД
  LProvider := CreateOleObject('ParusInfoProvider.ParusProvider');
  LProvider.QueryObject := Query;
  LProvider.StoredProcObject := StoredProc;

  //создание и использование объекта-приложения QueryBuilder
  LApplication := CreateOleObject('QueryBuilder.Application');

  //В качестве второго параметра передается СТРОКА, содержащая xml с описанием
  //структуры запроса и шаблоны для переноса в Excel
  LApplication.ExecuteTemplate(LProvider, S, 'Простой Перенос');
end;
  

3.2. Информация о базе данных
Провайдер Парус8 предоставляет информацию о четырех типах таблиц:
  1. Представление, описанное при помощи метаданных Парус8 как "вызываемое с клиента". В этом случае полями таблицы являются описанные атрибуты класса с соответствующими типами.
  2. Таблица, имеющая клиентский доступ и связанная с разделом, не имеющим ни одного описанного доступного представления, но имеющим описанные физические атрибуты. Информация о полях берется из метаданных Парус8
  3. Таблица, имеющая клиентский доступ и связанная с разделом, не имеющим ни одного описанного доступного представления, и не имеющим описанных атрибутов. Информация о полях берется из метаданных Oracle.
  4. Таблица, имеющая клиентский доступ и не связанная ни с каким разделом. Информация о полях берется из метаданных Oracle.

4. Разработка шаблонов

Шаблон представляет собой обычную рабочую книгу Excel.

Шаблоны для переноса данных в Excel физически интегрируются внутрь .MQR-файла и хранятся вместе с запросом. Разработку шаблона можно вести независимо, используя только Microsoft Excel (запуская его самостоятельно), а потом загрузить в файл запроса, а можно воспользоваться пунктом меню "Редактировать" на странице "Шаблоны".

Для взаимодействия с источником данных рабочая книга-шаблон должна содержать в любом модуле макрос с именем "Template" (без кавычек) с одним параметром. При выполнении переноса данных по этому шаблону QueryBuilder произведет вызов этого метода, передав в качестве фактического значения параметра объект, реализующий интерфейс IExternalQuery. Никаких других требований к рабочей книге-шаблону не выдвигается.
       
        В примере показан запрос на таблицу AGNLIST (провайдер Oracle), показывающий как простой перенос данных, так и сводную таблицу со сводной диаграммой распределения записей таблицы по полю CRN.
Пример запроса с шаблонами
В примере показан запрос на таблицу "TField" (провайдер Мельницы Данных), показывающий как простой перенос данных, так и сводную таблицу со сводной диаграммой распределения записей таблицы.
Пример запроса с шаблонами для Мельницы Данных`


4.1. Интерфейс IExternalQuery
Объект, реализующий этот интерфейс, передается в макрос генерации отчета Excel (Template). Все его свойства и методы доступны для испоьзования в процессе генерации отчета
  IExternalQuery = interface(IDispatch)
    ['{1A86D1DA-A56E-4D53-88F9-7A035D7D12B4}']
    function Select(const SQL: WideString): IExternalDataSet; safecall;
    function SelectedRecordsCount: Integer; safecall;
    function SelectedRecord(Index: Integer): OleVariant; safecall;
    procedure PlaceCurrentQuery(const Sheet: IDispatch; 
      CaptionsNeeded: WordBool = False; Row: Integer = 1; 
      Column: Integer = 1; ShiftRows: WordBool = True; 
      ShiftColumns: WordBool = False); safecall;
    procedure PlaceQuery(const Sheet: IDispatch; const DataSet: ExternalDataSet;
      Row: Integer = 1; Column: Integer = 1; ShiftRows: WordBool = True; 
      ShiftColumns: WordBool = False); safecall;
    property CurrentQuery: WideString;
  end;
  • функция Select возвращает объект, реализующий интерфейс IExternalDataSet с данными, полученными в результате запроса, заданного параметром SQL. Фактически метод является оберткой метода Perform объекта-провайдера IInfoProvider
  • функция SelectedRecordsCount возвращает количество записей, отмеченных пользователем в гриде в момент выгрузки в Excel
  • функция SelectedRecord возвращает первичный ключ отмеченной пользователем записи с номером Index
  • процедура PlaceCurrentQuery осуществляет перенос в указанное положение указанного рабочего листа данных текущего табличного представления. Параметр Sheet указывает на рабочий лист Excel, на который будет осуществляться перенос, параметр CaptionsNeeded определяет необходимость переноса заголовков колонок, параметры Row и Column определяют соответственно номер строки и столбца на рабочем листе Excel, начиная с которых будут расположены данные. Параметр ShiftRows определяет необходимость сдвига строк вниз при переносе данных (информация в ячейках, лежащих НИЖЕ строки, определенной параметром Row, будет либо затерта, либо сдвинута на требуемое число строк вниз. Параметр ShiftColumns определяет необходимость сдвига колонок вправо при переносе данных (информация в ячейках, лежащих ПРАВЕЕ столбца, определенного параметром Column, будет либо затерта, либо сдвинута на требуемое число строк вниз.
  • процедура PlaceQuery осуществляет перенос в указанное положение указанного рабочего листа данных заданного параметром DataSet набора данных. Параметр Sheet указывает на рабочий лист Excel, на который будет осуществляться перенос, параметр CaptionsNeeded определяет необходимость переноса заголовков колонок, параметры Row и Column определяют соответственно номер строки и столбца на рабочем листе Excel, начиная с которых будут расположены данные. Параметр ShiftRows определяет необходимость сдвига строк вниз при переносе данных (информация в ячейках, лежащих НИЖЕ строки, определенной параметром Row, будет либо затерта, либо сдвинута на требуемое число строк вниз. Параметр ShiftColumns определяет необходимость сдвига колонок вправо при переносе данных (информация в ячейках, лежащих ПРАВЕЕ столбца, определенного параметром Column, будет либо затерта, либо сдвинута на требуемое число строк вниз.
  • свойство CurrentQuery возвращает строку запроса, на основе которого постоено текущее табличное представление.

4.2. Интерфейс IExternalDataSet
Фактически, обертка над интерфейсом IDataSet .
  IExternalDataSet = interface(IDispatch)
    ['{CDC7992C-BB30-431C-9F81-3215175AD5AB}']
    procedure Next; safecall;
    function Eof: WordBool; safecall;
    property FieldCount: Integer;
    property FieldName[Index: Integer]: WideString;
    property Field[FieldIndex: OleVariant]: OleVariant;
  end;
Набор данных представляет собой однонаправленный курсор, каждая строка которого является набором именованных и нумерованных полей.
  • процедура Next осуществляет переход к следующей записи курсора.
  • функция Eof возвращает True в случае достижения конца курсора.
  • свойство FieldCount возвращает количество полей в строке курсора.
  • свойство FieldName возвращает имя поля с номером Index.
  • свойство Field возвращает значение поля, имя или номер которого задан параметром (если строка, то имя, если число, то номер). Допустимо возвращать значение Null для пустых полей.

5. Интерфейс автоматизации
Взаимодействие внешних приложений с QueryBuilder'ом осуществляется при помощи интерфейса
  IApplication = interface(IDispatch)
    ['{0E59D500-7A6A-43CA-8007-B7BB7E393CD4}']
    procedure Execute(const Provider: IUnknown; var Query: OleVariant); safecall;
    procedure ExecuteTemplate(const Provider: IUnknown; var Query: OleVariant; 
      const TemplateName: WideString); safecall;
    property Visible: WordBool;
  end;
  • Свойство Visible определяет видимость приложения
  • Процедура Execute осуществляет выполнение запроса. Первым параметром является объект-провайдер (созданный заранее внешним образом и установивший соединение с БД также заранее). Вторым параметром может быть передано значение, представляющее структуру запроса. Это может быть либо строка с указанием имени файла, либо объект, реализующий интерфейс IStream (например, MSXML.DOMDocument ), либо строка, представляющая собой xml-документ. Все средства манипуляции структурой и поведением запроса предоставляются на уровне работы с xml-документом, описывающим запрос.
  • Процедура ExecuteTemplate осуществляет выполнение запроса и применяет к результатам шаблон с именем, переданным в параметре TemplateName. Первые два параметра аналогичны параметрам метода Execute
Интерфейс автоматизации может быть использован в тех случаях, когда необходима интергация QueryBuilder'a в третьестороннюю информационную систему.