Buscar

Agenda - delphi + firebird (domains, triggers, procedures, generators) - parte 02

nome

Alessandro De Oliveira Alves

Colunista ainda sem descrição. Caro colunista, por favor envie-nos sua descrição.

Agenda - Parte II (Criação da aplicação em Delphi)

Salve, Salve companheiros !! Estamos aqui novamente para dar continuidade ao nosso projeto iniciado no artigo anterior.

Bem, na primeira parte deste artigo, criamos o banco de dados de nossa aplicação e seus objetos (Procedures, Triggers, Domains e Generators), agora vamos partir para o Delphi e unir as duas coisas.

Então, criemos uma nova aplicação e no formulário principal vamos adicionar os seguintes componentes:

7 Edits, 7 Labels, 6 Botões, 1 Groupbox, 1 DBGrid, 1 OpenDialog (paleta Dialogs), 1 DataSource (paleta Data Access) e 4 componentes da paleta Interbase - 1 IBDatabase, 1 IBTransaction, 2 IBQuery e 1 IBStoredProc.

Nosso formulário deverá ter a aparência abaixo:



Vou deixar a nomeação de componentes a critério de vocês, e vou usar imagens para determinar quais componentes iremos codificar, exceto os que seguem abaixo para evitar confusões durante o processo de codificação.

Dê um duplo clique no IBDatabase, e então abrirá o "Database Component Editor". Faça as configurações conforme segue abaixo:



No Object Inspector as propriedades do IBDatabase deverá estar assim:



Configurações do IBTransaction no Object Inspector:



Agora, no primeiro componente IBQuery, acesse a propriedade SQL. O Editor SQL será exibido. Adicione o SQL que segue:



Adicionado o SQL, ajuste as seguintes propriedades no object inspector:



Clicando na propriedade Params (circulada de azul) devemos ter a seguinte visão:



No outro componente IBQuery, acesse a propriedade SQL. O Editor SQL será exibido. Adicione o SQL que segue:



Vamos analisar rapidamente esse SQL. Lembram-se que, no nosso banco de dados criamos uma procedure selecionável de nome SP_NEW_ID? Pois bem, agora estamos fazendo um SELECT à partir de uma Stored Procedure, por isso chamamos de procedure selecionável. Estamos passando para a stored procedure uma parâmetro, que neste caso será o nome da tabela e ela nos retornará o pOUT_ID que será o valor que desejamos. Lembram-se da definição da procedure no banco de dados?



Pois aí está, passamos para a procedure um parâmetro de entrada que é o nome da tabela, e ela nos retorna no parâmetro de saída POUT_ID o valor que nos interessa.

Continuando as configurações do componente, no object inspector faça as configurações como abaixo:



Clicando na propriedade Params (circulada de azul) devemos ter a seguinte visão:



Configuremos agora o componente IBStoredProc conforme segue:



Uma vez configuradas estas propriedades, clicamos na propriedade PARAMS que deverá exibir a seguinte aparência:



Lembram-se da definição da Stored Procedure INS_UPD_DEL_CONTATO no banco de dados??



Vejam que o Delphi reconhece automaticamente os parâmetros de entrada exigidos pela Stored Procedure definida no banco de dados.

Agora, configure o componente Data Source da seguinte forma:



Pois bem pessoal, agora configure a propriedade DataSource do DBGrid como dsAgenda e pronto. Essas são as configurações básicas que devem ser feitas para que o nosso exemplo funcione adequadamente.

Obs.: O edit que aparece em "amarelo" nomeie como edtID, ele será utilizado para receber o identificador único (chave primária) de nossa tabela. Este pode ser até setado como Visible False, mas deixarei como True para que possamos ver seu comportamento.

Agora vamos codificar nossa aplicação.

Primeiramente vamos definir duas funções. Na seção private do formulário declare-as como segue:



Teclamos SHIFT+CTRL+C para o delphi criar para nós o corpo das funções na seção implementation.

Assim, definimos para a função fCamposPreenchidos o seguinte código:



Trata-se de uma função extremamente simples que, retorna true se o campo nome e, pelo menos um dos telefones estiver preenchido. Afinal de contas não faz sentido inserir na agenda um registro sem nome, ou, um registro que tenha apenas um nome e não tenha nenhum telefone, não é mesmo??

O código da função fGetNewID deve ser o seguinte:



