32
fevereiro 2012

The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

Embed Size (px)

Citation preview

Page 1: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012

Page 2: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012

Page 3: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 03

Desafio The Club

- Dicas Delphi

Dicas

- Cruzada

30

Delphi Delphi

DelphiDelphi

Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4

índiceCriando uma aplicação Client-Server no Delphi - Parte IV

Editorial

08Chegou fevereiro e com ele a nossa

maior festa popular. O Carnaval. Então va-mos todos aproveitar e festejar bastante! Sem se esquecer ... 04

Ler e exibir o Conteúdo de vários arquivos de texto utilizando DragDrop 05

Android - Criando uma tela de Venda

14

28

22

LegendaInicianteIntermediárioAvançado

Autor: Luciano Pimenta

Autor: Thiago C. Montebugnoli

Autor: Eduardo Massud

Autor: Antonio Spitaleri Neto 26Autor: Leonora Golin

Page 4: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201204

Bem-vindo

Delphi é marca registrada da Borland International, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Antonio Spitaleri Neto - Editor [email protected]

Chegou fevereiro e com ele chega nossa maior festa popular. O Carnaval. Então vamos todos aproveitar e festejar bastante! Sem se esquecer que depois da folia o trabalho prossegue. Então nada melhor que ler os artigos desse mês para que a volta ao batente seja bem produtiva.

Para começar temos o artigo de nosso consultor Eduardo Mas-sud mostrando como manipular arquivos no Delphi utilizando o recurso Drag and Drop.

Na sequência temos o artigo “Criando uma aplicação Client Server no Delphi parte 4” onde nosso colaborador Luciano Pimenta segue mostrando como desenvolver uma aplicação Delphi baseada na robustez da arquitetura Client – Server.

Para quem pretende se aventurar pela plataforma Android, nosso colaborador Thiago Montebugnoli traz esse mês como criar uma tela de venda nesse plataforma.

Para finalizar, sigo mostrando a vocês a ferramenta Lazarus. Esse mês trago o artigo “Conectando Firebird ao Lazarus”, onde demonstro como manipular bases de dados Firebird em Lazarus.

É isso. Bom carnaval a todos e até março !

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações e Suporte: (14) 3732-1529

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club Megazine 2009

Diretor TécnicoMarcos César Silva

DiagramaçãoEduardo Massud

CapaVitor Manuel Rodrigues

RevisãoEliziane Valentim

ColunistasAntonio Spitaleri Neto

Eduardo MassudLeonora Golin

Luciano PimentaThiago Cavalheiro Montebugnoli

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

Page 5: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 05

Delphi

A função de arrastar e soltar tem tido grande viabilidade, por ser bem mais intuitiva de que a busca com a caixa de diálogo, utili-zando um método muito mais simples e eficaz que agiliza no reconhecimento dos arquivos, interagindo e dinamizando nos modos de integração do aplicativo desenvolvido com o Sistema Operacional

Ao criarmos a unit será implementada a procedure WMDropFiles(var Msg: TWMDro-pFiles); message WM_DROPFILES; ela é a responsável por interpretar e gerenciar todo arquivo que é arrastado para a aplicação.

unit FmMain;

interface

uses Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, Menus, ExtCtrls, Grids, DBGrids, DB, DBClient, OleCtrls, SHDocVw;

