Problema com Mestre-Detalhe, Lookup e Filtros
Olá Galera, bom dia!
Há
tempos que eu venho enfrentando um problema com meu mestre detalhe que envolve
campos lookup. Para deixar bem claro o meu problema, vou mostrar cada passo que
realizo em uma aplicação exemplo.
1º: Meu banco de dados (Firebird) é composto
de três tabelas:
i)
FUNCIONARIO:
ii) ARMARIO:
iii) ARMARIO_FUNCIONARIO; (Mestre-Detalhe);
2º: Crio uma nova aplicação e insiro um Data Module:
CommandText (SDSARMARIO): SELECT * FROM ARMARIO CommandText (SDSFUNCIONARIO): SELECT * FROM FUNCIONARIO CommandText (SDSARMARIO_FUNCIONARIO): SELECT * FROM ARMARIO_FUNCIONARIO WHERE IDFUNCIONARIO = :IDFUNCIONARIO
3º: CRIO AS TELAS DE INSERÇÃO DE ARMÁRIOS E FUNCIONÁRIOS:
Tela 1 – Tela de Cadastro de Armários
Tela 2 – Tela de Cadastro de Funcionários e seus respectivos Armários
4º: Crio os Campos LookUp no CDSARMARIO_FUNCIONARIO:
Criação dos Fields NOME e TIPO
5º: Criação da Tela para adicionar armários no grid dos funcionários:
O click do botão faz o seguinte comando: FrmPrincipal.LocalizarLookup(DS1.DataSet, 'ARMARIO', 'IDARMARIO', 'DESCRICAO', 'Pesquisar Armário '); E a procedure LocalizarLookup tem o seguinte comando: procedure TFrmPrincipal.LocalizarLookup(xDSOrigem: TDataSet; xDescricaoLookup, xCodigo, xDescricao, xTituloPanel: String); begin Try FrmPesquisa := TFrmPesquisa.Create(Self); With FrmPesquisa do begin DSPesquisa.DataSet := xDSOrigem.FieldByName(xDescricaoLookup).LookupDataSet; Grid1.Columns[0].FieldName := xCodigo; Grid1.Columns[1].FieldName := xDescricao; xCampoPesquisa := xDescricao; Pnl1.Caption := xTituloPanel; ShowModal; if FrmPesquisa.ModalResult = mrOk then if xDSOrigem.State in [dsInsert,dsEdit] then xDSOrigem.FieldByName(xCodigo).AsString := DSPesquisa.DataSet.FieldByName(xCodigo).AsString; end; Finally FreeAndNil(FrmPesquisa); End; end; Como NOME e TIPO são campos lookup, eu vou buscar através da uma tela de pesquisa que me mostre todos os armários. Este seria um trabalho facilmente desenvolvido por uma dblookupcombobox, entretanto, este traria à memória todos os armários e o objetivo de buscar uma tela de pesquisa é justamente filtrar o que eu preciso. 6º: Características da Tela de Pesquisa
O click do botão tem o seguinte comando: With TClientDataSet(DSPesquisa.DataSet) do begin Close; Filtered := False; Filter := UpperCase(xCampoPesquisa + ' Like ' + QuotedStr('%' + EdtConteudo.Text + '%')); Filtered := True; Open; end; DSPesquisa.DataSet.First; 7º: O PROBLEMA > Já cadastrada a lista de armários, eu sigo o processo para cadastramento dos funcionários e seus respectivos armários. Da seguinte forma:
Aparecerá a seguinte tela:
Aparecerá a tela de Pesquisa de armários: Onde eu estarei pesquisando o armário de descrição ARM004 e clico na lupa para filtrar o dataset e me trazer a resposta somente do que preciso:
Dando um duplo clique no grid, tenho:
Clico em post , fecho a tela e terei os armários adicionados na grid, mas ao repetir o processo para o segundo e terceiro armário, observe que na grid somente o primeiro armário adicionado aparecem os dados, para o segundo e terceiro não:
Mas, se fechar e abrir o executável, os dados estão lá:
Galera, me ajudem com este problema aí! Estou tentando fazer o upload do código fonte do exemplo acima mas o site não está aceitando.
Att.
Rafael
ii) ARMARIO:
iii) ARMARIO_FUNCIONARIO; (Mestre-Detalhe);
2º: Crio uma nova aplicação e insiro um Data Module:
CommandText (SDSARMARIO): SELECT * FROM ARMARIO CommandText (SDSFUNCIONARIO): SELECT * FROM FUNCIONARIO CommandText (SDSARMARIO_FUNCIONARIO): SELECT * FROM ARMARIO_FUNCIONARIO WHERE IDFUNCIONARIO = :IDFUNCIONARIO
3º: CRIO AS TELAS DE INSERÇÃO DE ARMÁRIOS E FUNCIONÁRIOS:
Tela 1 – Tela de Cadastro de Armários
Tela 2 – Tela de Cadastro de Funcionários e seus respectivos Armários
4º: Crio os Campos LookUp no CDSARMARIO_FUNCIONARIO:
Criação dos Fields NOME e TIPO
5º: Criação da Tela para adicionar armários no grid dos funcionários:
O click do botão faz o seguinte comando: FrmPrincipal.LocalizarLookup(DS1.DataSet, 'ARMARIO', 'IDARMARIO', 'DESCRICAO', 'Pesquisar Armário '); E a procedure LocalizarLookup tem o seguinte comando: procedure TFrmPrincipal.LocalizarLookup(xDSOrigem: TDataSet; xDescricaoLookup, xCodigo, xDescricao, xTituloPanel: String); begin Try FrmPesquisa := TFrmPesquisa.Create(Self); With FrmPesquisa do begin DSPesquisa.DataSet := xDSOrigem.FieldByName(xDescricaoLookup).LookupDataSet; Grid1.Columns[0].FieldName := xCodigo; Grid1.Columns[1].FieldName := xDescricao; xCampoPesquisa := xDescricao; Pnl1.Caption := xTituloPanel; ShowModal; if FrmPesquisa.ModalResult = mrOk then if xDSOrigem.State in [dsInsert,dsEdit] then xDSOrigem.FieldByName(xCodigo).AsString := DSPesquisa.DataSet.FieldByName(xCodigo).AsString; end; Finally FreeAndNil(FrmPesquisa); End; end; Como NOME e TIPO são campos lookup, eu vou buscar através da uma tela de pesquisa que me mostre todos os armários. Este seria um trabalho facilmente desenvolvido por uma dblookupcombobox, entretanto, este traria à memória todos os armários e o objetivo de buscar uma tela de pesquisa é justamente filtrar o que eu preciso. 6º: Características da Tela de Pesquisa
O click do botão tem o seguinte comando: With TClientDataSet(DSPesquisa.DataSet) do begin Close; Filtered := False; Filter := UpperCase(xCampoPesquisa + ' Like ' + QuotedStr('%' + EdtConteudo.Text + '%')); Filtered := True; Open; end; DSPesquisa.DataSet.First; 7º: O PROBLEMA > Já cadastrada a lista de armários, eu sigo o processo para cadastramento dos funcionários e seus respectivos armários. Da seguinte forma:
Aparecerá a seguinte tela:
Aparecerá a tela de Pesquisa de armários: Onde eu estarei pesquisando o armário de descrição ARM004 e clico na lupa para filtrar o dataset e me trazer a resposta somente do que preciso:
Dando um duplo clique no grid, tenho:
Clico em post , fecho a tela e terei os armários adicionados na grid, mas ao repetir o processo para o segundo e terceiro armário, observe que na grid somente o primeiro armário adicionado aparecem os dados, para o segundo e terceiro não:
Mas, se fechar e abrir o executável, os dados estão lá:
Galera, me ajudem com este problema aí! Estou tentando fazer o upload do código fonte do exemplo acima mas o site não está aceitando.
Att.
Rafael
Rafael Ribeiro
Curtidas 0
Respostas
Eriley Barbosa
24/09/2010
Quando você cria campos Lookup, você deve dizer para o ClientDataset, que estes campos não participam de nenhuma atualização, condição e não são chaves também.
Clicando sobre os campos – agora TFields – observe que no Object Inspector aparece em meio as demais a propriedade ProviderFlags. Ao expandi-la, nos aparece 4 opções:
PfInUpdate:
Define se o campo será atualizado
PfInWhere:
Define se o campo participará da cláusula WHERE
pfInKey:
Define se o campo faz parte da Chave Primária
PfInHidden:
Define se o campo será oculto para os clientes
No seu caso os campos nome e tipo devem ter todas as subpropriedades de providerflags False, já que não existem fisicamente no banco de dados.
GOSTEI 0
Rafael Ribeiro
24/09/2010
ERILEY, BOA TARDE!
EU COLOQUEI TUDO "FALSE" E O PROBLEMA CONTINUA. EU TENHO CERTEZA QUE ISSO TEM A VER COM OS FILTROS.
EU COLOQUEI TUDO "FALSE" E O PROBLEMA CONTINUA. EU TENHO CERTEZA QUE ISSO TEM A VER COM OS FILTROS.
GOSTEI 0
Eriley Barbosa
24/09/2010
Duas dicas, primeiro o DsPesquisa ta ligado ao clientdataset que tem os Lookup?
Porque se estiver ele ta ficando filtrado, dai não exibe mais de um registro mesmo, tem que após a inclusão passar o Filtered para false.
O dbgrid que não está atualizando, seu datasource tem que ta ligado ao mesmo datasource que faz a inclusão, senão dara estes problemas de atualização também.
Na hora que volta para a tela que tem o dbgrid após a inclusão, um Close e open devem ser suficientes para atualizar.
Bom revise estas duas coisas.
GOSTEI 0
Rafael Ribeiro
24/09/2010
ERILEY, BOA TARDE!
FOI COMO EU DISSE... EU SABIA QUE O PROBLEMA ERA O FILTRO. E COMO VOCÊ, TAMBÉM, DISSE OS DADOS FICAVAM FILTRADOS. EU APLIQUEI O CDS.FILTERED := FALSE EM VÁRIOS LUGARES E NUNCA DAVA CERTO. MAS, FINALMENTE, ENCONTREI O LOCAL CERTO. DEPOIS QUE EU CHAMO A FUNÇÃO LOCALIZAR LOOKUP, EU TIRO O FILTRO. AGORA SIM.... DEPOIS DE MESES DEU CERTO!
MUITO OBRIGADO!
FOI COMO EU DISSE... EU SABIA QUE O PROBLEMA ERA O FILTRO. E COMO VOCÊ, TAMBÉM, DISSE OS DADOS FICAVAM FILTRADOS. EU APLIQUEI O CDS.FILTERED := FALSE EM VÁRIOS LUGARES E NUNCA DAVA CERTO. MAS, FINALMENTE, ENCONTREI O LOCAL CERTO. DEPOIS QUE EU CHAMO A FUNÇÃO LOCALIZAR LOOKUP, EU TIRO O FILTRO. AGORA SIM.... DEPOIS DE MESES DEU CERTO!
MUITO OBRIGADO!
GOSTEI 0