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;

conclusão

A programação orientada a objetos e a aplicação do DAO Pattern melhoram em muito a


qualidade de nosso código.

Este é apenas um exemplo de como criar aplicações orientadas a objetos no Delphi. Teste o
código, refatore e otimize este exemplo.

Um abraço.

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