Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Nelson Henrique

DBLookUpComboBox

Recommended Posts

Boa Tarde,

 

Sou um iniciante em programação, mas muito dedicado.

 

Estou desenvolvendo meu TCC antecipadamente nestas férias, já que estudo em 4 escolas e por isso o tempo é escasso.

 

Meu sistema é para um mercado, que atualmente utiliza um sistema em clipper. O.o

 

Meu problema esta numa besteira, que seria filtrar informações de um DBLookUpComboBox.

 

Ontem pesquisei e aprendi (na marra) a utilizar um, e aparentemente funciona. Mas com isso arrumei um problema pior.

 

Tenho 3 tabelas. Pais, Estado e Cidade. Coloquei 3 DBLookUpComboBox, e através dos keyfields consegui preencher as foreign keys da tabela de cadastro de funcionário.

 

Mas quando abro o DBLookUpComboBox da Cidade por exemplo, ele mostra TODOS os campos da tabela, ou seja, TODOS as cidades que estão cadastradas. O que eu preciso, é que apareça APENAS as cidades do estado anteriormente selecionado.

 

A primeira coisa que pensei foi linkar o DBLookUpComboBox com uma Query, mas nem imagino como fazer...

 

Em segundo momento, pensei em filtrar a tabela na propriedade Filter do componente IbTable, utilizando uma variavel global e jogando a keyfield do DBLookUpComboBox usado em estado na propriedade Filter da tabela cidade. Mas não consegui tambem.

 

Segue minhas anotações da SQL que usei:

 

CREATE TABLE "pais" (
	"cod_pais"  SMALLINT NOT NULL,
	"sgl_pais"  CHAR(2) NOT NULL,
	"nom_pais"  VARCHAR(50) NOT NULL
);



CREATE TABLE "estado" (
	"cod_estado"  SMALLINT NOT NULL,
	"cod_pais"	SMALLINT NOT NULL,
	"sgl_estado"  CHAR(2) NOT NULL,
	"nom_estado"  VARCHAR(50) NOT NULL
);



CREATE TABLE "cidade" (
	"cod_cidade"  INTEGER NOT NULL,
	"cod_estado"  SMALLINT NOT NULL,
	"nom_cidade"  VARCHAR(50) NOT NULL

Estou usando Firebird/Sql Manager

 

Se puderem me ajudar, agradeço muito. =]

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Nelson Henrique.

 

As duas opções em que voce imaginou estão corretas, só que a mais recomendável é a primeira opção em que pensastes, pois com uma instrução SQL em uma IBQuery, já que usa o Firebird, o filtro é mais rápido, muito embora isto seja imperceptível para uma tabela que contenha poucos registros.

 

Suponhamos que voce tenha 3 componentes TDBLookupComboBox, então no primeiro que está linkado a países, selecione e vá no Object Inspector do mesmo e na aba Events, selecione o Evento OnCloseUp e click duas vezes dentro da caixa de texto desse evento, para montar o esqueleto da procedure do evento, e depois vamos codificar dentro desse evento, o filtro da IBQuery que está listando ao TDBLookupCombobox dos Estados, assim:

 

procedure TForm1.dblcbPaisesCloseUp(Sender: TObject);
begin
   with IBQueryEstados do begin
	   Close;
	   SQL.Clear;
	   SQL.Add('Select * From Estados Where NomePais = :Pais');
	   ParamByName('Pais').Value := dblcbPaises.Text;
	   Open;
   end;
end;

Agora vamos fazer os mesmo procedimentos acima descritos com as cidades, implementando esse código:

 

procedure TForm1.dblcbEstadosCloseUp(Sender: TObject);
begin
   with IBQueryCidades do begin
	   Close;
	   SQL.Clear;
	   SQL.Add('Select * From Cidades Where NomeCidade= :Cidade');
	   ParamByName('Cidade').Value := dblcbEstados.Text;
	   Open;
   end;
end;

Fácil né.

 

Um abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já temos meio caminho andado.

 

Como você disse, facil mesmo. Bastou e entender tua lógica.

 

Mas só esqueceu de duas coisas. O seu código só funcionaria se eu tivesse o nome do país na tabela estado (coisa que não tenho, eu tenho apenas o código).

 

Resolvi isto utilizando a propriedade KEYFIELD, já que esta pega exatamente o código da tabela país e joga na foreign key da tabela do cadastro de funcionário por exemplo.

 

Resolvi isto desta maneira:

 