Pois bem, como já definimos um SQL para a query "qryID" e definimos também um parâmetro de entrada para ela, nesse código apenas: fechamos a query, atribuímos o valor do parâmetro de entrada da função "pTab" ao parâmetro de entrada da query, abrimos a query e atribuimos ao resultado da função o valor retornado no Fields[0] da query. Dessa forma, a função fGetNewID faz com que a query "qryID" com o select que lá adicionamos, vá até a SP_NEW_ID no banco de dados e nos retorne o próximo ID da tabela desejada.

Agora vamos ao evento "OnChange" do edit logo à frente do label "Localizar Nome" e vamos adicionar o seguinte código:



Código:



Como já definimos um SQL para a query "qryAgenda" e um parâmetro de entrada, o que fazemos aqui também é bastante simples. Apenas fechamos a query, atribuimos um valor ao parâmetro, no caso, o texto existente no edit "edtlocalizar" e abrimos a query. Dessa forma, como a query está ligada ao Data Source "dsAgenda" que por sua vez está ligado ao DBGrid, o resultado da query será exibido no DBGrid.

No evento "OnCreate" do form, adicione o seguinte código:



Com este código, logo na criação do formulário a query irá retornar todos os registros já existentes na tabela AGENDA do nosso banco de dados.

Vamos agora definir uma procedure que servirá para fazer as alterações no banco de dados. Vamos declarar na seção private o seguinte procedimento:



Na implementação do procedimento, adicionamos o seguinte código:



Aqui, através do componente IBStrProc (prcIns_Upd_Del_Contato) atribuímos os valores passados ao procedimento aos valores de entrada da Stored Procedure do banco de dados e executamos a Stored Procedure. O banco se encarrega de fazer o trabalho adequado, conforme seja o valor passado no parâmetro "pOperacao".

Vamos agora, codificar os botões de nossa aplicação.

No evento "OnClick" do botão com caption "Salvar - Novo" adicione o código:



Então, o que fazemos aqui?

Bem, usando a função por nós definida "fCamposPreenchidos" verificamos se os campos de preenchimento obrigatório estão de fato preenchidos, em caso negativo, informamos ao usuário que os campos obrigatórios devem ser preenchidos.

Satisfeita a condição de campos obrigatórios preenchidos, retornamos na propriedade "text" do edtID o novo ID a ser utilizado para a tabela AGENDA, usando para isso a função por nós definida "fGetNewID" passando como parâmetro da função o nome da tabela que desejamos.

Retornado o ID, chamamos a função InsUpdDelContato passando os valores contidos nos edit's como parâmetros de entrada para a função, sendo que, o último parâmetro é o que define qual a operação que desejamos realizar. Neste caso, "I" que representa a operação de Inserção (Insert). Colocamos a chamada ao procedimento dentro de um bloco Try..Except para dar um retorno ao usuário no caso de erro na execução do procedimento. Ao final, disparamos o evento "OnChange" do edtlocalizar.

No evento "OnClick" do botão com caption "Salvar - Edição" adicione o código:



Da mesma forma que no código anterior, verificamos o preenchimento dos campos obrigatórios e, fazemos a chamada ao procedimento InsUpdDelContato para efetuar a operação desejada, neste caso "A" que representa a alteração do registro (Update).

No evento "OnClick" do botão com caption "Excluir" adicione o código:



Aqui, o que muda é que, antes de chamar o procedimento verificamos se existe um registro selecionado, se existe um valor no campo edtID. Existindo, chamamos o procedimento passando os parâmetros. Neste caso, não precisamos passar todos os parâmetros, já que, para a exclusão de um registro necessitamos apenas de seu ID. Sendo assim, passamos os demais parâmetros como strings vazias.

No evento "OnClick" do botão com caption "Limpar Campos " adicione o código:



Aqui, sem mistérios, apenas limpamos os textos dos edit's.

No evento "OnCellClick" do DBGrid adicione o seguinte código:



Simplesmente atribuímos à propriedade "text" dos edits correspondentes o valor existente em cada campo da query conforme o registro que selecionamos no DBGrid.

No evento "OnKeyPress" dos edits relacionados a telefones, adicione o seguinte código, para que os mesmos aceitem apenas números e back space.



Agora, partimos para a parte de importação de TXT/CSV.

No evento "OnClick" do botão com 3 pontinhos (...) adicione o seguinte código:





Aqui, apenas atribuímos ao edit "edtOrigem" o caminho completo + o nome de arquivo selecionado a partir da Open Dialog.

No componente OpenDialog (opndlgOrigem) faça as seguintes configurações:



Clique na propriedade Filter e no Filter Editor adicione as opções para que sua aparência fique como segue abaixo:



