Caros amigos,

Gostaria de compartilhar um pouco do meu conhecimento com vocês através deste componente desenvolvido conforme minha necessidade.

Espero que seja de grande utilidade para todos.

Como percebemos em muitos fóruns, várias pessoas buscam componentes de data para Banco de Dados. Nesta matéria você vai aprender a criar o seu próprio componente para acesso a datas com banco de dados.

Se você só desejar pegar o componente, segue abaixo a Unit correspondente ao Componente, que é derivado de TDateTimePicker. Mas se quer aprender e mais detalhes, logo mais abaixo terá as explicações.

unit DBDateTimePicker;

interface

uses
SysUtils, Classes, Controls, ComCtrls, Forms, Dialogs, Graphics, DBCtrls,
DB, stdctrls;

type
TDBDateTimePicker = class(TDateTimePicker)
private
{ Private declarations }
FDataLink : TFieldDataLink;
function GetDataField:String;
procedure SetDataField(const Value : string);
function GetDataSource:TDataSource;
procedure SetDataSource(const Value : TDataSource);
procedure DataChange(Sender:TObject);
procedure UpdateData(Sender:TObject);
procedure Change;override;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property Field: TField read GetField;
published
{ Published declarations }
property DataSource : TDataSource read GetDataSource Write
SetDataSource;
property DataField : String read GetDataField write SetDataField;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents("Fernando", [TDBDateTimePicker]);
end;

{ TDBDateTimePicker }

procedure TDBDateTimePicker.Change;
begin
FDataLink.Modified;
inherited Change;
Try
FDataLink.Edit;
FDataLink.UpdateRecord;
Except
End;
end;

constructor TDBDateTimePicker.Create(AOwner: TComponent);
begin
inherited;
FDataLink := TFieldDataLink.Create;
FDataLink.OnDataChange := DataChange;
FDataLink.OnUpdateData := UpdateData;
FDataLink.Control := self;
Width := 100;
end;

procedure TDBDateTimePicker.DataChange(Sender: TObject);
begin
Date := FDataLink.Field.AsDateTime;
end;

destructor TDBDateTimePicker.Destroy;
begin
FDataLink.Free;
inherited;
end;

function TDBDateTimePicker.GetDataField: String;
begin
Result := FDataLink.FieldName;
end;

function TDBDateTimePicker.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;

procedure TDBDateTimePicker.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;