type TForm1 = class(TForm) Memo1: TMemo; StatusBar1: TStatusBar; OpenDialog1: TOpenDialog; ListBox1: TListBox; DataSource1: TDataSource; WebBrowser1: TWebBrowser; procedure Open1Click(Sender:

TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure

Close1Click(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure ListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private function ArquivoSuportado(const Extensao: string):

Ler e exibir o conteúdo de vários arquivos de texto utilizando o sistema de arrastar e soltar (Drag Drop).

Page 6: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201206

Boolean; procedure

Incluir(const Arquivo: string); procedure Exibir(I: Integer); procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES; public { Public declarations

} end;

var Form1: TForm1;

implementation

Na clausula Uses da seção implementation devemos declarar as funções ShellAPI e UFileCa-tcher que serão responsáveis por reconhecer o arquivo recebido.

uses ShellAPI, UFileCatcher;

{$R *.dfm}

Será incluída também uma constante com o nome de “Extensões”, que receberá todas as extensões que poderão permitir que os arquivos possam ser interpretados ao serem selecionados

const Extensoes = '*.txt;*.log;*.html;*.htm;*.xml;';

{ TForm1 }

Para que possamos habilitar o sistema de ar-rastar e soltar devemos criar 3 procedimentos que serão de inicialização, finalização e do momento em que estes arquivos são transferidos, e outro

que servirá para consultar se o arquivo é permitido ou inválido

procedure TForm1.FormCreate(Sender: TObject);

begin DragAcceptFiles(Self.Handle, True);end;

procedure TForm1.

FormDestroy(Sender: TObject);

begin DragAcceptFiles(Self.Handle, False);end;

procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);var I: Integer; Catcher: TFileCatcher;begin inherited; Catcher := TFileCatcher.Create(Msg.Drop); try for I := 0 to Pred(Catcher.FileCount) do Incluir(Catcher.Files[I]); finally Catcher.Free; end; Msg.Result := 0;end;

procedure TForm1.Incluir(const Arquivo: string);

begin if ArquivoSuportado(Arquivo) then

Exibir(ListBox1.Items.Add(Arquivo)) else ShowMessageFmt('Tipo de Arquivo não suportado', [Arquivo]);end;

Ao fecharmos o executável, removemos todos os arquivos listados e abertos pelo ListBox, limpando-o

procedure TForm1.Close1Click(Sender: TObject);var ItemIdx: Integer;begin ItemIdx := ListBox1.ItemIndex; if ItemIdx > -1 then begin ListBox1.Items.Delete(ItemIdx); if ItemIdx >= ListBox1.Items.Count then Dec(ItemIdx); Exibir(ItemIdx); end;end;

Na procedure “Exibir” carregamos todos os arquivos para os componentes que irão permitir que sejam visualizados

procedure TForm1.Exibir(I: Integer);varFileName: string;begin if I >= 0 then begin FileName := ListBox1.Items[I]; ListBox1.ItemIndex := I; Memo1.Lines.

Page 7: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 07

LoadFromFile(FileName); WebBrowser1.Navigate(FileName); StatusBar1.SimpleText := FileName; end else begin Memo1.Clear; StatusBar1.SimpleText := 'Nenhum arquivo selecionado!'; end;end;

function TForm1.ArquivoSuportado(const Extensao: string): Boolean;begin Result := Pos('*' + ExtractFileExt(Extensao) + ';', Extensoes) > 0;end;

Mesmo se tratando de um component Drag Drop, o Delphi executará algumas funções neces-sárias para que o arquivo seja recebido, como a listagem de registros ao selecionar o listbox e a utilização do componente OpenDialog, que irá reconhecer o caminho daquele arquivo.

procedure TForm1.ListBox1Click(Sender: TObject);begin Exibir(ListBox1.ItemIndex);end;

procedure TForm1.

Open1Click(Sender: TObject);begin if (OpenDialog1.Execute) then Incluir(OpenDialog1.FileName);

end;

procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin try if Key = VK_DELETE Then ListBox1.Items.Delete(ListBox1.

ItemIndex); Memo1.Clear; WebBrowser1.

Navigate('about:blank'); except end;end;

end.

Veja a Figura 1

Conclusão

O Sistema de arrastar e soltar sempre trouxe muito mais agilidade e simplicidade aos aplicativos por ser um método mais intuitivo ao usuário.

Figura 1 Aplicação em Execução

Consultor Técnico The Club.

Sobre o autor

Eduardo Massud

[email protected]

Page 8: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201208

Criando uma aplicação client-server no Delphi – Parte IV

Continuaremos neste artigo a criação da nossa aplicação client-server com o Delphi. Fizemos no artigo anterior uma das partes mais importante do sistema, o cadastro de orçamento. Agora, veremos outra parte importantíssima que é o cadastro de Ordem de serviço.

No sistema, à pedido do nosso cliente, uma Ordem de serviço, esta vinculada a um orçamento.

Criando a Ordem de serviço

Precisamos saber qual o orçamento vincula-remos a essa OS. Vamos pesquisar o orçamento, através da placa do veículo, uma das maneiras mais indicadas. Na tela da OS, utilizaremos novamente, a tela de pesquisa genérica.

Mostraremos a mesma, quando a pesquisa pelo orçamento retornar mais de um para a mesma placa (é possível). Assim, ao escolher o orçamento, alguns dados serão mostrados em

tela. Uma característica que precisamos ter aqui será de armazenar em memória, as peças/serviços adicionados para a OS.

Seria problemático, em termos de performan-ce, se fossemos adicionando ou removendo no banco, as peças/serviços que

farão parte da OS. Vamos colocar os dados em memória, e quando o usuário finalizar a OS, incluiremos tudo no banco de dados.

Usaremos nesse exemplo, Stored Procedure, juntamente com uma transação, para que possa-mos incluir a OS e suas peças/serviços sem termos problemas, caso algum erro ocorra.

Sobre as vantagens das Stored Procedure, podemos inumerar:

- Diminui a quantidade de tráfego na rede, pois podemos ou não usar parâmetros para a execução de todo o comando no servidor;

- Plano de execução mais otimizado, pois a mesma é “compilada” no banco de dados;

- Segurança: podemos dar acesso ao usuário do sistema para execução da Stored Procedure em vez de acesso a tabela do banco de dados;

- Facilidade: se precisarmos fazer uma mo-dificação na Stored Procedure, basta alterá-la no banco de dados que os “clientes” da aplicação já estarão aceitando/recebendo essas modificações (desde que não seja alterado os parâmetros da Stored Procedure);

- Regras de negócio: isso é uma discussão mui-to grande, deixar as regras no banco ou aplicação. A minha opinião é de que, cada caso é um caso. Dependendo, teremos vantagens em ter a regra no banco, em outro projeto, a vantagem pode estar em ter a regra do negócio na aplicação.

Criando as Stored Procedures

Veja na Listagem 1 o código das duas Stored

Page 9: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 09

Procedures que criaremos.

Listagem 1. Stored Procedures

CREATE PROCEDURE SP_ORDEM_SERVICO @nCdVeiculo int, @nCdOrcamento int, @sDsObservacoes varchar(max), @nCdOrdem int outputASBEGIN INSERT INTO OS (nCdVeiculo, nCdOrcamento, tDtOrdem, sDsObservacoes) VALUES (@nCdVeiculo, @nCdOrcamento, getdate(), @sDsObservacoes) select @nCdOrdem = @@identity from OS;END

CREATE PROCEDURE SP_ORDEM_SERVICO_DETALHES @nCdOrdem int, @nCdPeca int, @nQtPeca numeric(9,2), @nVlUnitario numeric(9,2)ASBEGIN INSERT INTO OS_DETALHE (nCdOrdem, nCdPeca, nQtPeca, nVlUnitario) VALUES (@nCdOrdem, @nCdPeca, @nQtPeca, @nVlUnitario) END

Note que na SP_ORDEM_SERVICO, temos no final um código para selecionar o valor inserido no campo chave (nCdOrdem) da tabela OS, que será retornado nos parâmetros (do tipo output) da Stored Procedure.

Assim, com o retorno desse valor, podemos indicar para a SP_ORDEM_SERVICO_DETALHES que vai inserir os itens (peças/serviços), o código da OS

que os itens estão vinculados. Tudo isso, dentro de uma transação, feita pela aplicação. Não podemos ter itens da OS inseridos, sem a vinculação do código da OS.

Criando o cadastro

Vamos criar agora, o cadastro da nossa OS. Veja na Figura 1 a tela de OS da aplicação.

No Click do botão, usamos o código da Lis-

tagem 2 para pesquisar os dados do orçamento.

Listagem 2. Pesquisa de Orçamento pela placa

DM.cdsOrcamentoPlaca.Close;DM.cdsOrcamentoPlaca.Params[0].AsString := edtPlaca.Text;DM.cdsOrcamentoPlaca.Open;if DM.cdsOrcamentoPlaca.RecordCount > 1 thenbegin try frmPesquisa := TfrmPesquisa.Create(self);

frmPesquisa.dsPesquisa.DataSet :=

DM.cdsOrcamentoPlaca; frmPesquisa.Descricao := 'Nome da peça/serviço'; frmPesquisa.ShowModal; finally frmPesquisa.Free; end; end;

if (DM.cdsOrcamentoPlaca.RecordCount > 1) or (DM.cdsOrcamentoPlaca.RecordCount = 1) thenbegin nCdOrcamento := DM.cdsOrcamentoPlacanCdOrcamento.AsInteger; nCdVeiculo := DM.cdsOrcamentonCdVeiculo.AsInteger;end;

Temos a mesma funcionalidade anterior, caso a consulta retorne mais de um registro, mostramos a tela de pesquisa genérica para que o usuário possa escolher o respectivo orçamento. Veja que no final

Figura 1. Tela de cadastro da OS.

Page 10: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201210

do código, preenchemos variáveis auxiliares com o código do orçamento e veículo para serem usadas na confirmação da OS.

O comando SQL do cdsOrcamentoPlaca que preenche os dados do orçamento:

select O.nCdOrcamento, O.nCdVeiculo, O.sNmCliente, O.sDsParecer, V.sNmModelo from ORCAMENTO O

INNER JOIN VEICULO

V ON V.nCdVeiculo = O.nCdVeiculoWHERE V.sNrPlaca = :PLACA and O.nIdStatus = 1

Um detalhe importante, veja que estamos pesquisando somente nos orçamentos ativos (nI-dStatus = 1), para que a pesquisa seja correta e não traga orçamentos que já foram usados no veículo.

Usando a pesquisa genérica não precisamos criar outra tela de consulta, ganhamos assim pro-dutividade em nossa aplicação.

Adicionando peças/serviços na OS

Precisamos adicionar em memória as peças/serviços escolhidos pelo usuário. Não seria correto, ficar adicionando e excluindo os itens no banco de dados. Seria uma degradação de performance muito grande.

Vamos adicionar um ClientDataSet no formulá-rio que terá os seguintes campos: código da peça, nome da peça, quantidade e preço. Veja na Figura 3 os campos do ClientDataSet.

Figura 3. Campos do cdsItens

Criamos um campo calculado para saber o subtotal da peça (quantidade * preço). Adicione um DataSource no formulário e faça a ligação do mesmo com o ClientDataSet e também do DBGrid com o DataSource.

Configure os campos do ClientDataSet no Grid. Veja na Figura 4 como ficou nosso formulário.

Vamos agora implementar o método respon-sável por adicionar os itens em memória no Clien-tDataSet. Veja na Listagem 3, o método IncluirItem.

Listagem 3. Incluindo o item em memória

procedure TfrmOrdem.IncluirItem;begin //validações if edtPeca.Text = '' then MessageDlg('Campo

Peça/serviço: preenchimento obrigatório.', mtError, [mbNo], 0) else if (edtQuantidade.Text = '') then MessageDlg('Campo Quantidade: preenchimento obrigatório.', mtError, [mbNo], 0) else if edtPreco.Text = '' then MessageDlg('Campo

Preço: preenchimento obrigatório.', mtError, [mbNo], 0) else begin //verifica se ClientDataSet ativo

Figura 4. Finalizando o formulário de cadastro de OS

Figura 5. Menu de contexto no grid

Page 11: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 11

if not cdsItens.Active then cdsItens.CreateDataSet;

//inclui o item cdsItens.Insert; cdsItensnCdPeca.

AsInteger := nCdPeca; cdsItenssNmPeca.AsString := edtPeca.Text; cdsItensnQtde.AsInteger := StrToInt(edtQuantidade.Text); cdsItensnVlPeca.AsCurrency := StrToCurr(edtPreco.Text); cdsItens.Post;

//limpa campos edtPeca.Text := ''; edtQuantidade.Text := ''; edtPreco.Text := ''; end;end;

Veja que fizemos algumas validações simples, antes de inserir o item. Poderíamos ter mais vali-dações, como valor e quantidade maior que zero etc. A inserção do item, é simples, primeiro veri-

ficamos se o ClientDataSet não esta ativo, assim, criamos o mesmo em memória usando o método CreateDataSet.

Para inserir um registro no controle, chama-mos o Insert, preenchemos os campos e por fim, executamos o método Post. Para excluir um item, vamos usar um menu de contexto. Adicione um PopupMenu no formulário.

Crie um item de menu chamado “Excluir”. No evento OnClick do menu, digite o seguinte código:

if cdsItens.Active then cdsItens.Delete;

Estamos verificando se o ClientDataSet esta ativo, então chamamos o Delete para excluir o item da memória. Precisamos apenas vincular o controle com a propriedade PopupMenu do grid. Veja na Figura 5 o uso do menu de contexto no Grid.

Para finalizarmos o nosso cadastro, vamos implementar algumas regras na tela para que o processo seja executado sem falhas. Vamos de-sabilitar (propriedade Enabled) o GroupBox com os dados do item para quando o usuário abrir o formulário, não possa adicionar itens, sem antes pesquisar um orçamento.

Vamos habilitar o mesmo somente quando for encontrado um orçamento. Por isso, modifiquei o

Grid para que fique dentro do GroupBox, assim o mesmo também fica desabilitado. Você também pode desabilitar o campo Observações e o botão de confirmar.

Uma melhoria bem legal que poderíamos fazer, mas deixo para você exercitar, seria o de trazer o valor da peça/serviço cadastrado no banco no campo Preço. Usaríamos apenas como sugestão, pois o usuário poderia modificar o valor. Vamos agora, confirmar nosso orçamento.

Usando transação com o dbExpress

Como estamos usando o dbExpress, usar transação de dados com o mesmo, é muito fácil. Vamos primeiramente, adicionar e configurar dois SQLStoredProc no Data Module para vinculá-los com as Stored Procedures criadas anteriormente.

Acesse a propriedade Params dos controles e veja que o mesmo já configura os parâmetros das Stored Procedures (Figura 7).

Precisamos então criar um método que faça

a inserção dos dados, usando Stored Procedure e transação. Na Listagem 4, temos o código do InserirOS criado no Data Module.

Listagem 4.Inserindo a Ordem de serviço no banco

function TDM.InserirOS(nCdOrcamento, nCdVeiculo: integer; cdsItens: TClientDataSet; sDsObservacoes: string): Boolean;var TransDesc: TDBXTransaction; nCdOrdem: integer; i: integer; bRetorno: Boolean;begin bRetorno := false;

//inicia a transação TransDesc := SysCar.Transaction(TDBXIsolations.ReadCommitted);

try //insere o orçamento

Figura 6. Cadastro de orçamento em execução

Page 12: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201212

spOS.Params[0].AsInteger := nCdVeiculo; spOS.Params[1].AsInteger := nCdOrcamento; spOS.Params[2].AsString := sDsObservacoes; spOS.ExecProc;

//armazena o valor inserido no banco nCdOrdem := spOS.Params[3].AsInteger;

//percorre os itens e insere no banco for i := 0 to cdsItens.RecordCount - 1 do begin //insere os itens spOS_Itens.Params[0].AsInteger := nCdOrdem; spOS_Itens.Params[1].AsInteger := cdsItens.FieldByName('nCdPeca').AsInteger; spOS_Itens.Params[2].AsInteger := cdsItens.FieldByName('nQtde').AsInteger; spOS_Itens.Params[3].AsCurrency := cdsItens.FieldByName('nVlPeca').AsInteger; spOS_Itens.ExecProc; end; bRetorno := true; except //caso ocorra algum

erro, da roolback SysCar.RollbackIncompleteFreeAndNil(TransDesc); end;

//comita as alterações no banco SysCar.ommitFreeAndNil(TransDesc);

Result := bRetorno;end;

O código esta comentado, mas vamos en-tender seu funcionamento. Primeiro, declaramos algumas variáveis para auxiliar-nos. A variável do tipo TDBXTransaction, é parâmetro para o método que inicia a transação.

Dentro de um bloco try...except, configuramos os parâmetros necessários para a inserção da OS e de seus itens. Algo bastante simples, como po-demos perceber.

A Stored Procedure que insere a OS, retorna o código da mesma em seu último parâmetro. Assim, armazenamos esse valor para usá-lo na inserção dos itens da OS. O bloco except, será executado, caso ocorra algum erro, assim, chamamos o Roll-backIncompleteFreeAndNil para não efetivar nada no banco de dados.

Se não ocorrer nenhum problema, o fluxo con-tinuará, sem executar o roolback e assim, executará o CommitFreeAndNil, que é a inserção dos dados, efetivamente, no banco. Veja que criamos uma function, que retorna um boolean, para sabermos se a inserção foi realizada corretamente.

Usamos uma variável, que é preenchida como false, pois se ocorrer erro, o retorno deverá ser falso. Preenchemos a variável com true, somente se o fluxo ocorreu corretamente e não gerou erro.

Caso tenha alguma dúvida sugiro uma pesquisa para entender o funcionamento de transação no dbExpress.

Nota: a partir da versão 2010 do Delphi, essa é a implementação para utilização de transação no dbExpress. Em versões anteriores, a lógica é a mesma, apenas muda as classes e métodos.

Cadastrando uma OS

Para finalizar nosso cadastro, vamos codificar o Confirmar na tela de OS, para que chame o método do Data Module, conforme a Listagem 5.

Listagem 5. Chamando a inserção da OS

if (not cdsItens.Active) or (cdsItens.RecordCount = 0) then MessageDlg('É necessário incluir peças/serviços

para confirmar a Ordem

de serviço.', mtError, [mbNo], 0)elsebegin if DM.InserirOS(nCdOrcamento, nCdVeiculo, cdsItens, mmObservacoes.Text) then begin MessageDlg('Registro inserido com sucesso.', mtInformation, [mbNo], 0); dsOrcamento.DataSet.Close; cdsItens.Close; end else MessageDlg('Ocorreu um erro. Contate o suporte', mtError, [mbNo], 0)end;

Veja que validamos se o ClientDataSet esta ativo ou se existem itens cadastrados. Em caso negativo, emitimos uma mensagem, senão, cha-mamos a função para inserir. Assim, verificamos se a mesma retornou com sucesso, para emitir a devida mensagem.

Figura 7. Parâmetros das Stored Procedures configurados no componente

Page 13: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 13

Poderíamos emitir a mensagem retornada para o usuário. Fica a seu critério implementar isso. Execute o projeto e faça um teste (Figura 8).

Poderíamos incrementar nosso cadastro, validando os campos Quantidade e Preço. Caso você deseje alterar a ordem de serviço, teríamos que rever a parte do carregamento de itens, onde apenas precisaríamos preencher o cdsItens com as peças/serviços cadastrado no banco.

Teríamos que ter também, obviamente, uma pesquisa para que o usuário possa escolher a or-dem de serviço que deseja alterar.

Para finalizar completamente, após confir-mar, precisamos mudar o status do orçamento vinculado a OS. Caso você deseje implementar a funcionalidade de editar os itens da OS, você deve atentar para mudar a lógica referente a status do Orçamento e da OS.

Listagem 6. Alterando o status do OrçamentoData module

procedure TDM.AlterarStatusOrcamento(nCdOrcamento: integer);var sql: string; Query: TSQLQuery;begin sql := 'update ORCAMENTO set nIdStatus = 0 where nCdOrcamento = ' + IntToStr(nCdOrcamento);

Query := TSQLQuery.Create(nil);

try Query.SQLConnection := SysCar; Query.SQL.Clear; Query.SQL.Add(sql); Query.ExecSQL(); finally Query.Free; end;end;

Formulário da OS

...

MessageDlg('Registro inserido com sucesso.', mtInformation, [mbNo], 0);

DM.AlterarStatusOrcamento(nCdOrcamento);...

Conclusões

Finalizamos neste artigo a nossa aplicação no

Figura 8. Salvando uma ordem de serviço

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

que se refere a cadastros, pois já implementamos

os principais. Criamos os cadastros que podemos chamar de auxiliares (cliente, peças e veículos), pois eles “abastecem” os cadastros prin-cipais, bem como os cadastros que são os principais (orçamento e ordem de serviço) do nosso projeto.

No próximo e último artigo, vamos finalizar o projeto com a parte de relatórios, onde criaremos listagens, relatórios com parâmetros etc.

Um grande abraço a todos e até a próxima!

Page 14: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201214

Android Criando uma tela de Venda

Neste artigo montaremos uma tela simples de venda de produtos, no nosso caso utilizaremos como exemplo o The Club. A intenção desta matéria é de trabalhar com alguns componentes, mostrando suas fun-cionalidades na prática e algumas classes úteis ao decorrer do desenvol-vimento deste artigo.

Eu considero este tipo de assunto um passo importante para quem está começando a trabalhar com o Sistema Android, para quem não sabe, programação em Android nada mais é que uma mistura do XML com o Java.

Portanto, especificamente neste artigo trabalharemos com o XML e programaremos alguma coisa em Java, a fim de possibilitar um apren-dizado fácil e intuitivo.

Conceitos Básicos e Essenciais

Para isto abra seu Eclipse e clique em “File/New/Android Project” e crie um projeto em Android, recomendo a criação na versão 2.2 ou 2.3.

A primeira tela que vemos quando estamos criando um projeto em Android é a clássica telinha “Hello World”, que todo mundo já está careca de saber e montar como primeiro projeto de exemplo. Mas explicarei alguns detalhes interessantes em relação da mesma, para isto clique em seu código XML e teremos um idêntico com este abaixo:

<?xml version=”1.0” encoding=”utf-8”?><LinearLayout xmlns:android=”http://

Page 15: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 15

schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent” ><TextView android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”@string/hello” /></LinearLayout>

Figura 01: Recursos no Sistema Android.

Pergunta: O que seria a palavra “@string” na linha android:text=”@string/hello” ?

Resposta: É uma referência que temos no nosso arquivo de recursos “strings.xml” encontrado no caminho /res/values. Para entendermos melhor dê um clique no mesmo e verá uma tela parecida com a Figura 01.

Temos aqui uma tela de recursos para o Sistema Android, ou seja, podemos mudar nosso valor da variável “hello” ou da “app_name” que seria o título de nosso exemplo.

Em “Resources Elements” temos vários elementos que podemos trabalhar e explorar nos possibilitando a criação e manipulação de variáveis muito úteis ao decorrer de nossa necessidade. Neste mesmo artigo criaremos uma do tipo Array que iremos aprender um pouco mais adiante.

É importante também ter em mente que podemos realizar este trabalho por XML, veja o código equivalente a Figura 01.

<?xml version=”1.0” encoding=”utf-8”?><resources>

<string name=”hello”>Hello World!</string> <string name=”app_name”>Vendas The

Club</string></resources>

Figura 02: Hierarquia de Componentes Utilizados.

Bem, como este não é nosso primeiro projeto, esta variável “hello” não será utiliza-

da, portanto podemos excluí-la tanto de nossa tela de recursos quanto na tela principal.

Criando uma interface gráfica

Para construirmos nossa tela, é obrigatório saber que o primeiro componente que

devemos inserir na tela são os denominados “Layouts”, os quais definem a orientação

da inserção dos componentes na tela. Ele pode ser encontrado na paleta com o mesmo

nome. Os mais utilizados são:

LinearLayout(Vertical): Possibilita a disposição vertical dos componentes da tela.

Exemplo:

<LinearLayout android:orientation=”vertical”> <LinearLayout>

LinearLayout(Horizontal): Possibilita a disposição horizontal dos componentes

da tela.

Exemplo:

<LinearLayout android:orientation=”horizontal”> <LinearLayout>

Page 16: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201216

A tela de venda possuirá a seguinte estrutura:

• Nome Cliente

• Cidade

• Estado

• Produtos

o The Club Lite (Delphi)

o The Club Lite (C#,.NET)

o The Club Professional

o The Club Student

• Botão “Efetuar Compra”

Para obtermos um resultado legal trabalharemos corretamente com os componentes de Layouts acima descritos. Por padrão nosso projeto é criado com um LinearLayout(Vertical).

A descrição dos componentes utilizados e a disposição em nossa tela principal. Veja a Figura 02 para melhores detalhes.

É importante entender o funcionamento destes dois principais tipos de

componentes de layouts, pois é possível manejá-los da forma que desejar, colocando um dentro do outro, entre outros tipos de configurações.

Podemos conferir o código XML correspondente abaixo:

<?xml version=”1.0” encoding=”utf-8”?><LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”fill_parent”> <LinearLayout android:layout_height=”wrap_content” android:orientation=”vertical” android:layout_width=”wrap_content” android:id=”@+id/linearLayout2”> <TextView android:layout_width=”wrap_content” android:text=”Nome Cliente:” android:id=”@+id/textView1” android:layout_height=”wrap_content”></TextView> <EditText android:layout_width=”316dp” android:id=”@+id/edtCliente” android:layout_height=”wrap_

content”></EditText> </LinearLayout> <LinearLayout android:layout_height=”wrap_content”

android:layout_width=”match_parent” android:id=”@+id/linearLayout1” android:orientation=”horizontal”> <LinearLayout android:layout_height=”match_parent” android:orientation=”vertical” android:layout_width=”wrap_content” android:id=”@+id/linearLayout4”> <TextView android:layout_width=”wrap_content” android:id=”@+id/textView3” android:layout_height=”wrap_content” android:text=”Cidade”></TextView> <EditText android:id=”@+id/edtCidade” android:layout_height=”wrap_content” android:layout_width=”206dp”></EditText> </LinearLayout> <LinearLayout android:layout_height=”match_parent” android:orientation=”vertical” android:id=”@+id/linearLayout3” android:layout_width=”match_parent”> <TextView android:layout_width=”wrap_content” android:id=”@+id/textView2” android:layout_height=”wrap_content” android:text=”Estado”></TextView> <Spinner android:id=”@+id/spnEstado” android:entries=”@array/uf” android:layout_height=”wrap_content” android:layout_width=”match_parent”></Spinner> </LinearLayout> </LinearLayout> <TextView android:textAppearance=”?android:attr/textAppearanceMedium” android:id=”@+id/textView4” android:layout_height=”wrap_content” android:text=”PRODUTOS” android:layout_width=”wrap_content”

Page 17: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 17

android:layout_gravity=”center”></TextView> <RadioGroup android:id=”@+id/rgCursos” xmlns:android=”http://schemas.android.com/apk/res/android” android:orientation=”vertical” android:layout_width=”fill_parent” android:layout_height=”wrap_content”> <RadioButton android:id=”@+id/rbLiteDelphi” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”The Club Lite (Delphi) - R$ 59,90”></RadioButton> <RadioButton android:id=”@+id/rbLiteC” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”The Club Lite (C#,.NET) - R$ 59,90”></RadioButton> <RadioButton android:id=”@+id/rbProfessional” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”The Club Professional - R$ 88,00”></RadioButton> <RadioButton android:id=”@+id/rbStudent” android:layout_width=”wrap_content” android:layout_height=”wrap_content” android:text=”The Club Student - R$ 25,00”></RadioButton> </RadioGroup> <Button android:id=”@+id/btnEfetuar” android:layout_height=”wrap_content” android:layout_width=”match_parent” android:text=”Efetuar Venda”></Button></LinearLayout>

Devemos dar uma atenção especial no componente RadioButton em conjunto com o RadioGroup, ele nos possibilita a criação de um grupo que permite apenas selecionar um tipo de Produto, que no nosso caso específico é o que devemos fazer.

O componente Spinner é parecido com o Combobox do Delphi, ou seja, podemos armazenar uma lista de Strings nele. Neste caso armazenaremos via XML todos os estados do Brasil, para isto acesse o caminho \values\strings.xml e adicionaremos uma variável do tipo Array. Podemos fazer isto via código XML ou utilizando a interface gráfica. Veja abaixo o XML correspondente:

<string-array name=”uf”> <item >AC </item> <item >AL </item> <item >AM </item> <item >BA </item> <item >CE </item> <item >ES </item> <item >GO </item> <item >MA </item> <item >MT </item> <item >MS </item> <item >MG </item> <item >PA </item> <item >PB </item> <item >PR </item> <item >PE </item> <item >PI </item> <item >RJ </item> <item >RN </item> <item >RS </item> <item >RO </item> <item >RR </item> <item >SC </item> <item >SP </item> <item >SE </item> <item >TO </item> </string-array>

Prontinho... Criamos agora mais um recurso no Android que poderá ser utilizado

em qualquer tela que precisarmos, não é legal?

Para carregarmos estes recursos utilizamos a função “entries”, veja abaixo o XML

completo deste componente.

Podemos rodar o exemplo e teremos uma tela parecida com a da Figura 03

<Spinnerandroid:id=”@+id/spnEstado”android:entries=”@array/uf” android:layout_height=”wrap_content” android:layout_width=”match_parent”></Spinner>

Page 18: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201218

Figura 03: Tela de Vendas.

Figura 04: Criando uma classe Registro.

Criando uma classe para armazenar os registros

Para guardar nossos dados em memória deveremos criar uma classe para esta

finalidade e consequentemente aprenderemos como criar uma classe no Java. Para isto

clique com o botão direito no pacote “Pct.Tela_Venda_Artigo” localizado no diretório /

src e escolha new/Class e deixe e escolha o Nome Registro. Ver Figura 04.

Adicionaremos algumas variáveis para armazenar o registro, sendo três do tipo

string “cliente”, “cidade” e “estado” e uma do tipo inteiro para o curso escolhido, sendo:

1 - The Club Lite (Delphi)

2 - The Club Lite (C#,.NET)

3 - The Club Professional

4 - The Club Student

Código correspondente:

package Pct.Tela_Venda_Artigo;

public class Registro

{ String cliente, cidade, estado; int curso;}Codificando o Botão “Efetuar Compra”O primeiro passo é abrir o arquivo principal .java, localizado em /src/Pct.Tela_Venda_Artigo. Importaremos a classe Widget para criarmos nossas variáveis.Import android.widget;O código comentado ficou da seguinte maneira:

public class Tela_Venda_ArtigoActivity extends Activity { //Variáveis que serão úteis no exemplo RadioGroup rgCursos; RadioButton rbLiteDelphi, rbLiteC, rbProfessional, rbStudent; TextView txtCliente, txtCidade, txtEstado; Spinner spEstado; Button btEfetuar;

Page 19: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 19

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Fazendo o denominado “casting” dos componentes utilizados rgCursos = (RadioGroup) findViewById(R.id.rgCursos); rbLiteDelphi = (RadioButton) findViewById(R.id.rbLiteDelphi); rbLiteC = (RadioButton) findViewById(R.id.rbLiteC); rbProfessional = (RadioButton)findViewById(R.id.rbProfessional); rbStudent = (RadioButton) findViewById(R.id.rbStudent); txtCliente = (TextView) findViewById(R.id.edtCliente); txtCidade = (TextView) findViewById(R.id.edtCidade); spEstado = (Spinner) findViewById(R.id.spnEstado); btEfetuar = (Button)

findViewById(R.id.btnEfetuar); //Acionar o evento setOnClickListener para o botão Efetuar btEfetuar.setOnClickListener(new

View.OnClickListener() { @Override public void onClick(View arg0) {//Instanciar a classe Registro para atribuir os dados digitados pelo usuário Registro reg = new Registro(); reg.cliente = txtCliente.getText().toString(); reg.cidade = txtCidade.getText().toString(); reg.estado = spEstado.

getSelectedItem().toString(); //Utilizar o Id do RadioGroup para

identificar o tipo de curso switch (rgCursos.getCheckedRadioButtonId()) { case R.id.rbLiteDelphi : reg.curso = 1; break; case R.id.rbLiteC : reg.curso = 2; break; case R.id.rbProfessional : reg.curso = 3; break; case R.id.rbStudent : reg.curso = 4; break; } //Utilização da Classe Builder para emitirmos um Alerta ao usuárioMensagemAlerta(“Resultado”, “Venda Efetuada com sucesso!” + “\n” + “-----------------------

---------------” + “Cliente: “ + reg.

cliente + “\n”+ “Cidade: “ + reg.cidade + “ / Estado: “ + reg.estado + “\n” + “Cód. Curso: “ + reg.curso); } }); }

//Implementação de uma função genérica para utilizar no nosso projetopublic void MensagemAlerta(String titulo, String corpo)

{

AlertDialog.Builder infoResultado = new AlertDialog.Builder(Tela_Venda_

ArtigoActivity.this); infoResultado.setTitle(titulo); infoResultado.setMessage(corpo); infoResultado.setNeutralButton(“Ok”,null); infoResultado.show(); }

Page 20: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201220

Conclusão

Este artigo nos demonstrou várias ideias e conceitos em relação ao Sistema Android. Como sabemos que é uma mistura de XML com o Java, primeiramente exploramos os denominados “resources” com exemplos e utilizações práticas do mes-mo. Procurei trabalhar com componentes diversificados a fim de proporcionar um melhor aprendizado.

Trabalhei em cima do evento “setOnClickListener” para finalmente explorar um pouco da classe “Builder” que é muito utilizada. Como se trata de um exemplo prático foi criado uma classe para armazenar os registros e futuramente consultá-los ou até mesmo gravar em uma base de dados.

Espero que vocês estejam gostando desta série de Artigos de Android, vou ficando por aqui, um forte abraço e até o mês que vem!

Thiago Cavalheiro Montebugnoli é tecnólogo, formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC) foi consultor técnico do The Club, já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Proces-samento de Dados da Prefeitura Municipal de Itaí-SP. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certi-fied Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

Sobre o autor

Thiago Cavalheiro Montebugnoli

[email protected]

Page 21: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 21

Page 22: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201222

Em artigo anterior, apresentei a vocês a ferramenta Lazarus. Relembrando, Lazarus é um projeto independente OpenSource, desenvolvido em Linux, possui sua IDE ba-seada no Delphi e utiliza como compilador o FreePascal, que é um compilador já com tradição no mundo OpenSource. Nesse artigo anterior mostrei a ferramenta Lazarus não como um substituto, mas sim como uma alternativa ou até mesmo um complemento ao uso do Delphi.

Lazarus vem apostando bastante no conceito da multiplataforma, possibilitando hoje a geração de executáveis para ambientes 32 e 64 bits, Win-dows e Linux, além de gerar programas para Mac OS e também já existem testes para a geração de aplicativos para plataformas móveis como Android.

Hoje o principal projeto que existe em Lazarus é o projeto ACBr, que é uma suíte de componentes para automação comercial. O projeto ACBr hoje é desenvolvido em parte em Lazarus e com isso vem chamando atenção da comunidade Delphi para a

ferramenta.

Para quem tem pensado em começar a utilizar Lazarus, nesse artigo estarei mostrando mais uma faceta da ferramenta, a importantíssima conexão a banco de dados. Lazarus hoje possui conexões nativas para os principais bancos gratuitos exis-tentes: PostgreeSql, MySql, Sqlite e Firebird, além de possuir conexões para Oracle e ODBC, com a conexão ODBC disponível, podemos, em ambiente Windows utilizar o Lazarus com Sql Server, um dos bancos de dados mais robustos do mercado.

As opções como vimos são variadas, e nesse artigo estarei mostrando a conexão do Lazarus com o banco de dados Open Source mais utilizado pela comunidade Delphi: Firebird. Mãos a obra então!

Conhecendo os componentes de conexão

Nesse artigo não estarei abordando a instala-ção do Lazarus já que no artigo anterior já mostrei como procedemos para realizar o Download e instalar o mesmo.

Com o Lazarus devidamente instalado, abra-o. A primeira característica que verificamos é que, comparado com o Delphi, Lazarus possui bem menos abas de componentes.

Para nossa tarefa, a aba mais importante é a SqlDB. É nela que se encontram os componentes que realizam a conexão com as diversas bases de dados que são suportadas pelo Lazarus. A aba SqlDB pode ser vista na figura 1:

Os oito últimos componentes dessa aba são os conectores, que realizam a conexão Lazarus – Bancos de dados. Pela ordem temos as seguintes opções de conexão:

PostgreeSQL; Oracle; ODBC; Os três seguintes são para diversas

versões do MySQL; SQLite; Interbase/Firebird

Os quatro componentes que iniciam a aba são os componentes de consulta, onde estaremos

Conexão ao Firebird em Lazarus

Page 23: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 23

retirando e passando informações para a base de dados.

No artigo, estaremos utilizando o último com-ponente, para Interbase/Firebird.

Também estaremos utilizando dessa aba os componentes de consulta, no caso o SqlQuery.

Conectando ao Firebird

Conforme já mencionado, estaremos utilizan-do o componente de conexão ao Interbase/Firebird para construirmos um exemplo de manipulação de uma base de dados Firebird.

O primeiro passo é criarmos nossa base de dados de exemplo. Chamarei a mesma de The-Club_Lazarus_Teste.

Veja o script de criação da base:

CREATE DATABASE ‘C:\THE_CLUB_LAZARUS_TESTE.fdb’ page_size 4096 user ‘SYSDBA’ password ‘masterkey’ CREATE TABLE THE_CLUB_NOMES( ID_NOME INTEGER NOT NULL, NOME VARCHAR(50), RG VARCHAR(20), CPF VARCHAR(20));

Após criarmos a base de dados, faremos o projeto no Lazarus. Abra o Lazarus e inicie um novo projeto do tipo Application.

Por ora não estaremos montando o layout da aplicação. Estaremos criando a função de conexão ao banco de dados Firebird.

Abra o código da unit e na cláusula uses colo-que a unit: IBConnection.

Na seção implementation declare a função conforme mostrado abaixo:

function ConexaoFirebird(DataBaseHost,DataBaseName,UserName,Password:String):TIBConnection;var ConnAux:TIBConnection;begin ConnAux:=TIBConnection.Create(nil); ConnAux.HostName:=DataBaseHost; ConnAux.DatabaseName:=DataBaseName; ConnAux.UserName:=UserName; ConnAux.Password:=Password; ConnAux.Connected:=True;

if(ConnAux.Connected)then Result:=ConnAux

else Result:=nil;end;

Essa função receberá pela ordem, o servidor, ou ip do servidor de banco de dados (em geral localhost), o caminho e nome do arquivo de ban-co de dados, o nome de usuário e a senha e nos devolverá, caso a conexão se realize, um objeto IBConnection com a conexão.

Vamos testar a conexão. No evento OnCreate do formulário principal da aplicação que criamos, iremos chamar essa função e mostrar o resultado no Caption da janela. Veja o código do evento OnCreate do formulário:

procedure TForm1.FormCreate(Sender: TObject);var Conn:TIBConnection;begin Conn:=ConexaoFirebird(‘localhost’,’C:\TheClub_Lazarus_Teste’,’SYSDBA’ ,’masterkey’);

if(Conn<>nil)then Caption:=’Conexão OK’ else Caption:=’Não foi possível realizar a conexão’;

end;

Veja o resultado na figura 2.

Figura 1

Figura 2

Page 24: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201224

Repare que no topo da página irá aparecer a mensagem avisando que a conexão está fun-cionando.

Essa função que criamos é bastante útil porque cria a instância da conexão ao ser chamada. Isso possibilita utilizarmos uma conexão por acesso ao banco, reduzindo o tráfego em uma única conexão.

Na sequência, faremos a função de inserção de dados em nossa tabela. Utilizaremos essa função de conexão e através dela passaremos os valores via Sql direto.

Para inserirmos dados, agora precisamos ter um layout de tela com alguns objetos. Iremos aproveitar o formulário já existente e montaremos o layout conforme a figura 3.

Com o layout criado, faremos a rotina de in-serção dos dados diretamente no botão “Inserir”. Criaremos, além da conexão, um objeto do tipo SqlQuery para inserir os dados.

Veja o código do OnClick do botão “Inserir”:

procedure TForm1.Button1Click(Sender: TObject);var Sql:string; Conn:TIBConnection; Trans:TSQLTransaction;begin // Conectamos ao banco Conn:=ConexaoFirebird(‘localhost’,’C:\TheClub_Lazarus_Teste’,’SYSDBA’,’masterkey’); Trans:= TSQLTransaction.

Create(nil); // Criamos a transação para a conexão

if(Conn<>nil)then // Se a conexão estiver ok, fazemos a inserção dos dados begin Conn.Transaction:=Trans; // Ligamos o componente de transação a conexão

// Montamos a frase Sql de inserção Sql:=Format(‘INSERT INTO THE_CLUB_NOMES

VALUES(%s,%s,%s,%s)’, [edtCodigo.Text,QuotedStr(edtNome.Text),QuotedStr(edtRG.Text),

QuotedStr(edtCPF.Text)]); try try // Iniciamos a transação e executamos o insert via conexão Trans.StartTransaction; Conn.ExecuteDirect(Sql); Trans.Commit; ShowMessage(‘Registro inserido com sucesso’);

