Блог Александра Божко
Архивы
Рубрики
Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

В этом посте, как и обещал, немного расскажу об утилите, позволяющей вставлять элементы структуры БД в текст, посредством буфера обмена. Рабочее название DB2Clipboard.

Зачем это нужно?

Утилита избавляет разработчика от необходимости постоянно обращаться к СУБД при необходимости найти названия поля в определенной таблице. Название поля и другая информация, взятая из структуры БД (тип и размер поля, название таблицы и т.д. ),  могут быть вставлены в код приложения буквально с помощью одного нажатия кнопки мыши. При этом, в качестве редактора кода может быть использован не только Delphi, а в любой редактор.

Собственно, это развитие того приложения, о котором я писал больше года назад.

Как это работает?

В данной версии программы, структура базы данных загружается из  .xsd файла, который генерируется с помощью ERStudio (см. предыдущий пост). В отличие от предыдущего варианта данная версия может работать практически с любой СУБД. Минус, собственно заключается в том, что требуется ERStudio. Как и раньше на экране висит StayOnTop форма в левой части которой находится список таблиц (представлений, запросов и т.д.), а справа – набор кнопок, каждая из которых соответствует полю в соответствующей таблице. То, как это выглядит на практике показано на видео. Рекомендую смотреть в HD в полноэкранном режиме.

 Что сделано?

В настоящей версии поддерживаются скрипты. Т.е. можно вставить не только непосредственно имя поля, но и некий текст сгенерированный на основе данных модели. Например, если активирован скрипт

FieldByName(‘<fn>’).as<ft>;,

то вместо <fn> в текст будет вставляться имя поля, а вместо <ft> – его тип. Так же реализована поддержка циклического перебора полей и имитация нажатия некоторых клавиш (Enter, Home, Tab и т.д.).

Как это реализовано?

Поразмыслив, я решил полностью переработать структуру программы. Написал несколько классов.

TmbsTimer = class(TTimer)
 {skip}

 public
  property fgw: HWND read Ffgw write SetFGW;
end;

TmbsTableInfo = class
{skip}
 public

 constructor Create;

  property TblName: string read GetTableName write SetTableName;
  property FieldList: TmbsFieldList read GetFieldList  write SetFieldList;
end;

TmbsTableList = class
{skip}
  public
    { public declarations }
    constructor Create;
    procedure Add(pTable: TmbsTableInfo);
    procedure Delete(Index: Integer);
    function Count: Integer;
    procedure ImportXML(FileName: string);
    procedure Clear;

    property Tables[Index: Integer]: TmbsTableInfo read GetTable; default;
end;

TmbsFieldInfo =  class
{skip}
  public
  property FldName: string read GetFLDName write SetFLDName;
  property Table: TmbsTableInfo read GetTable write SetTable;
  property FldSize: integer read GetFldSize write SetFldSize;
  property FldType: string read GetFldType write SetFldType;
  property Checked: boolean read GetChecked write SetChecked;

end;

TmbsFieldList = class

{skip} 

  public
    { public declarations }
    constructor Create;
    procedure Add(pField: TmbsFieldInfo);
    procedure Delete(Index: Integer);
    function Count: Integer;
    property Table: TmbsTableInfo read GetTable write SetTable;
    property Fields[Index: Integer]: TmbsFieldInfo read GetField; default;
  published
    { published declarations }
end;

  TmbsCustomButton = class(TBitBtn)
{skip}
  public
    { Public declarations }
    procedure Click; override;
    property FGW: HWND read FFGW write SetFGW;
    constructor Create(AOwner: TComponent);  override; //; Fld: TmbsFieldInfo
    destructor Destroy; override;
  published
    { Published declarations }
    property InsertedText: string read GetInsertedText write SetInsertedText;
    property Timer: TmbsTimer read GetMbsTimer write SetmbsTimer;
  end;

  TmbsTblButton = class(TmbsCustomButton)
{skip}
  public
    { Public declarations }
     function ExpressionToInsString(AEpression: string): string;
     procedure Click; override;

  published
    { Published declarations }
    constructor Create(AOwner: TComponent);  override; //; Fld: TmbsFieldInfo
    property Expression: string read GetExpression write SetExpression;
    property DefExpressionIndex: integer read GetDefExpressionIndex write SetDefExpressionIndex;
    property Table: TmbsTableInfo read GetTable write SetTable;
  end;

  TmbsFieldButton = class(TmbsCustomButton)
{skip}
  public
    { Public declarations }
    class function ReplaceTblTags(s: string; aTbl: TmbsTableInfo): string; static;
     function ExpressionToInsString(AEpression: string): string;
     procedure Click; override;
  published
    { Published declarations }

    constructor Create(AOwner: TComponent);  override; //; Fld: TmbsFieldInfo
    property Field: TmbsFieldInfo read GetField write SetField;
    property InsertType: TmbsFldInsType read GetInsertType write SetInsertType;
    property Expression: string read GetExpression write SetExpression;
    property DefExpressionIndex: integer read GetDefExpressionIndex write SetDefExpressionIndex;
  end;

  TmbsFieldCheckBox = class(TcheckBox)
{skip}

 published
    { Published declarations }

    constructor Create(AOwner: TComponent);  override; //; Fld: TmbsFieldInfo
    property Field: TmbsFieldInfo read GetField write SetField;

  end;

Выше приведены фрагменты описания классов. Вкратце, что для чего…

  • TmbsTimer – таймер, который “слушает” систему на предмет текущего окна, хэндл которого и хранит в свойстве fgw.
  • TmbsTableInfo – информация о таблице, содержит название таблицы и список полей.
  • TmbsTableList – список таблиц. Кроме обычных для списка методов содержит метод ImportXML.
  • TmbsFieldInfo- информация о поле
  • TmbsFieldList- список полей
  • TmbsCustomButton- базовый класс, реализующий кнопку, которая вставляет текст в активное окно (то самое, хэндл которого хранит таймер).
  • TmbsTblButton – кнопка, вставляющая информацию о таблице.
  • TmbsFieldButton – кнопка, вставляющая информацию о поле.
  • TmbsFieldCheckBox- чекбокс, для выбора полей, обрабатываемых в выражении.

Вполне возможно, что код будет рефакториться, но такая организация классов уже сейчас позволяет довольно легко построить пользовательский интерфейс.

Что дальше?

Естественно, самым логичным шагом было бы обеспечить прямой импорт структуры непосредственно из БД. Что я и планирую сделать используя FireDAC.

Кроме того, работа над эргономикой. Например, фильтр таблиц, “горячие клавиши” и т.д.

А можно посмотреть?

Все что сделано в рамках данного проекта, я делал для себя. Пока я не имею представления о дальнейшем его развитии. Возможно, это будет полностью бесплатное приложение, возможно коммерческое, а возможно очередной “мёртвый проект”. Я не спешу выкладывать его в открытый доступ, но обещаю, что все читатели моего блога при желании смогут получить программу бесплатно. Те, кому не терпится посмотреть как это работает могут написать сюда и получить ссылку на приложение в том виде, в котором оно есть.


Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика