Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Classe Delphi

Fazer download em docx, pdf ou txt
Fazer download em docx, pdf ou txt
Você está na página 1de 42

Olá Galera, vamos ver neste artigo um pouco sobre classes.

Vou
mostrar como criar uma classe do zero, e explicar o que o Delphi faz quando
usamos CTRL + SHIF + C ( Comando para implementar as propriedades e
Métodos de uma determinada classe ).

Inicialmente vamos criar uma Classe chamada de TCliente, para isso criarmos


uma unit, e vamos salvar seu nome como uCliente.pas
unit uCliente;
  interface
  implementation
end.

Neste momento vamos criar a classe

Veja no código abaixo, como vamos criar a classe no Delphi.


unit uCliente;

interface
  Type

  TCliente = class
  private

  protected

  public

  published

  end;

implementation

end.

Criaremos agora as propriedades básicas da Classe TCliente, ID, Nome, Sexo,


CPF, RG, Telefone, Endereco, Bairro, Cidade, CEP.

Veja o código como ficará.


unit uCliente;

interface
  Type

  TCliente = class
  private

  protected

  public

  published

  end;

implementation

end.

Vamos criar as propriedades básicas da Classe TCliente, ID, Nome, Sexo,


CPF, RG, Telefone, Endereco, Bairro, Cidade, CEP.

Veja o código como ficará


unit uCliente;

interface
  Type

  TCliente = class
  private

  protected

  public
    property ID       :String;
    property Nome     :String;
    property Sexo     :String;
    property CPF      :String;
    property RG       :String;
    property Telefone :String;
    property Endereco :String;
    property Bairro   :String;
    property Cidade   :String;
    property CEP      :String;

  published
  end;
implementation

end.
Ao final da digitação da property CEP: String, iremos usar a combinação de
teclas CTRL + SHIF + C, para implementar a classe.
Seu código agora irá modificar complementa, incluindo várias procedures e
Fields. Vamos analisar como ficou o código.
unit uCliente;

interface
  Type

  TCliente = class
  private
    FNome: String;
    FBairro: String;
    FCEP: String;
    FID: String;
    FCPF: String;
    FSexo: String;
    FCidade: String;
    FEndereco: String;
    FTelefone: String;
    FRG: String;
    procedure SetBairro(const Value: String);
    procedure SetCEP(const Value: String);
    procedure SetCidade(const Value: String);
    procedure SetCPF(const Value: String);
    procedure SetEndereco(const Value: String);
    procedure SetID(const Value: String);
    procedure SetNome(const Value: String);
    procedure SetRG(const Value: String);
    procedure SetSexo(const Value: String);
    procedure SetTelefone(const Value: String);

  protected

  public
    property ID       :String read FID write SetID;
    property Nome     :String read FNome write SetNome;
    property Sexo     :String read FSexo write SetSexo;
    property CPF      :String read FCPF write SetCPF;
    property RG       :String read FRG write SetRG;
    property Telefone :String read FTelefone write SetTelefone;
    property Endereco :String read FEndereco write SetEndereco;
    property Bairro   :String read FBairro write SetBairro;
    property Cidade   :String read FCidade write SetCidade;
    property CEP      :String read FCEP write SetCEP;

  published

  end;
implementation

{ TCliente }

procedure TCliente.SetBairro(const Value: String);


begin
  FBairro := Value;
end;

procedure TCliente.SetCEP(const Value: String);


begin
  FCEP := Value;
end;

procedure TCliente.SetCidade(const Value: String);


begin
  FCidade := Value;
end;

procedure TCliente.SetCPF(const Value: String);


begin
  FCPF := Value;
end;

procedure TCliente.SetEndereco(const Value: String);


begin
  FEndereco := Value;
end;

procedure TCliente.SetID(const Value: String);


begin
  FID := Value;
end;

procedure TCliente.SetNome(const Value: String);


begin
  FNome := Value;
end;

procedure TCliente.SetRG(const Value: String);


begin
  FRG := Value;
end;

procedure TCliente.SetSexo(const Value: String);


begin
  FSexo := Value;
end;

procedure TCliente.SetTelefone(const Value: String);


begin
  FTelefone := Value;
end;

end.
O que houve?

Para cada property criada, por exemplo:    property ID       :String; . O Delphi
criou 2 métodos de leitura(Read) e escrita(Write) :    property ID       :String
read FID write SetID; , onde:
    FID = Field para armazenar o valor passado para propriedade
    SetID = Procedure para validar por exemplo um ID já existe, ou então se o
CPF é válido, e logo em seguida atribuir o conteúdo informado para o Field
FID, veja como o Delphi implementa o SetID;

procedure TCliente.SetID(const Value: String);


begin
  FID := Value;
end;

Com este método o parâmetro Const(não pode ser alterado dentro do método)
Value contém o valor informado quando usamos por exemplo :

Procedure TFrmCliente.Novo;
begin
   Cliente.ID := 1;
End;

Sendo assim, o que este método SetID faz simplesmente é armazenar o Value
em FID, como a linha abaixo mostra :
FID := Value

O código fica bem grande, dando a entender que fizemos muitas


implementações e tudo mais, porém fizemos alguma validação com os
campos ? Fizemos alguma regra de negocio ? NÃO!!!
Vamos implementar uma regra básica para entendermos como fazer e depois
adaptar. Supondo que gostaríamos de validar a quantidade de caracteres de um
CPF, contando os pontos e traço. Sendo assim teríamos 14 caracteres, como
um exemplo 123.456.789-01.

Usando a função Length , encontrada na unit System, podemos ver o tamanho