except // Se ocorrer erro cancela a transação Trans.Rollback; end; finally Trans.Free; Conn.Free; end; end;end;

Veja o aplicativo em execução na figura 4:

Para finalizar, vamos completar nosso exemplo com a consulta aos dados. Utilizaremos a mesma tela que estamos utilizando para inserir os dados para essa consulta. Só que utilizaremos três com-ponentes fixos:

SqlQuery: Aba sqlDB; DataSource: Aba DataAccess; DbGrid: Aba DataControls;

Figura 3

Figura 4

Page 25: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 25

Colocaremos também um button com o texto “Atualizar Consulta” para mostrarmos os dados atualizados após as inserções.

Veja como ficará o layout na figura 5

Ligue o DataSource ao SqlQuery através da propriedade DataSet e o Dbgrid no DataSource através da propriedade DataSource.

Na propriedade Sql do SqlQuery coloque a frase:

SELECT * FROM THE_CLUB_NOMES.

Na função de atualizar a consulta, iremos criar a instância da conexão e ligar a Query a essa instân-cia para gerarmos a consulta ao abrirmos a Query.

Vamos agora ao código do botão “Atualizar Consulta”:

procedure TForm1.Button2Click(Sender:

TObject);var Conn:TIBConnection;

Trans:TSQLTransaction;begin try SQLQuery1.Close; // Conectamos ao banco Conn:=ConexaoFirebird(‘localhost’,’C:\TheClub_Lazarus_Teste’,’SYSDBA’,’masterkey’);Trans:=TSQLTransaction.

