Retornar código gerado de campo autoincremento para a tela, utilizando DBExpress. Automatizando processos com TFieldDataLink.
Saudações companheiros da DevMedia.
Procedure TForm1.AdicionarClick(Sender: TObject);var nI:Integer;Begin SdsTeste.Append;
For nI := 0 To (Self.ComponentCount-1) Do Begin
If Self.Components[nI] Is TText Then SDSTeste.FieldByName( TText( Self.Components[nI] ).DataField ).AsString := TText( Self.Components[nI] ).Text; End;
SdsTeste.Post; SdsTeste.ApplyUpdates(0);
ShowMessage( SDSTeste.FieldByName('Codig_Prod').AsString );End;Fiz uma meia implementação com um TFieldDataLink da biblioteca DBCtrls em um TEdit. Biblioteca essa que contem os componentes da paleta Data Controls. Segui o princípio da implementação desse componente no DBEdit.
Blz, assim eu automatizo a transferência dos dados do DataSet para o Edit com o evento OnDataChage do TFieldDataLink.
Procedure TText.DataChange(Sender:TObject);Begin If ( FDataLink.DataSource <> Nil ) And ( FDataLink.Field = Nil ) Then If Not( FDataLink.DataSource.State In [dsEdit,dsInsert] ) Then Begin Text := FDataLink.Field.DisplayText; End;End;
Porque dessa implementação e não utilizar o DBEdit ? Na utilização dos módulos, não serão seguidos os passos padrões, tipo... Clicar no botão NOVO, Inserir os dados, Clicar no botão SALVAR. Em caso de necessidade de alteração, seleciona o registro, clica no botão ALTERAR...
Como podem ver no primeiro bloco de código que coloquei, já estou efetuando um Append no TSimpleDataSet, logo em seguinda, passandos os valores dos edits para o TSimpleDataSet e por fim, post e ApplyUpdates... Só para ilustrar.
Esses dados são salvos numa tabela onde o campo código é autoincremento. Então, gostaria de saber de vocês, se nesse método que estou utilizando consigo retornar o novo código gerado para o registro novo recem salvo e voltá-lo a tela, para que o usuário possa ver o código gerado para o registro recem cadastrado ?
Outro detalhe, por acaso alguém tem uma idéia de como melhorar esse processo passar os dados dos campos para o DataSet ?
Desde já muito grato !
Att.
Tiago Silva
Tiago Silva
Curtidas 0
Respostas
Marco Salles
28/02/2011
Desculpe a ignorancia , não sei se é o sono , mas que Biblioteca é esta que vc se refere ???
TFieldDataLink da biblioteca DBCtrls ??? Isto é nativo do Delphi.. No Ide Insight não consegui localizar
Sera o sono ????
GOSTEI 0
Tiago Silva
28/02/2011
Eita... será que postei alguma besteira ?
É que estou mexendo na versão XE do Delphi. Porém, observando a versão 6, também encontrei. DBCtrls é a Unit onde tem o componente DBEdit. Cole um DBEdit no form, mande salvar e cancele, verá que ela será automaticamente adicionada.
É a primeira classe da biblioteca.
Agora... será que falei alguma besteira ai ???? Por favor, me corrijam !
Grande abraço !
É que estou mexendo na versão XE do Delphi. Porém, observando a versão 6, também encontrei. DBCtrls é a Unit onde tem o componente DBEdit. Cole um DBEdit no form, mande salvar e cancele, verá que ela será automaticamente adicionada.
É a primeira classe da biblioteca.
Agora... será que falei alguma besteira ai ???? Por favor, me corrijam !
Grande abraço !
GOSTEI 0
Marco Salles
28/02/2011
entendi .. so que não dá para enteder quem é quem neste métodos
Poderia colocar a definição e a classe de cada objeto neste métodos .
Por exemplo
If Self.Components[nI] Is TText Then
TText ??? que classe é esta ??
GOSTEI 0
Tiago Silva
28/02/2011
Hehehe... Sim...
TText é o nome dado ao edit que estou aplicando essas alterações...
Essa é sua Unit, é só para aprendizagem, claro:
Assim ficou meu formulário de testes:
A conexão com o banco de dados fiz diretamente na propriedade Connection do TSimpleDataSet
utilizando seu InternalConnection.
A idéia é que os campos fiquem livres para o usuário. Ele insere o código no campo código e
autmaticamente os outros TText são populados com as devidas informações (isso não tá implementado,
porém, se o SDSTeste estiver populado e vc selecionar um determinado regitro, eles já são passados
para os TText. Isso graças a ligação com o TFieldDataLink).
Ele limpa os campos, informa novos dados e clica em adicionar, então ai é que os registros são lançados
no SdsTeste para logo após ser salvo no banco de dados.
Com isso, o campo código que é autoincremento deveria receber o novo código gerado para ele e ser
mostrado ao usuário.
Acho que agora consegui ser claro ! heheh
Obrigado !
TText é o nome dado ao edit que estou aplicando essas alterações...
Essa é sua Unit, é só para aprendizagem, claro:
Unit Text;
Interface
Uses
StdCtrls, Classes, DB, DBCtrls;
Type
TText = Class(TEdit)
Private
FFieldLink:TDataFieldLink;
Public
Constructor Create(AOwner:TComponent); Override;
Destructor Destroy(); Override;
Protected
Procedure KeyPress(var Key:Char); Override;
Private
Procedure ProximoCampo;
Procedure CampoAnterior;
Procedure DataChange(Sender:TObject);
Procedure OnFieldLinkActivate(Sender:TObject);
Protected
Function GetDataField: WideString;
Procedure SetDataField(Value: WideString);
Function GetDataSource: TDataSource;
Procedure SetDataSource(Value: TDataSource);
Published
Property DataField:WideString Read GetDataField Write SetDataField;
Property DataSource:TDataSource Read GetDataSource Write SetDataSource;
End;
Procedure Register;
Implementation
Uses
Windows, Messages, Controls, SysUtils;
Procedure Register;
Begin
RegisterComponents('FWEdits', [TText]);
End;
{ TText }
// Constructor & Destructor ------------------------------------------------- //
Constructor TText.Create(AOwner: TComponent);
Begin
Inherited Create(AOwner);
ControlStyle := ControlStyle + [csReplicatable];
FFieldLink := TDataFieldLink.Create;
FFieldLink.Control := Self;
FFieldLink.OnDataChange := DataChange;
FFieldLink.OnActiveChange := OnFieldLinkActivate;
Inherited ReadOnly := ( DataSource <> Nil );
End;
Destructor TText.Destroy;
Begin
FreeAndNil(FFieldLink);
Inherited;
End;
// Métodos Protected's Herdados da Classe Pai ------------------------------- //
Procedure TText.KeyPress(var Key:Char);
Begin
Inherited;
If ( Key = #13 ) Then
Begin
Key := #0;
ProximoCampo;
End;
If ( Key = #27 ) Then
Begin
Key := #0;
CampoAnterior;
End;
End;
// Métodos Privates Implementados ------------------------------------------- //
Procedure TText.ProximoCampo;
Begin
SendMessage( Self.Parent.Handle, WM_NEXTDLGCTL, 0, 0 );
End;
Procedure TText.CampoAnterior;
Begin
SendMessage( Self.Parent.Handle, WM_NEXTDLGCTL, 0, 1 );
End;
Procedure TText.DataChange(Sender:TObject);
Begin
If ( FFieldLink.DataSource <> Nil ) And ( FFieldLink.Field = Nil ) Then
If Not( FFieldLink.DataSource.State In [dsEdit,dsInsert] ) Then
Begin
Text := FFieldLink.Field.DisplayText;
End;
End;
Procedure TText.OnFieldLinkActivate(Sender: TObject);
Begin
If FFieldLink.Field <> Nil Then
Begin
Alignment := FFieldLink.Field.Alignment;
MaxLength := FFieldLink.Field.Size;
End
Else
Begin
Alignment := taLeftJustify;
End;
End;
// Métodos de Propriedades Implementadas ------------------------------------ //
Procedure TText.SetDataField(Value: WideString);
Begin
FFieldLink.FieldName := Value;
OnFieldLinkActivate(Self);
End;
Function TText.GetDataField: WideString;
Begin
Result := FFieldLink.FieldName;
End;
Procedure TText.SetDataSource(Value: TDataSource);
Begin
If FFieldLink.DataSource <> Value Then
FFieldLink.DataSource := Value;
End;
Function TText.GetDataSource: TDataSource;
Begin
Result := FFieldLink.DataSource;
End;
End.
Assim ficou meu formulário de testes:
Unit Unit1;
Interface
Uses
Forms, Controls, StdCtrls, Classes, Text, Grids, DBGrids, DB, DBClient,
SimpleDS, DBXFirebird, ExtCtrls, DBCtrls;
type
TForm1 = Class(TForm)
Text1: TText;
Label1: TLabel;
Text2: TText;
Label2: TLabel;
Text3: TText;
Label3: TLabel;
DBGrid1: TDBGrid;
Adicionar: TButton;
SDSTeste: TSimpleDataSet;
DtsTeste: TDataSource;
procedure AdicionarClick(Sender: TObject);
procedure FormShow(Sender: TObject);
Private
Public
End;
var
Form1: TForm1;
Implementation
Uses
Dialogs;
{$R *.dfm}
Procedure TForm1.FormShow(Sender: TObject);
Begin
SdsTeste.CreateDataSet;
End;
Procedure TForm1.AdicionarClick(Sender: TObject);
var nI:Integer;
Begin
SdsTeste.Append;
For nI := 0 To (Self.ComponentCount-1) Do
Begin
If Self.Components[nI] Is TText Then
SDSTeste.FieldByName( TText( Self.Components[nI] ).DataField ).Text :=
TText( Self.Components[nI] ).Text;
End;
SdsTeste.Post;
SdsTeste.ApplyUpdates(0);
ShowMessage( SDSTeste.FieldByName('Codig_Prod').AsString );
End;
End.
A conexão com o banco de dados fiz diretamente na propriedade Connection do TSimpleDataSet
utilizando seu InternalConnection.
A idéia é que os campos fiquem livres para o usuário. Ele insere o código no campo código e
autmaticamente os outros TText são populados com as devidas informações (isso não tá implementado,
porém, se o SDSTeste estiver populado e vc selecionar um determinado regitro, eles já são passados
para os TText. Isso graças a ligação com o TFieldDataLink).
Ele limpa os campos, informa novos dados e clica em adicionar, então ai é que os registros são lançados
no SdsTeste para logo após ser salvo no banco de dados.
Com isso, o campo código que é autoincremento deveria receber o novo código gerado para ele e ser
mostrado ao usuário.
Acho que agora consegui ser claro ! heheh
Obrigado !
GOSTEI 0
Wilson Junior
28/02/2011
Porque o seu TText não pode herdar do TDBEdit?
GOSTEI 0
Tiago Silva
28/02/2011
Porque o TDBEdit só tem seu ReadOnly setado como False quando ele está amarrado a um TDataSource e um TField e, ainda assism, quando o DataSet amarrado ao TDataSource está em modo de edição ( dsEdit, dsInsert ).
E é disso que estou fugindo.
E é disso que estou fugindo.
GOSTEI 0
Marco Salles
28/02/2011
Vamos com calma , para não perder o foco .. Para te entender melhor estou tentando compilar a Unidade
Porém não reconhece TDataFieldLink .. ??
Procurei esta classe no site da embarcadero e tb não encontrei ???
GOSTEI 0
Tiago Silva
28/02/2011
opa, inverte ai, é TFieldDataLink... heheh
GOSTEI 0
Tiago Silva
28/02/2011
Pessoal, valeu ai pela força.
Vou criar um método onde eu passo o formulário como parâmetro, nesse método terei esse loop que fiz com o FOR para popular o TSimpleDataSet.
E pronto, problema resolvido... Grande abraço !
Valeu !
Vou criar um método onde eu passo o formulário como parâmetro, nesse método terei esse loop que fiz com o FOR para popular o TSimpleDataSet.
E pronto, problema resolvido... Grande abraço !
Valeu !
GOSTEI 0