With DM.qry_cidade do
  Begin
	Active:= false;
	ParamByName('Estado').Value := cbx_pais.KeyField;
	Active:= true;
  End;

E no atributo SQL do query, coloquei:

 

Select * From ESTADO Where "COD_PAIS" = :Pais

 

Mas agora, a outra coisa que você esqueceu... Como que eu coloco os dados que foram retornados nesta consulta no DBLookUpComboBox???

 

 

Já me ajudou bastante amigo... Obrigado!

Se puder continuar me ajudando, agradeço!!

 

Abraços

 

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só tem um negócio estranho...

 

Para conferir as querys, eu coloquei um DBgrid e um DataSource para a consulta país/estado e outra dupla para a consulta estado/cidade.

 

O país/estado funcionou perfeitamente... mostrou no DBGrid os 27 estados brasileiros como eu cadastrei.

Já o estado/cidade, ele nomeia as colunas do DBGrid, mas não exibe valor algum!!!

 

Não sei o que esta acontecendo. A consulta esta correta. O banco de dados também esta todo preenchido. O DBGrid tambem esta ligado. -.-"

 

Mas isto é o de menos... se eu conseguir preencher os LookUp corretamente, já estou feliz.

 

Obrigado e boa noite.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Nelson Henrique.

 

Respondendo a sua pergunta de como se coloca os dados no DBLookupCombobox, esta é a parte mais fácil.

 

A maneira correta de se configurar o DBLookupCombobox e esta:

 

1º) ListSource: Aqui vamos apontar para o DataSouce que está linkado no componente que vai ler a sua tabela (Paises, Estados e Cidades) que vai preencher a lista.

 

2º) ListField: Aqui nós apontamos para o campo que vai preencher a lista, detalhe é que voce pode listar valores por mais de um campo, desde que os nomes dos campos estejam separados por ponto e vírgula ";" dentro da combo ListField.

 

3º) KeyField: Aqui nós apontamos para o campo cujo valor é a chave que queremos armazenar na outra tabela, muitas das vezes, queremos listar um valor, porém queremos armazenar outro valor que corresponde a chave primária - estrangeira na outra tabela, e é justamente o seu caso, então em KeyField aponte para a chave primária da tabela que pode ser por exemplo "Cod_Pais", e em ListField aponte para Nome_Pais.

 

4º) DataSource: Aqui nós apontamos para o DataSource que está linkado no componente que lê a tabela onde iremos armazenar os dados especificado em KeyField, detalhe é que se voce não especificar nenhuma tabela de destino, o DBLookupCombobox não é nem ativado em tempo de execução.

 

5º) DataField: Aqui nós configuramos o campo da tabela de destino que vai armazenar o dado especificado em KeyField.

Bom, é isto, espero que tenha ajudado.

 

Um abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A linkagem ficou perfeita. Muito Obrigado.

 

 

Mas a nossa consulta não esta funcionando. =/

 

Ele ainda esta retornando TODOS OS VALORES DA TABELA.

 

Ou seja, com consulta ou sem consulta, esta dando na mesma.

 

Tem alguma ideia de como fazer a consulta funcionar??? Eu garanto que linkei o DataSource corretamente na Query.

 

Abraços, e Obrigado por enquanto... =D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite Nelson Henrique.

 

Talvez o erro deva estar aqui

 

With DM.qry_cidade do

Begin

Active:= false;

ParamByName('Estado').Value := cbx_pais.KeyField;

Active:= true;

End;

Percebeu que voce está atribuindo ao parâmetro Estado, o código do País. Como voce configurou na Query a SQL com os seus parâmetros ?

 

Posta aqui para que eu possa ter um idéia.

 

Um abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Percebi sim... Pelo menos acho que era isso que eu devia ter feito... =D

 

Isto esta no query ESTADO, que deveria fazer a consulta na tabela ESTADO retornando todos os campos com o COD_PAIS igual ao KEY_FIELD do campo selecionado no lookup da tabela PAIS:

 

Select * From ESTADO Where "COD_PAIS" = :Pais

E na propriedade ONCLOSEUP do lookup da tabela PAIS:

 

With DM.qry_estado do
  Begin
	Active:= false;
	ParamByName('Pais').Value := cbx_pais.KeyField;
	Active:= true;
  end;

E o mesmo se repete.

 

Isto esta no query CIDADE, que deveria fazer a consulta na tabela CIDADE retornando todos os campos com o COD_ESTADO igual ao KEY_FIELD do campo selecionado no lookup da tabela ESTADO:

 