procedure TDBDateTimePicker.SetDataSource(const Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;

procedure TDBDateTimePicker.UpdateData(Sender: TObject);
begin
FDataLink.Field.AsDateTime := FDataLink.Field.AsDateTime;
end;

end.

Detalhes:

Quem já conhece o desenvolvimento de componentes para Banco de Dados, pode achar que basta criar as propriedades comuns em banco de dados:

DataSource - Que identifica o objeto da classe TDataSource ao qual o componente está vinculado.
DataField - O nome do campo da tabela cujo valor do registro corrente será exibido e/ou editado pelo componente.

Porém, como a Borland é maravilhosa, ela desenvolveu uma nova classe chamada TFieldDataLink, será desta que criaremos um componente para acessos a Dados. Esta classe possui duas propriedades principais:

DataSource - Que identificará o componente da classe TDataSource ao qual o nosso componente será vinculado.
FieldName - Que indentificará o nome do campo ao qual o nosso componente será vinculado.

Agora, ao invés de criarmos campos internos, basta usar as propriedades da classe TFieldDataLink (que precisa ser criado e destruído por nosso Componente).

Antes de começarmos, precisamos declarar certas Units:

dbctrls - onde se encotra a classe TFieldDataLink.
db - onde se encontra a classe TDataSource.

uses
SysUtils, Classes, Controls, ComCtrls, Forms, Dialogs, Graphics, DBCtrls,
DB, stdctrls;

Vamos lá..

Precisaremos então criar um objeto interno do tipo TFieldDataLink.

Na sessão private:

FDataLink : TFieldDataLink;

Agora precisamos definir o método de leitura e de escrita dos campos DataSource e DataField. Normalmente, Get Leitura, Set escrita.

-----DataSource
function GetDataSource : TDataSource;
procedure SetDataSource(Value : TDataSource);
-----DataField
function GetDataField : string;
procedure SetDataField(Value : string);

Vamos declarar as propriedades que aparecerão no Object Inspector. Na área Published declarar:

property DataSource : TDataSource read GetDataSource write SetDataSource;
property DataField : string read GetDataField write SetDataField;

Iremos agora implementar esses métodos pressionando CTRL+SHIFT+C

function TDBDateTimePicker.GetDataSource: TDataSource;
begin
Result := FDataLink.DataSource;
end;

procedure TDBDateTimePicker.SetDataSource(const Value: TDataSource);
begin
FDataLink.DataSource := Value;
end;

function TDBDateTimePicker.GetDataField: String;
begin
Result := FDataLink.FieldName;
end;

procedure TDBDateTimePicker.SetDataField(const Value: string);
begin
FDataLink.FieldName := Value;
end;

Vamos definir o método de "Construção" e de "Destruição". Faremos assim, dentro de public:

destructor Destroy;override;
constructor Create(Aowner : TComponent);override;

Pressionando Novamente CTRL+SHIFT+C

Implementaremos esses métodos assim:

constructor TDBDateTimePicker.Create(AOwner: TComponent);
begin
inherited;
FDataLink := TFieldDataLink.Create;
end;

destructor TDBDateTimePicker.Destroy;
begin
FDataLink.Free;
inherited;
end;

Aparentemente nosso componente está funcionando. Mas somente se você desejar EXIBIR os dados. Se alterado o seu conteúdo, ele não sofrerá modificações, pois não há nenhum método para identificar esta modificação. Então vamos lá.

Na classe TFieldDataLink tem o evento OnDataChange, que é executado sempre que o valor armazenado for modificado.

Na área private:

procedure DataChange(Sender : TObject);

Implementamos com CTRL+SHIFT+C e completaremos da seguinte forma:

procedure TDBDateTimePicker.DataChange(Sender: TObject);
begin
Date := FDataLink.Field.AsDateTime;
end;

Precisamor associá-lo ao evento OnDataChange de FDataLink, faremo isso no Create da seguinte forma:

FDataLink.OnDataChange := DataChange

Agora precisaremos criar um componente para refletir alterações feitas pelo próprio componente. O procedimento responsável por isso é o OnUpdateData do FDataLink, novamente na área Private:

procedure UpdateData(Sender : TObject).

Implementamos com CTRL+SHIFT+C e completaremos da seguinte forma:

procedure TDBDateTimePicker.UpdateData(Sender: TObject);
begin
FDataLink.Field.AsDateTime := FDataLink.Field.AsDateTime;
end;

Precisamos associá-lo ao evento OnUpdateData de FDataLink. Faremos isso no Create da seguinte forma:

FDataLink.OnUpdateData := UpdateData;

Precisaremos ainda, criar o método change da classe-base de maneira que o valor armazenado no campo seja alterado sempre que o usuário alterar o texto exibido pelo componente

Na área private:

procedure Change;override;

Implementamos...

procedure TDBDateTimePicker.Change;
begin
FDataLink.Modified;
inherited Change;
Try
FDataLink.Edit;
FDataLink.UpdateRecord;
Except
End;
end;

É isso! Fique a seu critério fazer alguma mudança nos procedimentos. Dica: Colocando try..except, quando o componente estiver associado a um datasource e este for retirado,
precisaremos colocar estas mudanças no nosso componente, pois poderá haver
um erro.

Se algum quiser mais dicas para implementarmos este nosso componente, só entrar em contato.

Espero que curtam a Dica. Qualquer elogio, crítica ou sugestão é só entrar em contato
por e-mail ou deixar um comentário.

e-mail: fernando_tremonti@yahoo.com.br

msn: fernando_tremonti@hotmail.com


Abraços.