Create(nil); // Criamos a transação para a conexão

Conn.Transaction:=Trans; SQLQuery1.DataBase:=Conn;

SQLQuery1.Open;// Abrimos a query

finally Conn.Free; Trans.Free; end;end;

Veja a consulta em execução na figura 6:

Com a parte de consulta fechamos nosso exemplo de manipulação do banco de dados Fire-bird com Lazarus.

Conclusão

Nesse segundo artigo sobre Lazarus, demons-trei como utilizar a ferramenta no trato com um dos bancos de dados mais utilizados pela comunidade Delphi atualmente: O Firebird.

Firebird é um banco que a cada dia vem se tornando mais robusto e confiável. Então toda fer-ramenta de automação comercial precisa possuir uma boa integração com esse banco, e nessa parte Lazarus se mostra totalmente efetivo.

Além do Firebird, estarei mostrando nos pró-ximos artigos como podemos conectar o Lazarus a outros bancos de dados como SqlLite e MySql, excelentes opções de bancos Open Source.

É isso, espero que tenham gostado e até a próxima!

Consultor Técnico The Club.

Sobre o autor

Antonio Spitaleri Neto

[email protected]

Figura 5

Figura 6

Page 26: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201226

X

MÉTODOS RAVEReportde A a Z

WWRITE NULL DATA – este método escreve