Select * From CIDADE Where "COD_ESTADO" = :Estado

E na propriedade ONCLOSEUP do lookup da tabela ESTADO:

 

With DM.qry_cidade do
  Begin
	Active:= false;
	ParamByName('Estado').Value := cbx_estado.KeyField;
	Active:= true;
  End;

Espero que tenha "te ajudado a me ajudar"... =D

 

Abraços, e Obrigado!

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Nelson Henrique.

 

Verifiquei que voce fez tudo certo, entretanto, se continua dando algo errado, então devemos:

 

Primeiro:

Verificar qual o valor retornado pela propriedade KeyValue do DBLookupCombobox, deste modo:

 

ShowMessage(IntToStr(cbx_pais.KeyValue));

Existe também uma outra opção além de se utilizar o KeyValue, pois quando voce seleciona o item de um ComboBox que seja, e este estiver linkado em uma tabela do banco de dados, ele movimenta essa tabela para o ponteiro do registro selecionado, então voce pode referenciar o valor ao campo da tabela deste modo:

 

With DM.qry_estado do
	Begin
	  Active:= false;
	  ParamByName('Pais').Value := DM.qry_pais.FieldByName('Cod_Pais').Value;
	  Active:= true;
	end;

Se o erro persistir, então meu velho, dê uma olhada dentro do sua tabela, e veja se ele não está repetindo a mesma chave estrangeira para todos os registros na hora de salvar.

 

Um abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa Tarde,

 

Eu adicionei o código do showmessage, e a keyfield esta variando como deveria.

 

Tentei utilizar o outro método que você disse, utilizando o valor do campo retornado na query, mas ai o LookUp FICA VAZIO. -.-"

 

Agora, um detalhe que reparei aqui.

 

Meu código estava errado!

 

With DM.qry_estado do
  Begin
	Active:= false;
	ParamByName('Pais').Value := cbx_pais.[color="#FF0000"]KeyField[/color];
	Active:= true;
  end;

O correto seria:

 

With DM.qry_estado do
  Begin
	Active:= false;
	ParamByName('Pais').Value := cbx_pais.[color="#FF0000"]KeyValue[/color];
	Active:= true;
  end;

Ou seja, eu estava jogando O NOME DO CAMPO no parâmetro, e sei lá por que ele estava retornando todos os valores.

 

Agora, com o código (acredito eu) correto, ELE NÃO ESTA RETORNANDO NADA, assim como quando eu utilizo a segunda opção.

 

Sei que minha opinião pouco vale, mas acho que estamos esquecendo de fazer algum tratamento, ou coisa do tipo.

 

Jogando no showmessage, aparece certinho o valor que eu quero (No cbx_pais, já que o cbx_estado e o cbx_cidade ficam vazios).

 

Estou ficando estressado já com isso... Já tentei de tudo!

 

Abraços e Obrigado

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah.. Esqueci de dizer.

 

Minhas tabelas estão 100% preenchidas. Nada é mudado nas tabelas Pais, Estado e Cidade durante a execução do sistema.

 

As Foreign Keys foram conferidas e reconferidas, e estão todas corretas.

 

Abraços!

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, tive um certo problema assim no meu programa, eu tinha que filtrar as "subclasses" por "classe" selecionada.

o que fiz foi o seguinte:

configure assim:

 

DBLookupcombobox(país):

datasource = datamodule1.tabelacadastro

datafield = datamodule1.<campo que você quiser gravar na tabela(país)>

listsource = datamodule1.tabelapaís

keyfield = cd_país

listfield = nm_país

 

no evento onClick:

 

var pais : string;

with datamodule1.query1 do

begin

close;

sql.clear;

sql.add('select * from estados where cd_pais<chave estrangeira para país> = '+ pais);

open;

end;

 

dblookupcombobox(estado):

datasource = datamodule1.<tabelacadastro>

datafield = <campo que você quiser gravar na tabela(estado)>

listsource = datamodule1.Datasource1 <datasource criado direcionado para a Query1>

listfield = nm_estado

keyfield = cd_estado

 

siga a mesma lógica com a cidade...

espero ter ajudado, abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Demytrius, sei que a intensão foi de ajudar, mas este tópico é anterior a agosto/2008... por favor, poste em tópicos mais recentes, até porque o colega que abriu o tópico, a esta altura, já deve ter resolvido o problema dele não?

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.