de uma string, veja como ficaria o código para saber se foi informado 14
caracteres ou não.
procedure TCliente.SetCPF(const Value: String);
begin
  If Length(Value) = 14 Then
     FCPF := Value
  else
    raise Exception.Create('CPF inválido, número de caracteres maior
ou menor que 14');
    //Para usar o Exception devemos dar uses em SysUtils;
end;

Com isso temos uma suposta regra de negócios, onde o CPF tem que 14
caracteres, nem a mais, nem a menos. Voltando então a pergunta inicial,
temos regras de negocio nesta nossa classe de Cliente ? Inicialmente não ,
então não precisamos ter procedures SetID, SetNome,SetCPF,Set.... O que
vou fazer é bem simples , mas requer muita atenção.  Inicialmente vamos
apagar todas as procedures declaradas e implementadas. Feito isso seu código
ficará assim :
unit uCliente;

interface
 uses SysUtils;

  Type
  TCliente = class
  private
    FNome: String;
    FBairro: String;
    FCEP: String;
    FID: String;
    FCPF: String;
    FSexo: String;
    FCidade: String;
    FEndereco: String;
    FTelefone: String;
    FRG: String;
{REMOVEMOS AS DECLARAÇÕES DAS PROCEDURES DAQUI }
  protected

  public
    property ID       :String read FID write SetID;
    property Nome     :String read FNome write SetNome;
    property Sexo     :String read FSexo write SetSexo;
    property CPF      :String read FCPF write SetCPF;
    property RG       :String read FRG write SetRG;
    property Telefone :String read FTelefone write SetTelefone;
    property Endereco :String read FEndereco write SetEndereco;
    property Bairro   :String read FBairro write SetBairro;
    property Cidade   :String read FCidade write SetCidade;
    property CEP      :String read FCEP write SetCEP;

  published

  end;

implementation

{REMOVEMOS AS IMPLEMENTAÇÕES DAS PROCEDURES DAQUI }

end.

Já esta pronto ? Não!! Falta agora remover o método de escrita(Write) nas


propertys e modificar para escrever diretamente nos Fields, mas como assim?
Veja abaixo o código
unit uCliente;

interface
  Type

  TCliente = class
  private
    FNome: String;
    FBairro: String;
    FCEP: String;
    FID: String;
    FCPF: String;
    FSexo: String;
    FCidade: String;
    FEndereco: String;
    FTelefone: String;
    FRG: String;
  protected
  public
{Observe que onde esta SetID, SetNome, Set... Foi modificado agora
para FID, FNome,F...}

    property ID       :String read FID write FID;


    property Nome     :String read FNome write FNome;
    property Sexo     :String read FSexo write FSexo;
    property CPF      :String read FCPF write FCPF;
    property RG       :String read FRG write FRG;
    property Telefone :String read FTelefone write FTelefone;
    property Endereco :String read FEndereco write FEndereco;
    property Bairro   :String read FBairro write FBairro;
    property Cidade   :String read FCidade write FCidade;
    property CEP      :String read FCEP write FCEP;

  published

  end;

implementation

end.

Como vocês podem ver a Unit  fica mais limpa, a classe fica bem mais
simples de se visualizar e dar manutenção, agora atenção, isso é se você não
tiver regras de negocio para suas propertys ok? Caso tenha você faz como o
Delphi implementa, cria a procedure, associa ela ao Write da property e
implementa ela com sua regra de negócio. Ficará então da seguinte forma com
a única regra de negocio que criamos, a do tamanho do CPF
unit uCliente;

interface
  uses SysUtils;

  Type

  TCliente = class
  private
    FNome: String;
    FBairro: String;
    FCEP: String;
    FID: String;
    FCPF: String;
    FSexo: String;
    FCidade: String;
    FEndereco: String;
    FTelefone: String;
    FRG: String;

   {Metodo de validação do CPF}


    procedure SetCPF(const Value: String);

  protected

  public
    property ID       :String read FID write FID;
    property Nome     :String read FNome write FNome;
    property Sexo     :String read FSexo write FSexo;
   {Property CPF agora tem um mecanismo de validação para sua escrita}
    property CPF      :String read FCPF write SetCPF;
    property RG       :String read FRG write FRG;
    property Telefone :String read FTelefone write FTelefone;
    property Endereco :String read FEndereco write FEndereco;
    property Bairro   :String read FBairro write FBairro;
    property Cidade   :String read FCidade write FCidade;
    property CEP      :String read FCEP write FCEP;

  published

  end;

implementation

{ TCliente }

procedure TCliente.SetCPF(const Value: String);


begin
  If Length(Value) = 14 Then
     FCPF := Value
  else
    raise Exception.Create('CPF inválido, número de caracteres maior
ou menor que 14');
end;

end.

Para usar sua classe e testar, faça o seguinte: crie um form e coloque um
BitBtn.

Precisamos dar Uses em uCliente para poder acessar a Classe TCliente. Feito
isso, no evento onClick do BitBtn, implemente o seguinte :
procedure TFrmCliente.BtnNovoClick(Sender: TObject);
Var
  C: TCliente;
Begin
    C := TCliente.Create;
    C.Nome:= 'WESLEY YAMAZACK'  ;
    C.Bairro:= 'CENTRO'  ;
    C.CEP:= '216548-856 '  ;
    C.ID:= '00005'  ;
    C.CPF := '123.456.789-100'  ; // Deste jeito você vera o erro
    C.CPF := '123.456.789-10'  ; // Deste jeito irá funcionar
    C.Sexo:= 'M'  ;
    C.Cidade:= 'RIO DE JANEIRO '  ;
    C.Endereco:= 'RUA M, N 145, APTO 809'  ;
    C.Telefone:= '(21)3222-1111 '  ;
    C.RG:= '12.313.214-1'  ;
    C.Free;
end;
POO e DAO Pattern no Delphi: Criando uma tela de login

Veja neste artigo como utilizar de maneira prá tica assuntos como Programaçã o Orientada a

Objetos, DAO Pattern, e o framework DbExpress 4, assuntos muito importantes dentro da

comunidade Delphi.

Introdução
A POO (Programação Orientada a Objetos), cujos pilares básicos são: Herança,
Polimorfimo e Encapsulamento, é uma metodologia inteligente de desenvolvimento de
software, que visa tornar os sistemas mais flexiveis a mudanças, fáceis de manter, e
permite uma grande reutilização de código.

Um dos problemas encontrados em sistemas escritos de maneira procedural é a


descentralização de responsabilidades (regras de negócio misturadas a camada de
apresentação), onde o mesmo código aparece repetidas vezes em diferentes pontos do
sistema, tornando o custo de manutenção cada vez maior. Não são raros os casos de
empresas que precisaram reescrever sistemas do zero por tais problemas.

Para corrigir este problema, podemos utilizar a POO em conjunto com o Design
Pattern DAO.

O Padrão DAO (Data Access Object) é um pattern que permite separar acesso a dados e
regras de negócio da camada de apresentação, centralizando as responsabilidades de
manipulação do banco de dados e facilitando a manutenção.

Neste tutorial criaremos um sistema simples de Login, utilizando conceitos de


programação orientada a objetos e separação de camadas com DAO Pattern, utilizando
a linguagem e IDE Delphi.

O Delphi é uma linguagem de alto nível, compilada, fortemente tipada, que suporta os
paradigmas de programação estruturada e orientada a objetos, sendo uma excelente
ferramenta de desenvolvimento.

Para esse artigo foi utilizado o Delphi XE e banco de dados Firebird 2.5

Criação do Projeto
Crie um novo diretório, onde serão salvos o Banco de Dados (caso use
firebird/interbase) e os arquivos do Projeto.

Utilizando o Banco de Dados e o Front End de sua preferência, crie um novo banco e
execute os scripts abaixo para criação da tabela Usuarios, e o usuario administrador,
respectivamente:
Listagem 1: Scripts do Banco de Dados

// Criação da tabela USUARIOS

CREATE TABLE USUARIOS

  CODIGO     INTEGER NOT NULL,

  USUARIO    VARCHAR(20) NOT NULL,

  SENHA  VARCHAR(20) NOT NULL,

CONSTRAINT PK_USUARIOS PRIMARY KEY (CODIGO)

// INSERT do primeiro Usuario da tabela

INSERT INTO USUARIOS (CODIGO, USUARIO, SENHA) VALUES


(1,’administrador’,’admin123’)

Utilizando o Delphi, crie um novo projeto no Menu New -> VCL Forms Application –


Delphi.

Adicione uma nova Unit ao projeto no Menu New -> Unit –Delphi.

Iremos utilizar a nova Unit para criação da classe TLoginModel, que será responsável
por transferir informações entre a camada de negócios e a camada de apresentação.

A classe TLoginModel possui dois campos, que são: FUsuario e FSenha.

Respeitando as boas práticas de POO, não iremos expor publicamente nossos campos,
mas iremos encapsular o acesso a eles utilizando métodos getters, setters e propriedades.

Listagem 2: Class TLoginModel

unit uLoginModel;

interface

  Type

   TLoginModel = class

    strict private

      // campos
      FUsuario: string;

      FSenha: string;

      // getters

      function GetUsuario: string;

      function GetSenha: string;

      // setters

      procedure SetUsuario(const Value: string);

      procedure SetSenha(const Value: string);

    public

      // propriedades

      property Usuario : string read GetUsuario write SetUsuario;

      property Senha : string read GetSenha write SetSenha;

   end;

implementation

{ TLoginModel }

function TLoginModel.GetSenha: string;

begin

 Result := FSenha;

end;

function TLoginModel.GetUsuario: string;

begin

 Result := FUsuario;
end;

procedure TLoginModel.SetSenha(const Value: string);

begin

  FSenha := Value;

end;

procedure TLoginModel.SetUsuario(const Value: string);

begin

  FUsuario := Value;

end;

end.

Volte ao formulário da aplicação e altere a propriedade Name para frmLogin.

Utilizando a Tool Palette, adicione os seguintes controles:

 3 Labels;
 2 Edits;
 2 Buttons.

Altere a propriedade Name dos controle para:

 3 Labels (lblTitulo, lblUsuario, lblSenha);


 2 Edits (edtUsuario, edtSenha);
 2 Buttons (btnLogar, btnSair);

Organize o formulário e altere a propriedade Caption dos controle conforme a imagem


abaixo:
Figura 1: Formulário frmLogin

Utilizando o menu New, adicione um Data Module ao seu projeto.

Adicione um controle do tipo SQLConnection da paleta DbExpress, que será usado


para criar uma conexão com o Banco de Dados.

Configure o controle SQLConnection de acordo de o caminho do seu banco.

Defina a propriedade LoginPrompt como False para que a senha do banco não seja


solicitada novamente a cada nova conexão.

Altere a propriedade Name do Data Module para dm_dados e a propriedade Name


SQLConnection para LOGINOO.

Salve o projeto e as units no diretório criado no início do artigo, seguindo a


nomenclatura:

 Formulário Login - uFrmLogin;


 Unit Login Model - uLoginModel;
 Data Module - uDm_Dados;
 Nome do Projeto – LOGINOO;

Inclua uma nova Unit no Menu New -> Unit –Delphi.

Salve a nova Unit criada como uLoginDAO.


A classe TLoginDAO será usada para centralizar as regras de negócio e o acesso ao
banco de dados.

Para nossa classe TLoginDAO, utilizaremos métodos do framework DbExpress 4, que é


a engine de acesso e manipulação de dados mais utilizada pelos programadores Delphi.

A nova arquitetura do DbExpress 4 traz novas features que permitem um


desenvolvimento totalmente orientado a objetos, de maneira simples e elegante.

Digite as informações da classe TLoginDAO, e não esqueça de dar uses nas Units
uLoginModel, DBXCommon, SysUtils.

Listagem 3: Classe TLoginDAO

unit uLoginDAO;

interface

uses uLoginModel, DBXCommon, SysUtils;

  type

   TLoginDAO = class

   public

     // função Logar passando um objeto LoginModel como parâmetro

     function Logar(LoginModel: TLoginModel): Boolean;

   end;

implementation

uses

  Dialogs;

{ TLoginDAO }
function TLoginDAO.Logar(LoginModel: TLoginModel): Boolean;

 var

  dbcon     : TDBXConnection; // objeto para conexao

  sql       : TDBXCommand;  // objeto para executar instruçoes SQL

  parametro : TDBXParameter; // objeto para parametrizar instruçao SQL

  reader    : TDBXReader; // objeto que guarda o resultado de um


TDBXCommand;

begin

 try

  try

    // fabrica uma conexão com o banco

    dbcon:=TDBXConnectionFactory.GetConnectionFactory.GetConnection('L
OGINOO',

           'sysdba','masterkey');

    // cria um comando sql no objeto dbcon

    sql := dbcon.CreateCommand;

    // instrução SQL

   sql.Text := 'SELECT * FROM USUARIOS WHERE UPPER(USUARIO) = UPPER(?)


' +

                  ' AND UPPER(SENHA) = UPPER(?)';

    // parametro Usuario

    parametro := sql.CreateParameter;

    parametro.DataType := TDBXDataTypes.WideStringType;

    parametro.Name := 'pUsuario';

    sql.Parameters.AddParameter(parametro);

    sql.Parameters.Parameter[0].Value.SetWideString(LoginModel.Usuario
);

    // parametro Senha


    parametro := sql.CreateParameter;

    parametro.DataType := TDBXDataTypes.WideStringType;

    parametro.Name := 'pSenha';

    sql.Parameters.AddParameter(parametro);

    sql.Parameters.Parameter[1].Value.SetWideString(LoginModel.Senha);

    sql.Prepare; // prepara a instrução SQL para executar no Banco

    reader := sql.ExecuteQuery; // executa o SQL e guarda o resultado


no reader;

    while (reader.Next) do // retorna True se o reader não estiver


vazio

      Result := True;

  except on E : Exception do

    ShowMessage('Não foi possível logar no sistema' + #13 +


E.Message);

  end;

 finally

  // libera os objetos da memória

  FreeAndNil(dbcon);

  FreeAndNil(sql);

  FreeAndNil(reader);

 end;

end;

end.

Passaremos agora à codificação do formulário de nossa aplicação. Adicione o seguinte


código ao evento OnClick do botão btnLogar:

Listagem 4: Evento OnClick do Botão btnLogar

procedure TfrmLogin.btnLogarClick(Sender: TObject);


var

  LoginModel: TLoginModel;

  LoginDAO: TLoginDAO;

begin

LoginModel := TLoginModel.Create; // cria o objeto LoginModel na


Memória

LoginDAO := TLoginDAO.Create; // cria o objeto LoginDAO na Memória

// verifica se há algum edit em branco

 if (edtUsuario.Text = '') or (edtSenha.Text = '') then

  raise Exception.Create('Digite usuário e senha')

 else

  begin

    try

      LoginModel.Usuario := edtUsuario.Text;

      LoginModel.Senha := edtSenha.Text;

        if LoginDAO.Logar(LoginModel) then

         begin

          ShowMessage('Acesso Autorizado');

         end

        else

          ShowMessage('Acesso não liberado');

    finally

     // libera os objetos da memória

      FreeAndNil(LoginModel);

      FreeAndNil(LoginDAO);

    end;

  end;

end;

No evento OnClick do botão btnSair, digite o seguinte o seguinte comando:


Listagem 5: Evento OnClick do Botão btnSair

procedure TfrmLogin.btnSairClick(Sender: TObject);

begin

 Application.Terminate; // encerra a aplicação;

end;
POO na prática com Delphi - SimpleMasterDetail

Olá pessoal, neste artigo mostrarei de forma prática e direta como é fácil utilizar POO
no Delphi, criaremos uma classe para conexão e uma classe de clientes para realizar as
operações de Select, Insert, Update e Delete no banco. A POO (Programação Orientada
a Objetos) facilita e muito a manutenção e o reaproveitamento de código, sendo ainda
fácil de se entender e aplicar, vamos pôr a mão na massa?

Crie um banco de dados com uma tabela chamada Clientes:

// Observe que o campo id é auto incremento

  CREATE TABLE Clientes( id int IDENTITY(1,1) NOT NULL,

  Nome varchar(50),

  Endereco varchar(50),

  Telefones varchar(50),

  Obs varchar(200) )

Tabela construída vamos agora para a construção de nossa classe de conexão, (File >
New > Unit). Nesta eu utilizei ADO, observe abaixo a unit uConn:

unit uConn; interface

  uses ADODB;

  type

     TConn = class    public

     Conn : TADOConnection;    constructor Create;    end;


implementation { TConn }

  constructor TConn.Create;

  begin

  Conn := TADOConnection.Create(nil);

  Conn.LoginPrompt := false;

  Conn.ConnectionString := 'Provider=SQLOLEDB.1'+

                           ';Password=XXXXX'+

                           ';Persist Security Info=False'+

                           ';User ID=XXXXX'+
                           ';Initial Catalog=Clientes'+

                           ';Data Source=QD_08';

  Conn.Connected := true; end; end.

Observe que na classe TConn o create é o único método disponível, e no mesmo a


conexão já é realizada, claro, você pode e deve implementar outros métodos nesta classe
como capturar a string de conexão de um arquivo ini ou xml, mas como a intenção aqui
e mostrar os primeiros passos POO no Delphi fiz de forma reduzida.

Agora vamos a classe de Clientes (File > New > Unit), observe abaixo a unit uClientes:

unit uClientes; interface uses ADODB, DB, SysUtils, uConn; type

  TClientes = class   private     FObs: string;

      FNome: string;

      FChave: integer;

      FEndereco: string;

      FTelefone: string;

      FQry: TADOQuery;

      FDs: TDataSource;

      Conexao : TConn;

      FDsPesquisa: tDataSource;     FQryPesquisa: TADOQuery;

      procedure SetChave(const Value: integer);

      procedure SetEndereco(const Value: string);

      procedure SetNome(const Value: string);

      procedure SetObs(const Value: string);

      procedure SetTelefone(const Value: string);

      procedure SetDs(const Value: TDataSource);7

      procedure SetQry(const Value: TADOQuery);

      procedure SetDsPesquisa(const Value: tDataSource);

      procedure SetQryPesquisa(const Value: TADOQuery);

      published   public

        constructor Create(Conn: TConn); // utiliza a classe de conexão


     // Propriedades

     property Chave : integer read FChave write SetChave;

     property Nome : string read FNome write SetNome;

     property Endereco : string read FEndereco write SetEndereco;

     property Telefone : string read FTelefone write SetTelefone;

     property Obs : string read FObs write SetObs;

     // Componentes

     property Qry : TADOQuery read FQry write SetQry;

     property QryPesquisa : TADOQuery read FQryPesquisa write


SetQryPesquisa;

     property Ds : TDataSource read FDs write SetDs;

     property DsPesquisa : tDataSource read FDsPesquisa write


SetDsPesquisa;

     // Métodos

     function Selecionar(Chave: Integer; Nome,Ordem: String):Boolean;

     function Inserir : boolean;    function Alterar : boolean;

     function Deletar(chave: integer) : boolean;

  end; implementation { TClientes }

  function TClientes.Alterar: boolean; begin with Qry do    begin    Close;

     SQL.Text :=    ' Update Clientes Set '+

                    ' Nome = :Nome,'+

                    ' Endereco = :Endereco,'+

                    ' Telefones = :Telefones,'+

                    ' Obs = :Obs'+

                    ' Where '+

                    ' id = :id';

     // Observe a utilização dos Fileds (FChave,Fnome...etc...)

     Parameters.ParamByName('id').Value           := FChave;

     Parameters.ParamByName('Nome').Value         := Fnome;
     Parameters.ParamByName('Endereco').Value     := Fendereco;

     Parameters.ParamByName('Telefones').Value    := FTelefone;

     Parameters.ParamByName('Obs').Value          := FObs;    try

        ExecSQL;       Result := true;

        except       Result := False;

       end;

    end;

   end;

  constructor TClientes.Create(Conn: TConn); begin

  { No create é passada a conection das Qrys }

  Conexao         := Conn;

  Qry             := TADOQuery.Create(nil);

  Ds              := TDataSource.Create(nil);

  QryPesquisa     := TADOQuery.Create(nil);

  DsPesquisa      := TDataSource.Create(nil);

  Qry.Connection         := Conexao.Conn;

  QryPesquisa.Connection := Conexao.Conn;

  Ds.DataSet         := Qry; DsPesquisa.DataSet := QryPesquisa; end;

  function TClientes.Deletar(Chave: integer): boolean;

   begin with Qry do    begin    Close;

     SQL.Text  := ' delete from Clientes'+

                  ' where id = :Chave';

     Parameters.ParamByName('Chave').Value := Chave;

     try

        ExecSQL;       Result := True;

     except       Result := False;

     end;

    end;

  end;
  function TClientes.Inserir: boolean; begin with Qry  do

   begin

    Close;

     Sql.text := ' Insert into Clientes'+

                 ' (Nome, Endereco, Telefones, Obs)'+

                 ' Values '+

                 ' (:Nome, :Endereco, :Telefones, :Obs)';

     // Observe a utilização dos Fileds (FChave,Fnome...etc...)

     Parameters.ParamByName('Nome').Value           := Fnome;

     Parameters.ParamByName('Endereco').Value       := Fendereco;

     Parameters.ParamByName('Telefones').Value      := FTelefone;

     Parameters.ParamByName('Obs').Value            := FObs;

     try

        ExecSQL;       result := true;

     except

        result := false;

     end;

    end;

  end;

  function TClientes.Selecionar(Chave: Integer; Nome,Ordem: String):


Boolean;

  begin

  Nome := '%'+Nome+'%';

  with QryPesquisa do

  begin

   Close;

     Sql.Text := ' Select * from Clientes where 1=1 ';

     if Chave > 0 then       begin

        Sql.add(' and id = :Chave');

        Parameters.ParamByName('Chave').Value := Chave;
     end;

     if Nome <> '' then

        sql.add(' and Nome like '+quotedstr(Nome));

     if Ordem <> '' then       sql.add(' Order by '+Ordem);

      try

        Open;

        if not eof then          Result := true

          else

           Result := false;

     except

           Result := false;

     end;

    end;

  end;

  procedure TClientes.SetChave(const Value: integer);

  begin

   FChave := Value; end;

  procedure TClientes.SetDs(const Value: TDataSource); begin  FDs :=


Value; end;

  procedure TClientes.SetDsPesquisa(const Value: tDataSource);

  begin

   FDsPesquisa := Value; end;

  procedure TClientes.SetEndereco(const Value: string);

  begin

   FEndereco := Value; end;

  procedure TClientes.SetNome(const Value: string);

  begin

   FNome := Value; end;

  procedure TClientes.SetObs(const Value: string);

  begin
   FObs := Value; end;

  procedure TClientes.SetQry(const Value: TADOQuery);

  begin

   FQry := Value; end;

  procedure TClientes.SetQryPesquisa(const Value: TADOQuery);

  begin

   FQryPesquisa := Value; end;

  procedure TClientes.SetTelefone(const Value: string); begin

   FTelefone := Value; end; end.

Observem que esta classe é simples e só contém métodos com SQL, estes métodos são
usados na nossa tela. Na Figura 1 segue uma sugestão de layout para a tela.

Figura 1.
Sugestão de layout

Observe abaixo o código do formulário, note que no create do mesmo instanciei nossas
classes e já realizei um select para carregar o grid. Código da unit ufrmPrincipal:

unit ufrmPrincipal; interface

 uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

   Forms, Dialogs, uConn, StdCtrls, Buttons, Grids, DBGrids, ExtCtrls,

   DBCtrls, ComCtrls, uClientes;


 type

   TfrmPrincipal = class(TForm)

     PageControl1: TPageControl;

     TabSheet1: TTabSheet;

     TabSheet2: TTabSheet;

     TabSheet3: TTabSheet;

     TabSheet4: TTabSheet;

     Label1: TLabel;

     DBNavigator1: TDBNavigator;

     DBGrid1: TDBGrid;

     Label2: TLabel;

     Label3: TLabel;

     Label4: TLabel;

     Label5: TLabel;

      edtNome: TEdit;

      edtEndereco: TEdit;

      edtTelefone: TEdit;

      mmoObs: TMemo;

     Label6: TLabel;

     Label7: TLabel;

     Label8: TLabel;

     Label9: TLabel;

     BitBtn1: TBitBtn;

     BitBtn2: TBitBtn;

     mmoUPObs: TMemo;

     edtUpTelefones: TEdit;

     Label10: TLabel;

     Label11: TLabel;

      edtUpEndereco: TEdit;

     Label12: TLabel;
     Label13: TLabel;

      edtUpNome: TEdit;

     Label14: TLabel;

      edtClienteDel: TEdit;

      BitBtn3: TBitBtn;

     Label15: TLabel;

     procedure BitBtn1Click(Sender: TObject);

     procedure FormCreate(Sender: TObject);

     procedure DBGrid1CellClick(Column: TColumn);

     procedure BitBtn2Click(Sender: TObject);

     procedure DBGrid1DblClick(Sender: TObject);

     procedure PageControl1Change(Sender: TObject);

     procedure BitBtn3Click(Sender: TObject);

     procedure Label15MouseLeave(Sender: TObject);

     procedure Label15MouseMove(Sender: TObject; Shift: TShiftState; X,

      Y: Integer);

     procedure Label15Click(Sender: TObject);   private

     { Private declarations }

     procedure LimpaCampos;

   public

     { Public declarations }   end;

 var

   frmPrincipal: TfrmPrincipal;

   Conn : TConn;

   Clientes : TClientes;

 implementation uses DB, ufrmSplashSobre;

 {$R *.dfm}

 procedure TfrmPrincipal.BitBtn1Click(Sender: TObject); begin


 if edtNome.text = '' then exit;

 with Clientes do   // preeencho as properties    begin

    Nome     := edtNome.text;

    Endereco := edtEndereco.text;

    Telefone := edtTelefone.text;    Obs      := mmoObs.Text;

    if Inserir then  // operação incluir

     begin

      Application.MessageBox('Registro incluido com


sucesso!','Confirmação',MB_OK);

     end

    else

      begin

       Application.MessageBox('O registro não foi


incluído!','Atenção',MB_OK);

    end;

   end;

 LimpaCampos; end;

 procedure TfrmPrincipal.BitBtn2Click(Sender: TObject); begin

 if edtUpNome.text = '' then exit;

 with Clientes do // preeencho as properties    begin

    Chave    :=
DBGrid1.DataSource.DataSet.FieldByName('id').AsInteger;

    Nome     := edtUpNome.text;

    Endereco := edtUpEndereco.text;

    Telefone := edtUpTelefones.text;

    Obs      := mmoUpObs.Text;

    if Alterar then  // operação alterar

       begin

       Application.MessageBox('Registro alterado com


sucesso!','Confirmação',MB_OK);
    end

    else

      begin

       Application.MessageBox('O registro não foi


alterado!','Atenção',MB_OK);

      end;

    end;

 LimpaCampos;   end;

 procedure TfrmPrincipal.BitBtn3Click(Sender: TObject); begin

 if edtClienteDel.text = '' then exit;

 if
clientes.Deletar(DBGrid1.DataSource.DataSet.FieldByName('id').asintege
r)then

   begin

    Application.MessageBox('Registro deletado com


sucesso!','Atenção',MB_OK);

   end else

   begin

    Application.MessageBox('O registro não foi


deletado!','Atenção',MB_OK);

   end;

 LimpaCampos; end;

 procedure TfrmPrincipal.DBGrid1CellClick(Column: TColumn); begin

 // carrega dados na tela de update e delete

 edtUpNome.text      :=
DBGrid1.DataSource.DataSet.FieldByName('Nome').asstring;

 edtUpEndereco.text  :=
DBGrid1.DataSource.DataSet.FieldByName('Endereco').asstring;

 edtUpTelefones.text :=
DBGrid1.DataSource.DataSet.FieldByName('telefones').asstring;

 mmoUPObs.Text       :=
DBGrid1.DataSource.DataSet.FieldByName('Obs').asstring;

 edtClienteDel.text  :=
DBGrid1.DataSource.DataSet.FieldByName('Nome').asstring; end;
 procedure TfrmPrincipal.DBGrid1DblClick(Sender: TObject); begin

 // duplo click no grid leva para tela de update


PageControl1.ActivePageIndex := 2; end;

 procedure TfrmPrincipal.FormCreate(Sender: TObject); begin

 Conn                   := TConn.Create; // Cria a conexão e conecta

 Clientes               := TClientes.Create(Conn); // cria o objeto


cliente

 Clientes.Selecionar(0,'','Nome'); // metodo de seleção de cliente

 DBGrid1.DataSource     := clientes.DsPesquisa;

 DBNavigator1.DataSource:= Clientes.DsPesquisa;

 //Conn.Destroy; end;

 procedure TfrmPrincipal.LimpaCampos; var

 i : integer; // limpa edits e memos begin

 for I := 1 to ComponentCount -1 do    begin

    if Components[i] is Tedit then       (Components[i] as TEdit).clear;

    if Components[i] is TMemo then       (Components[i] as TMemo).clear;

   end; end;

 procedure TfrmPrincipal.PageControl1Change(Sender: TObject); begin

 if PageControl1.ActivePageIndex = 0 then

    Clientes.Selecionar(0,'','Nome'); // refresh no grid end;

 procedure TfrmPrincipal.Label15MouseLeave(Sender: TObject); begin

 label15.Font.Style := [];  // efeito link end;

 procedure TfrmPrincipal.Label15MouseMove(Sender: TObject;

   Shift: TShiftState; X, Y: Integer); begin

 label15.Font.Style := [fsUnderline]; // efeito link end;

 procedure TfrmPrincipal.Label15Click(Sender: TObject); var

 frmSplashSobre : TfrmSplashSobre; begin try

    frmSplashSobre := TfrmSplashSobre.create(application);

    frmSplashSobre.ShowModal;

    finally
    freeandnil(frmSplashSobre);

   end;

end;

end.

Master Detail
Agora mostraremos uma relação simples “Master Detail” com POO no Delphi. Para
isso vamos construir nossa tabela de Compras, vejam o código:

CREATE TABLE Compras( id int IDENTITY(1,1) NOT NULL,

  Produto varchar(50),

  Valor varchar(50), Data varchar(50), idCliente int )

Observações: Como foi usado o SQL server 2005, o id é auto incremento. Além disso,
tudo foi definido como varchar para facilitar e agilizar a construção do exemplo. Não é
a forma correta, mas foi a mais rápida.

Tendo em mente que você viu o artigo anterior, neste vou implementar apenas a classe
de Compras (ou vendas, fique à vontade), FILE > NEW > UNIT. Observe o código da
nossa unituCompras:

unit uCompras;

interface uses ADODB, DB, SysUtils, uConn; type

TCompras = class   private

    FChave: integer;

    FChaveCliente: integer;

    FValor: string;

    FProduto: string;

    FData: string;

    FQry: TADOQuery;

    FQryPesquisa: TADOQuery;

    FDs: TDataSource;

    FDsPesquisa: tDataSource;     Conexao : TConn;


    procedure SetChave(const Value: integer);

    procedure SetChaveCliente(const Value: integer);

    procedure SetData(const Value: string);

    procedure SetDs(const Value: TDataSource);

    procedure SetDsPesquisa(const Value: tDataSource);

    procedure SetProduto(const Value: string);

    procedure SetQry(const Value: TADOQuery);

    procedure SetQryPesquisa(const Value: TADOQuery);

    procedure SetValor(const Value: string);  public

   constructor Create(Conn: TConn); // utiliza a classe de conexão

   // Propriedades

   property Chave : integer read FChave write SetChave;

   property Produto : string read FProduto write SetProduto;

   property Valor : string read FValor write SetValor;

    // ou Real

   property Data : string read FData write SetData;

   // ou TDatetime

   property ChaveCliente : integer read FChaveCliente write


SetChaveCliente;

   // Componentes

   property Qry : TADOQuery read FQry write SetQry;

   property QryPesquisa : TADOQuery read FQryPesquisa write


SetQryPesquisa;

   property Ds : TDataSource read FDs write SetDs;

   property DsPesquisa : tDataSource read FDsPesquisa write


SetDsPesquisa;

   // Métodos

   function Selecionar(Chave,ChaveCliente: Integer; Produto,Ordem:


String):Boolean;

   function Inserir : boolean;


   function Alterar : boolean;

   function Deletar(chave: integer) : boolean;

end; implementation { TCompras }

function TCompras.Alterar: boolean; begin with Qry do

   begin

    Close;

   SQL.Text :=    ' Update Compras Set '+

                  ' Produto = :Produto,'+

                  ' Valor = :Valor,'+

                  ' Data = :Data,'+

                  ' idCliente = :idCliente'+

                  ' Where '+

                  ' id = :id';

   // Observe a utilização dos Fileds (FChave,Fnome...etc...)

   Parameters.ParamByName('id').Value          := FChave;

   Parameters.ParamByName('Produto').Value     := FProduto;

   Parameters.ParamByName('Valor').Value       := FValor;

   Parameters.ParamByName('Data').Value        := FData;

   Parameters.ParamByName('idCliente').Value   := ChaveCliente;

   try

      ExecSQL;       Result := true;       except

      Result := False;       end;    end; end;

constructor TCompras.Create(Conn: TConn); begin

{ No create é passada a conection das Qrys }

Conexao         := Conn;

Qry             := TADOQuery.Create(nil);

Ds              := TDataSource.Create(nil);

QryPesquisa     := TADOQuery.Create(nil);

DsPesquisa      := TDataSource.Create(nil);
Qry.Connection         := Conexao.Conn;

QryPesquisa.Connection := Conexao.Conn;

Ds.DataSet         := Qry;

DsPesquisa.DataSet := QryPesquisa; end;

function TCompras.Deletar(chave: integer): boolean;

 begin

  with Qry do    begin    Close;

   SQL.Text  := ' delete from Compras'+

                ' where id = :Chave';

   Parameters.ParamByName('Chave').Value := Chave;

   try

      ExecSQL;       Result := True;       except

      Result := False;       end;    end; end;

function TCompras.Inserir: boolean; begin with Qry  do

   begin    Close;

   Sql.text := ' Insert into Compras'+

               ' (Produto, Valor, Data, idCliente)'+

               ' Values '+

               ' (:Produto, :Valor, :Data, :idCliente)';

   // Observe a utilização dos Fileds (FChave,Fnome...etc...)

   Parameters.ParamByName('Produto').Value     := FProduto;

   Parameters.ParamByName('Valor').Value       := FValor;

   Parameters.ParamByName('Data').Value        := FData;

   Parameters.ParamByName('idCliente').Value   := ChaveCliente;

   try

      ExecSQL;       result := true;

   except

      result := false;

   end;

 end; end;
function TCompras.Selecionar(Chave,ChaveCliente: Integer; Produto,
Ordem: String): Boolean; begin

{Observe que posso buscar por id da compra ou id do cliente} Produto :=


'%'+Produto+'%';

with QryPesquisa do    begin    Close;

   Sql.Text := ' Select * from Compras where 1=1 ';

   if Chave > 0 then       begin

      Sql.add(' and id = :Chave');

      Parameters.ParamByName('Chave').Value := Chave;

   end;

   if ChaveCliente > 0 then       begin

      Sql.add(' and idCliente = :ChaveCliente');

      Parameters.ParamByName('ChaveCliente').Value := ChaveCliente;

  end;

   if Produto <> '' then

      sql.add(' and Produto like '+quotedstr(Produto));

   if Ordem <> '' then       sql.add(' Order by '+Ordem);

    try

      Open;

      if not eof then

         Result := true       else

         Result := false;       except

         Result := false;       end;

   end; // end do begin with Qrypesquisa do end;

procedure TCompras.SetChave(const Value: integer); begin

  FChave := Value; end;

procedure TCompras.SetChaveCliente(const Value: integer); begin

  FChaveCliente := Value; end;

procedure TCompras.SetData(const Value: string);

begin
  FData := Value; end;

procedure TCompras.SetDs(const Value: TDataSource);

begin

 FDs := Value; end;

procedure TCompras.SetDsPesquisa(const Value: tDataSource); begin

  FDsPesquisa := Value; end;

procedure TCompras.SetProduto(const Value: string); begin

  FProduto := Value; end;

procedure TCompras.SetQry(const Value: TADOQuery); begin

  FQry := Value; end;

procedure TCompras.SetQryPesquisa(const Value: TADOQuery); begin

  FQryPesquisa := Value; end;

procedure TCompras.SetValor(const Value: string); begin

  FValor := Value; end;

end.

Notem que é tudo muito igual ao primeiro artigo, os métodos de SQL têm o mesmo
nome, são as operações básicas do dia a dia, com esta classe criada vamos agora para
criação da nossa tela, o frmPrincipal, onde teremos dois dbgrids um para exibir o cliente
e outro para exibir as compras feitas pelo mesmo, observe abaixo o código
da unit ufrmPrincipal:

unit ufrmPrincipal; interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,


Forms,

  Dialogs, Grids, DBGrids, StdCtrls, ExtCtrls, DBCtrls, uConn,


uClientes,

  uCompras, Menus, ufrmInsereCompra;

type

  TfrmPrincipal = class(TForm)

    DBGridMaster: TDBGrid;

    DBGridDetail: TDBGrid;
    Label1: TLabel;

    Label2: TLabel;

    DBNavMaster: TDBNavigator;

    DBNavDetail: TDBNavigator;

    Label3: TLabel;     Label4: TLabel;

    procedure FormCreate(Sender: TObject);

    procedure DBGridMasterCellClick(Column: TColumn);

    procedure DBGridMasterDblClick(Sender: TObject);

    procedure DBGridDetailDblClick(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

  end;

var

  frmPrincipal: TfrmPrincipal;

  Conn : TConn;

  Cliente : TClientes;   Compra : TCompras; implementation {$R *.dfm}

procedure TfrmPrincipal.FormCreate(Sender: TObject); begin

Conn    := TConn.Create;  // cria o obj de conexão e conecta

Cliente := TClientes.Create(Conn);

// cria o obj cliente e vicula o mesmo a conexão

Compra  := TCompras.Create(Conn);  // cria o obj compra...

Cliente.Selecionar(0,'','Nome');

DBGridMaster.DataSource := Cliente.DsPesquisa;

DBNavMaster.DataSource  := Cliente.DsPesquisa;

DBGridDetail.DataSource := Compra.DsPesquisa; DBNavDetail.DataSource 


:= Compra.DsPesquisa; end;

procedure TfrmPrincipal.DBGridDetailDblClick(Sender: TObject); begin //


deleta registro

if
Compra.Deletar(DBGridDetail.DataSource.DataSet.FieldByName('id').AsInt
eger) then    begin

   Application.MessageBox('Registro deletado com


sucesso!','Confirmação',MB_OK);    end else    begin

   Application.MessageBox('O registro não foi


deletado!','Atenção',MB_OK);    end;

// refresh no grid

Compra.Selecionar(0,DBGridMaster.DataSource.DataSet.fieldbyname('id').
AsInteger,'','Produto

');

end;

procedure TfrmPrincipal.DBGridMasterCellClick(Column: TColumn); begin

{Com um clique realiza um select na tabela de compras}

Compra.Selecionar(0,DBGridMaster.DataSource.DataSet.fieldbyname('id').
AsInteger,'','Produto

');

end;

procedure TfrmPrincipal.DBGridMasterDblClick(Sender: TObject); var

frmVende : TfrmInsereCompra; begin

// chama form de venda

try

   frmVende := TfrmInsereCompra.Create(nil);    frmVende.ShowModal;

   finally

   FreeandNil(frmVende);    end; // end try end; end.

Observem que não estamos usando ainda a separação das camadas que é altamente
recomendável, mas como este é um exemplo para introdução a POO no Delphi usamos
aqui apenas a persistência e a tela, facilitando assim o aprendizado.

Seguindo então vamos criar um form para “realizar as vendas conforme o código
da unitufrmInsereCompra:

unit ufrmInsereCompra;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,


Forms,

  Dialogs, StdCtrls, ComCtrls, ImgList, Buttons, ExtCtrls;

type

  TfrmInsereCompra = class(TForm)     Label1: TLabel;

    lblClienteSelecionado: TLabel;     BitBtn1: TBitBtn;

    RgProdutos: TRadioGroup;

    procedure FormCreate(Sender: TObject);     procedure


BitBtn1Click(Sender: TObject);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);  


private

    { Private declarations }   public

    { Public declarations }   end;

var

  frmInsereCompra: TfrmInsereCompra;

implementation uses ufrmPrincipal, uCompras;

// para ter acesso aos objetos criados la.

{$R *.dfm}

procedure TfrmInsereCompra.BitBtn1Click(Sender: TObject); begin

with Compra do // para valores as properties    begin

   Case RgProdutos.ItemIndex of   // para exemplificar o case

   0 : begin

       Produto := 'Corsa 1.0';        valor   := 'R$ 30,00';       


end;    1 : begin

       Produto := 'Sabão em pó';        valor   := 'R$ 150,00';

       end;    2 : begin

       Produto := 'Galinha Caipira';        valor   := 'R$


80,00';        end;    3 : begin

       Produto := 'Revista Playboy';        valor   := 'R$


50,00';        end;    end; // end case

   Data         := Formatdatetime('dd/mm/yyyy', date);

   ChaveCliente :=
Cliente.DsPesquisa.DataSet.fieldbyname('id').asinteger;
   if Inserir then // operação incluir

      begin

       Application.MessageBox('O registro incluído com


sucesso !','Confirmação',MB_OK);       end    else       begin

       Application.MessageBox('O registro não foi


incluído!','Atenção',MB_OK);       end;

   end; end;

procedure TfrmInsereCompra.FormClose(Sender: TObject; var Action:


TCloseAction); begin

// antes de fechar dar um refresh no grid

Compra.Selecionar(0,frmPrincipal.DBGridMaster.DataSource.DataSet.field
byname('id').AsInteg er,'','Produto'); end;

procedure TfrmInsereCompra.FormCreate(Sender: TObject);

begin

  // Observem, o cliente aqui é o mesmo usado no formPrincipal...

  lblClienteSelecionado.Caption :=
Cliente.DsPesquisa.DataSet.fieldbyname('Fantasia').asstring; end; end.

Você também pode gostar