um valor nulo dentro do evento OnGetRow de um componente de conexão de dados. Os da-dos para os campos personalizados devem ser escritos na mesma ordem em que os campos foram definidos no evento OnGetCols.

Example (Delphi)

Connection.WriteNullData( );

WRITE STRING DATA – Este método grava o conteúdo de um campo String personalizado (de tipo dtString) dentro do evento OnGetRow de um componente de conexão de dados. Os dados para campos personalizados devem ser escritos na mesma ordem em que os cam-pos foram definidos no evento OnGetCols. Os parâmetros formatdata definem o valor formatado do campo, mas podem ficar em

branco se não for necessária uma saída pré--formatada. Parâmetros NativeData devem conter o conteúdo não modificável do campo.

Example (Delphi)

Connection.WriteStrData( ‘’,CustomerName );

XD2I – este método converte a unidade de medida horizontal da tela de impressora de pontos (dots) para polegadas (inches).

Example (Delphi)

// Com Units atualmente configuradas para unInch XPos := RvNDRWriter1.XD2I( LastXDots );

XD2U – este método converte a unidade de medida horizontal da tela da impressora de

pontos (dots) para unidades (units) (definida por Unidades em UnitsFactor)

Example (Delphi)

XPos := RvNDRWriter1.XD2U( LastXDots );