No evento "OnClick" do botão com caption "Import TXT/CSV" adicione o seguinte código:




Na seção VAR (destacado em amarelo) definimos variáveis que irão armazenar os valores obtidos à partir do arquivo texto. Lembram que falaríamos da utilização da classe TStringList?? Pois bem, olha aí (destacada em vermelho) a variável "str" do tipo TStringList.

Como vamos fazer uma importação, a primeira providência é ver se o arquivo informado no edit origem, de fato existe. Usamos para isso a função "FileExists" que recebe como parâmetro o caminho do suposto arquivo que utilizaremos.

Logo abaixo, criamos nossa StringList, instanciando na variável str um objeto da classe TStringList, e logo após isso, definimos que o caracter delimitador de nossa TStringList é o ponto-e-vírgula.

No código logo abaixo, destacado em azul claro, apenas fazemos a atribuição de nosso arquivo texto.

Atribuímos à variável "ArqOrigem" do tipo String, o valor contido na propriedade "text" do edit "edtOrigem". A seguir, atribuímos à variável "Arq" do tipo TextFile o arquivo existente no caminho que aponta a variável "ArqOrigem". Usando o procedimento RESET abrimos o arquivo. Usando o procedimento ReadLn fazemos a leitura da primeira linha do arquivo aberto e atribuímos o conteúdo à variável "Linha".

Dentro do loop while, enquanto existirem linhas a serem lidas, ou seja, enquanto não chegarmos ao final do arquivo, atribuímos à propriedade "DelimitedText" da nossa StringList o valor da variável linha.

Aí que a coisa fica interessante. Lembram que definimos a propriedade delimiter da nossa StringList como ";" ? Pois bem, sabemos que, normalmente um arquivo CSV tem seus valores separados por ponto-e-vírgula, sendo assim, o arquivos que utilizaremos no nosso exemplo possui uma estrutura semelhante à que segue abaixo:

"LUIZ CARLOS";34377121;98775300;"luizcarlos@qualquermail.com.br"
"CELIA CARDOSO";33485211;81985591;"celia@mycompany.com.br"
"ZELIA SANTOS";33958752;96325554;"zelia@qualquermail.com.br"

Onde, o primeiro campo é o nome da pessoa, o segundo é o telefone residencial, o terceiro é o telefone celular e o quarto é o e-mail. Um observação importante deve ser feita aqui. Para que o resultado esperado seja correto no uso da TStringList como vamos fazer, quando no arquivo CSV/TXT, o valor for uma string composta por mais de um valor e, houver espaço entre suas partes, como por exemplo no nome LUIZ CARLOS, toda a string deve vir entre aspas duplas, caso contrário a TStringList entenderá se tratar de dois valores independentes.

Continuando então....sabendo da estrutura de nosso arquivo CSV/TXT e, tendo definido a propriedade delimiter da nossa StringList como sendo o ";", atribuimos à propriedade "DelimitedText" o valor da variável linha que recebeu uma linha de nosso arquivo CSV/TXT.

Feito isso, podemos tratar nossa StringList como uma matriz de valores, onde, podemos acessar o valor desejado através de seu índice, e é exatamente o que fazemos aqui. Utilizando os índices desejados, resgatamos os valores da StringList e atribuímos às variáveis que definimos para armazenar os respectivos valores a serem inseridos no nosso banco de dados.

Uma vez com os valores nas respectivas variáveis, geramos um ID para o registro a ser inserido e fazemos a devida inserção no banco de dados chamando a procedure InsUpdDelContato que criamos em nossa aplicação. Em caso de erro, uma mensagem é exibida ao usuário.

A casa inserção uma nova linha do arquivo é lida (ReadLn) e inserida no banco de dados até que se chegue ao final do arquivo.

Finalizado o arquivo, ele é fechado (CloseFile) e uma mensagem de sucesso na importação é exibida.

É isso aí galera..... finalizamos assim mais um artigo. Espero que o conteúdo deste artigo possa auxiliá-los em suas tarefas do dia-a-dia.


Para baixar todo o conteúdo deste artigo, clique aqui.

Alessandro Alves
planetadelphi@oppus.eti.br
www.oppus.eti.br

Publicidade

Vote no artigo




Quantidade de votos: 0 votos
Aceitação: 0%


Detalhes do artigo

Categoria: Banco de dados
Adicionado dia: 28/05/06
Por: Alessandro De Oliveira Alves
Visualizado: 96581 vezes

Planeta Delphi - Tudo sobre programação Delphi Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009