Fórum Retornar código gerado de campo autoincremento para a tela, utilizando DBExpress. Automatizando processos com TFieldDataLink. #396484
28/02/2011
0
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
Curtir tópico
+ 0Posts
01/03/2011
Marco Salles
Gostei + 0
01/03/2011
Tiago Silva
É 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
01/03/2011
Marco Salles
Gostei + 0
01/03/2011
Tiago Silva
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
01/03/2011
Wilson Junior
Gostei + 0
01/03/2011
Tiago Silva
E é disso que estou fugindo.
Gostei + 0
01/03/2011
Marco Salles
Gostei + 0
01/03/2011
Tiago Silva
Gostei + 0
01/03/2011
Tiago Silva
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
Clique aqui para fazer login e interagir na Comunidade :)