XI2D – este método converte a unidade de medida horizontal da tela da impressora de inch (polegadas) para pontos (dots).

Example (Delphi)

// Com Unidades atuais configuradas para unInchCurrXDots := RvNDRWriter1.XI2D( RvNDRWriter1.XPos );

XI2U – este método converte a medida horizontal de inch (polegadas) para unit (de-finida pela Units e UnitsFactor).

Example (Delphi)

Page 27: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 27

YZ

XPos := RvNDRWriter1.XI2U( LastXInch );

XU2D – este método converte a medida horizontal de units (definida pelas Units e UnitsFactor) para pontos (dots).

Example (Delphi)

CurrXDots := RvNDRWriter1.XU2D( RvNDRWriter1.XPos );

XU2C – este método converte a medida horizontal de units (definida pelas Units e UnitsFactor) para polegadas (inches).

Example (Delphi)

//com units configuradas para unCMCurrXInch := RvNDRWriter1.XU2I( RvNDRWriter1.XPos );

YD2I – este método converte a unidade de medida vertical da tela da impressora de pontos (dots) para polegadas (inches).

Example (Delphi)

// com unidades configuradas para unInch YPos := RvNDRWriter1.YD2I( LastYDots );

YD2U – este método converte a unidade de medida vertical da tela da impressora de pontos (dots) para unidades de medidas (definidas pela Units e UnitsFactor).

Example (Delphi)

RvNDRWriter1.YPos = RvNDRWriter1.YD2U( LastYDots );

YI2D – este método converte a unidade de medida vertical da tela da impressora de polegadas para pontos.

Example (Delphi)

// com Units configurada para unInch CurrYDots := RvNDRWriter1.YI2D( YPos );

YI2U – este método converte a unidade de medida vertical da tela da impressora para unidades de medidas (definida pela Units e UnitsFactor).

Example (Delphi)

RvNDRWriter1.YPos := RvNDRWriter1.YI2U( LastYInch );

YU2D – este método converte a unidade de medida vertical da tela da impressora DE unidades de medidas (definida pela Units e UnitsFactor) para pontos (dots).

Example (Delphi)

CurrYDots := RvNDRWriter1.YU2D( RvNDRWriter1.YPos );

YU2I – este método converte a unidade de medida vertical da tela da impressora de unidades de medidas (definida pela Units e UnitsFactor) para polegadas (inches).

Example (Delphi)

Consultora Técnica The Club.

Sobre o autor

Leonora Golin

[email protected]

// Com units configuradas para unCM CurrYInch := RvNDRWriter1.YU2I( RvNDRWriter1.YPos );

ZOOM IN – este método adiciona Zoo-mInc ao ZoomFactor atual e aumenta a ima-gem na tela. Se um evento OnZoomChange for definido, então será chamado e será responsável por redesenhar a página, caso contrário, a tela é redesenhada.

Example (Delphi)

// este código faz com que o ZoomFactor seja incrementado por ZoomInc. RvRenderPreview1.ZoomIn;

ZOOM OUT - este método subtrai Zoo-mInc do ZoomFactor atual e diminui a imagem na tela. Se um evento OnZoomChange for definido, então será chamado e será respon-sável por redesenhar a página, caso contrário, a tela é redesenhada.

Example (Delphi)

RvRenderPreview1.ZoomOut;

Page 28: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201228

Dicas DELPHI

Alterando as configurações de Rede

Nessa dica será criado um exemplo de como alterar as propriedades da rede fazendo com que os dados sejam recriados, como o IP, a máscara de rede e o gateway, diretamente pela aplicação.

unit AlteraIP;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type TForm1 = class(TForm) private { Private declarations } public { Public declarations }

Criamos duas funções, uma que irá receber os dados da conexão, retor-nando se é uma conexão existente ou não, e outra que aguarda a execução do momento necessário.

function MudarIp(Conexao, Ip, Mascara, Gateway: string):boolean; function ExecutarAguardando(Arquivo: string; Visibilidade: integer):integer; end;

var Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

function TForm1.ExecutarAguardando(Arquivo: string; Visibilidade: integer): integer;

O primeiro passo é criarmos 6 variáveis que servirão para identificar o caminho do diretório, as informações de inicialização e de execução e o resultado geral de hardware

var Aplicativo, Diretorio, WorkDir: string; Inicializacao: TStartupInfo; Processo: TProcessInformation; Resultado: DWord;

Iremos agora copiar o texto da variável “Aplicativo” para armazená-la na variável “Arquivo”, depois, selecionar o diretório padrão dá máquina correspon-dente, e novamente copiar, só que desta vez copiando o conteúdo da variável “Diretório” para a variável “WorkDir”

begin StrPCopy(Aplicativo, Arquivo); GetDir(0, WorkDir); StrPCopy(Diretorio, WorkDir);

Logo fazemos a verificação de dados inicializados, através da procedure FillChar, que irá identificar a quantidade de bytes utilizados no processo, iremos trazer as informações de inicialização e a condição da sua execução

FillChar(Inicializacao, Sizeof(Inicializacao), #0); Inicializacao.cb := Sizeof(StartupInfo); Inicializacao.dwFlags := STARTF_USESHOWWINDOW; Inicializacao.wShowWindow := Visibilidade;

Logo em seguida, caso o processo não seja criado, retornamos o resultado com o valor de -1, para considerar inutilizado o processo, mas caso já seja con-siderado um processo criado, ele irá aguardar o processo, retornará o código de saída do processo e exibirá o resultado.

if not CreateProcess(nil, aplicativo, nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, Inicializacao, Processo) then Result := -1 else begin WaitforSingleObject(Processo.hProcess, INFINITE); GetExitCodeProcess(Processo.hProcess,Resultado); Result := Resultado; end;

E por ultimo, a principal alteração, que recupera os dados de configuração de rede e altera de acordo com os dados informados.

begin Result:=(ExecutarAguardando(‘Configurar o endereco IP netsh “’+Conexao+’” ‘+ ‘ estatico ‘+Ip+ ‘ ‘+Mascara +’ ‘+GateWay+’ 1’, SW_HIDE)=0); end;

E para que tenhamos certeza de que as alterações dos dados da conexão tenham sido realmente alteradas precisamos verificar utilizando a função MudarIp, se os dados tiveram validade

Page 29: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012 29

begin if not MudarIp(‘Local Area Connection’, ‘192.168.10.22’, ‘255.255.255.0’, ‘192.168.10.90’) then ShowMessage(‘Erro na alteração do IP’) else ShowMessage(‘IP alterado sem erros’); end;end;end.

Essa dica é útil pra quem precisa administrar uma rede e necessita de alterações dos valores dos dados estáticos de suas conexões, através da própria aplicação facilitará e exigirá menos contato com interno as configurações do sistema operacional.

Fechar sistema ao acessar uma janela da aplicação

Essa dica utiliza um procedimento que irá controlar a restrição de acesso á determinados formulários fechando a aplicação, de acordo com o Caption do formulário ao tentar acessá-la

unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type TForm1 = class(TForm) private { Private declarations }

É importante declará-la como sendo pública para que todas as outras units possam enxerga-la.

public { Public declarations } procedure FinalizaPorCaption(const frmClasse, frmJanela: string); end;

var Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

Depois de criada a procedure, é utilizada a constante PROCESS_TERMINATE que indexa o caminho do processo declarado, fazendo com que se encerre, além das variáveis que servirão para verificar o formulário ativo do sistema

procedure TForm1.FinalizaPorCaption(const frmClasse, frmJanela: string);const PROCESS_TERMINATE = $0001;var HWNDJanela: HWND; HandleProc: THandle; IDProcesso: Integer; Classe, Janela: PChar;

A procedure verifica se a classe e a janela estão vazias e então declarando seus valores como nil, caso não, ela resgata os valores passados pelos parâ-metros da procedure, fornecidas pelo usuário.

begin try if Classe = ‘’ then Classe:= nil else Classe:= PChar(Classe);

if Janela = ‘’ then Janela:= nil else Janela:= PChar(Janela);

Após identificado o formulário da aplicação iremos armazená-la na variável do tipo HWND que controla os processo em execução e o GetWindowThrea-dProcessID, identificando a janela e o índice do processo

HWNDJanela:= FindWindow(Classe, Janela); GetWindowThreadProcessID(HWNDJanela, @IDProcesso);

E fechando o metodo try...finally encerramos o processo pelo ID definido

finally HandleProc:= OpenProcess(PROCESS_TERMINATE, False, IDProcesso); TerminateProcess(HandleProc, 4); end;end;

end.

Conclusão

Esse procedimento serve como, por exemplo, para as permissões de usuário, ou encerrar forçadamente um acesso não permitido, ocasionando o encerramento do sistema.

Page 30: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 201230

VerticalHorizontal

Page 31: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012

Page 32: The Club - megazine · - Dicas Delphi Dicas ... Delphi Delphi Delphi Delphi Conexão ao Firebird em Lazarus Métodos RAVReport - de A a Z - parte 4 índice Criando uma aplicação

fevereiro 2012