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

Tiago Silva

Responder

Posts

01/03/2011

Marco Salles

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 ????
Responder

Gostei + 0

01/03/2011

Tiago Silva

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 !
Responder

Gostei + 0

01/03/2011

Marco Salles

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 ??
Responder

Gostei + 0

01/03/2011

Tiago Silva

Hehehe... Sim...
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 !
Responder

Gostei + 0

01/03/2011

Wilson Junior

Porque o seu TText não pode herdar do TDBEdit?
Responder

Gostei + 0

01/03/2011

Tiago Silva

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.
Responder

Gostei + 0

01/03/2011

Marco Salles

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 ???
Responder

Gostei + 0

01/03/2011

Tiago Silva

opa, inverte ai, é TFieldDataLink... heheh
Responder

Gostei + 0

01/03/2011

Tiago Silva

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 !
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar