Exibir Campos Concatenados em uma Grid
Olá, gostaria de saber se alguem pode me ajudar com a dúvida abaixo. Espero que sim.
Tenho uma aplicação em Delphi + Firebird, usando como conexão SqlDataSet, DataSetProvider, ClientDataSet e DataSource. O que eu quero é exibir dois campos, string, em um campo da grid. Pra tentar fazer essa exibição eu criei o campo TITULO_AGRUPADO do tipo calculado, string no ClientDataSet. Depois criei uma coluna na grid e selecionei esse campo no FieldName. E fiz a consulta abaixo pra agrupar os dois campos no firebird:
Quando rodo a aplicação, não aparece nenhum erro, executa normal, mas o campo TITULO_AGURADO da grid aparece vazio. Alguém sabe o motivo disso? Falta algo pra exibir esse campo?
Desde já agradeço a ajuda.
Tenho uma aplicação em Delphi + Firebird, usando como conexão SqlDataSet, DataSetProvider, ClientDataSet e DataSource. O que eu quero é exibir dois campos, string, em um campo da grid. Pra tentar fazer essa exibição eu criei o campo TITULO_AGRUPADO do tipo calculado, string no ClientDataSet. Depois criei uma coluna na grid e selecionei esse campo no FieldName. E fiz a consulta abaixo pra agrupar os dois campos no firebird:
DmDados.ClientTitulosNacionais.Close;
With DmDados.SqlTitulosNacionais do
begin
close;
CommandText :=
Select PKCOD_TITULO_NACIONAL, FKCOD_EDITORA_ORIGINAL, FKCOD_EDITORA_NACIONAL, FKCOD_TIPO_PUBLICACAO,
+ NOME_TITULO_NACIONAL, NOME_SERIE_TITULO_NACIONAL, SERIE_TITULO_NACIONAL, SITUACAO_TITULO_NACIONAL,
+ PERIODO_PUBLICACAO, NUMERO_TOTAL_EDICOES, COMENTARIO_TITULO, DATA_HORA_CADASTRO,
+ (NOME_TITULO_NACIONAL || SERIE_TITULO_NACIONAL) as TITULO_AGRUPADO From TB_TITULOS_NACIONAIS
+ Order by NOME_TITULO_NACIONAL;
open;
end;
DmDados.ClientTitulosNacionais.Open;
Quando rodo a aplicação, não aparece nenhum erro, executa normal, mas o campo TITULO_AGURADO da grid aparece vazio. Alguém sabe o motivo disso? Falta algo pra exibir esse campo?
Desde já agradeço a ajuda.
Allan Ramos
Curtidas 0
Respostas
Allan Ramos
13/02/2012
DmDados.ClientTitulosNacionais.Close;
With DmDados.SqlTitulosNacionais do
begin
close;
CommandText :=
Select PKCOD_TITULO_NACIONAL, FKCOD_EDITORA_ORIGINAL, FKCOD_EDITORA_NACIONAL, FKCOD_TIPO_PUBLICACAO,
+ NOME_TITULO_NACIONAL, NOME_SERIE_TITULO_NACIONAL, SERIE_TITULO_NACIONAL, SITUACAO_TITULO_NACIONAL,
+ PERIODO_PUBLICACAO, NUMERO_TOTAL_EDICOES, COMENTARIO_TITULO, DATA_HORA_CADASTRO,
+ (NOME_TITULO_NACIONAL || SERIE_TITULO_NACIONAL) as TITULO_AGRUPADO From TB_TITULOS_NACIONAIS
+ Order by NOME_TITULO_NACIONAL;
open;
end;
DmDados.ClientTitulosNacionais.Open;
With DmDados.SqlTitulosNacionais do
begin
close;
CommandText :=
Select PKCOD_TITULO_NACIONAL, FKCOD_EDITORA_ORIGINAL, FKCOD_EDITORA_NACIONAL, FKCOD_TIPO_PUBLICACAO,
+ NOME_TITULO_NACIONAL, NOME_SERIE_TITULO_NACIONAL, SERIE_TITULO_NACIONAL, SITUACAO_TITULO_NACIONAL,
+ PERIODO_PUBLICACAO, NUMERO_TOTAL_EDICOES, COMENTARIO_TITULO, DATA_HORA_CADASTRO,
+ (NOME_TITULO_NACIONAL || SERIE_TITULO_NACIONAL) as TITULO_AGRUPADO From TB_TITULOS_NACIONAIS
+ Order by NOME_TITULO_NACIONAL;
open;
end;
DmDados.ClientTitulosNacionais.Open;
GOSTEI 0
Allan Ramos
13/02/2012
Postei novamente o código acima pois ficou ruim de ver no primeiro post.
GOSTEI 0
Marco Salles
13/02/2012
e o que voce coloca no evento do campo calculado ??
GOSTEI 0
Allan Ramos
13/02/2012
e o que voce coloca no evento do campo calculado ??
Nada. Pra ser sincero, procurando pela internet eu achei que era só criar o campo calculado e informar o nome dele no as TITULO_AGRUPADO. Não usei nenhum evento, a pesquisa acima é disparada no formulário que tem a grid, pra exibição dos dados.
GOSTEI 0
Gustavo Bretas
13/02/2012
Allan, provavelmente um dos campos esta NULL, então tente usar COALESCE, por exemplo:
(COALESCE(NOME_TITULO_NACIONAL, ) || COALESCE(SERIE_TITULO_NACIONAL, )) as TITULO_AGRUPADO
No segundo parâmetro do COALESCE vc pode colocar um texto fixo ou até mesmo outro campo!
Verifica se é isso!
Abraço!
(COALESCE(NOME_TITULO_NACIONAL, ) || COALESCE(SERIE_TITULO_NACIONAL, )) as TITULO_AGRUPADO
No segundo parâmetro do COALESCE vc pode colocar um texto fixo ou até mesmo outro campo!
Verifica se é isso!
Abraço!
GOSTEI 0
Allan Ramos
13/02/2012
Olá Bretas, boa tarde.
Realmente, um dos campos, o SERIE_TITULO_NACIONAL pode ser nulo, não é obrigatório. O primeiro campo é obrigatório. Só pra explicar,
pode ser cadastrado um título e eu não selecionar nenhuma série, aí mostraria Título A. Ou eu posso ter mais de um título com o mesmo nome,
aí seleciono a série e aparece Título A (1ª Série), Título A (2ª Série), e assim por diante. Eu fiz uma solução paliativa, que é juntar os
campos e salvar numa coluna da tabela NOME_SERIE_TITULO_NACIONAL, mas usando a concatenação não precisaria desse campo, poupando espaçõ no bd.
Tentei fazer como tu sugeriu assim:
NOME_TITULO_NACIONAL || COALESCE(SERIE_TITULO_NACIONAL, ) As TITULO_AGRUPADO From TB_TITULOS_NACIONAIS
Ou mesmo tirando a vírgula, ficando:
COALESCE(SERIE_TITULO_NACIONAL)
Mas sempre que entro no form pra listar assim, aparece o erro:
Project Proj.exe raised exception class TDBXError with message Token unknown -line 1, column 338 ).
Pelo que entendi, lendo sobre o COALESCE agora, ele procura o primeiro campo não nulo indicado. Tentei botar também:
COALESCE(SERIE_TITULO_NACIONAL, NOME_TITULO_NACIONAL)
Só pra fazer um teste, e aí não da erro, mas mesmo assim não lista nada no campo TITULO_AGURPADO.
Realmente, um dos campos, o SERIE_TITULO_NACIONAL pode ser nulo, não é obrigatório. O primeiro campo é obrigatório. Só pra explicar,
pode ser cadastrado um título e eu não selecionar nenhuma série, aí mostraria Título A. Ou eu posso ter mais de um título com o mesmo nome,
aí seleciono a série e aparece Título A (1ª Série), Título A (2ª Série), e assim por diante. Eu fiz uma solução paliativa, que é juntar os
campos e salvar numa coluna da tabela NOME_SERIE_TITULO_NACIONAL, mas usando a concatenação não precisaria desse campo, poupando espaçõ no bd.
Tentei fazer como tu sugeriu assim:
NOME_TITULO_NACIONAL || COALESCE(SERIE_TITULO_NACIONAL, ) As TITULO_AGRUPADO From TB_TITULOS_NACIONAIS
Ou mesmo tirando a vírgula, ficando:
COALESCE(SERIE_TITULO_NACIONAL)
Mas sempre que entro no form pra listar assim, aparece o erro:
Project Proj.exe raised exception class TDBXError with message Token unknown -line 1, column 338 ).
Pelo que entendi, lendo sobre o COALESCE agora, ele procura o primeiro campo não nulo indicado. Tentei botar também:
COALESCE(SERIE_TITULO_NACIONAL, NOME_TITULO_NACIONAL)
Só pra fazer um teste, e aí não da erro, mas mesmo assim não lista nada no campo TITULO_AGURPADO.
GOSTEI 0
Marco Salles
13/02/2012
Mas para que Sql , se os dados estão na memória do cleintdataset ?
So utilizar o Internalcalc não ?
So utilizar o Internalcalc não ?
GOSTEI 0
Gustavo Bretas
13/02/2012
Allan, o COALESCE é composto de dois parâmetros, quando o primeiro é nulo ele adiciona o segundo, se o segundo tbm for nulo vc pode colocar dentro de outro COALESCE, entende? não apareceu nada depois da virgula no post por que o fórum elimina as aspas simples, entende?
Faz do jeito que eu postei, mas coloque vazio depois da virgula!
Faz do jeito que eu postei, mas coloque vazio depois da virgula!
GOSTEI 0
Allan Ramos
13/02/2012
Opa, quero agradecer vocês pela ajuda. Não sei porque o Coalesce não funcionou comigo, mas a dica do InternalCalc funcionou perfeitamente. Fiz assim:
Criei um campo no ClientDataSet com o nome de TITULO_AGRUPADO, do tipo InternalCalc e no evento OnCalcFields botei:
var
Serie :String;
begin
if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 0 then
Serie :=
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 1 then
Serie := (1ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 2 then
Serie := (2ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 3 then
Serie := (3ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 4 then
Serie := (4ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 5 then
Serie := (5ª Série);
ClientTitulosNacionais.FieldByName(TITULO_SERIE_AGRUPADO).AsString :=
ClientTitulosNacionais.FieldByName(NOME_TITULO_NACIONAL).AsString + Serie;
end;
Assim funcionou da maneira que eu queria. Obrigado pela ajuda. Abraços.
Criei um campo no ClientDataSet com o nome de TITULO_AGRUPADO, do tipo InternalCalc e no evento OnCalcFields botei:
var
Serie :String;
begin
if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 0 then
Serie :=
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 1 then
Serie := (1ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 2 then
Serie := (2ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 3 then
Serie := (3ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 4 then
Serie := (4ª Série)
else if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 5 then
Serie := (5ª Série);
ClientTitulosNacionais.FieldByName(TITULO_SERIE_AGRUPADO).AsString :=
ClientTitulosNacionais.FieldByName(NOME_TITULO_NACIONAL).AsString + Serie;
end;
Assim funcionou da maneira que eu queria. Obrigado pela ajuda. Abraços.
GOSTEI 0
Allan Ramos
13/02/2012
Olá, deixa eu aproveitar que não consegui finalizar esse post e já tirar uma outra dúvida, já que ainda sou meio verde nesse InternalCalc que usei.
Com o outro sistema, que eu salvava já o campo concatenado num campo do bd, eu listava ele em ordem alfabetica e funcionava tranquilo. Se eu tivesse o código 1 como Titulo (2ª Série) e o código 2 como Título (1ª Série), ele listava o 1ª série, depois o 2ª série, normal.
Mas agora notei que em alguns casos ele na ordem certa, mas na maioria dos casos ele lista de acordo com o código cadastrado, o mais baixo primeiro. No SqlDataSet já uso o CommandText como:
Select * From Tabela Order By Nome_Titulo, Serie_Titulo. (Não uso o *, só botei de exemplo) e quando entro no form ainda jogo esse mesmo sql pro SqlDataSet, mas mesmo assim continua listando só alguns casos corretos.
Acredito que esse Sql não faça muito efeito usando o InternalCalc, mas tem algo que consigo fazer? Só corrigindo uma informação que passei errada acima, o campo serie_nacional não fica nulo, é do tipo smallint e quando não tem nada eu jogo um 0 nele.
Grato pela ajuda e paciencia. ;)
Com o outro sistema, que eu salvava já o campo concatenado num campo do bd, eu listava ele em ordem alfabetica e funcionava tranquilo. Se eu tivesse o código 1 como Titulo (2ª Série) e o código 2 como Título (1ª Série), ele listava o 1ª série, depois o 2ª série, normal.
Mas agora notei que em alguns casos ele na ordem certa, mas na maioria dos casos ele lista de acordo com o código cadastrado, o mais baixo primeiro. No SqlDataSet já uso o CommandText como:
Select * From Tabela Order By Nome_Titulo, Serie_Titulo. (Não uso o *, só botei de exemplo) e quando entro no form ainda jogo esse mesmo sql pro SqlDataSet, mas mesmo assim continua listando só alguns casos corretos.
Acredito que esse Sql não faça muito efeito usando o InternalCalc, mas tem algo que consigo fazer? Só corrigindo uma informação que passei errada acima, o campo serie_nacional não fica nulo, é do tipo smallint e quando não tem nada eu jogo um 0 nele.
Grato pela ajuda e paciencia. ;)
GOSTEI 0
Allan Ramos
13/02/2012
Só complementando, uma coisa que achei estranha, é que o código sql pra concatenação funcional. Joguei ele no IbExpert e me retornou exatamente o que eu quero, com os campos juntos em ordem de nome. O problema que estou encontrando é que esses dados não são exibidos na Grid do Delphi. Não da nenhum erro, mas as linhas da grid ficam vazias.
Eu tentei criar o campo calculado no SqlDataSet, depois adcionar ele no Client DataSet e exibir como coluna na Grid, passando a concatenação desde o SqlDataSet, mas o sistema roda e na Grid não aparece nada.
Eu tentei criar o campo calculado no SqlDataSet, depois adcionar ele no Client DataSet e exibir como coluna na Grid, passando a concatenação desde o SqlDataSet, mas o sistema roda e na Grid não aparece nada.
GOSTEI 0
Joel Rodrigues
13/02/2012
Opa, deixa só eu me meter aqui no final. Allan, só otimizando(enxugando) o código, você poderia economizar algumas linhas fazendo:
---
Serie := ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString + ª Série;
if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 0 then
Serie :=
else
Serie := ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString + ª Série;
---
Nada demais, só uma pequena observção.
---
Serie := ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString + ª Série;
if ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString = 0 then
Serie :=
else
Serie := ClientTitulosNacionais.FieldByName(SERIE_TITULO_NACIONAL).AsString + ª Série;
---
Nada demais, só uma pequena observção.
GOSTEI 0
Deivison Melo
13/02/2012
Boa tarde,
Porquê vc não efetua a concatenação no sql e dá um alias a esse campo, feito isso vc enxergara ele no grid já concatenado!
Porquê vc não efetua a concatenação no sql e dá um alias a esse campo, feito isso vc enxergara ele no grid já concatenado!
GOSTEI 0
Allan Ramos
13/02/2012
Valeu Joel, vou seguir tua dica.
Deivison, eu tentei fazer isso. Eu tenho o sql concatenado pronto e funcionando (testei pelo ibexpert), aí joguei ele no sqldataset e criei um campo calculado do tipo string chamado TITULO_AGRUPADO e adicionei esse campo também no ClientDataSet. É esse campo que to ligando na grid, e la no sql eu concateno usando AS TITULO_AGRUPADO... Ou seja, funciona o sql, mas a grid não mostra os campos, fica em branco quando adiciono esse campo. Os outros campos mostra normal.
Não sei se to criando esse campo de maneira errada.
Deivison, eu tentei fazer isso. Eu tenho o sql concatenado pronto e funcionando (testei pelo ibexpert), aí joguei ele no sqldataset e criei um campo calculado do tipo string chamado TITULO_AGRUPADO e adicionei esse campo também no ClientDataSet. É esse campo que to ligando na grid, e la no sql eu concateno usando AS TITULO_AGRUPADO... Ou seja, funciona o sql, mas a grid não mostra os campos, fica em branco quando adiciono esse campo. Os outros campos mostra normal.
Não sei se to criando esse campo de maneira errada.
GOSTEI 0
Joel Rodrigues
13/02/2012
Se você trouxer o campo já concatenado do banco, não precisará de um CalcField, será um campo como os outros.
GOSTEI 0
Allan Ramos
13/02/2012
Pois eu ja tentei até criar um campo no banco de dados pra concatenar, mas também não deu. Antes eu tinha um campo varchar que eu concatenava no post, e ele salvava os dois campos, mas aí é um campo a mais no banco que não precisaria. Eu estou muito encucado com essa grid que não exibe hehe.
GOSTEI 0
Joel Rodrigues
13/02/2012
Tente depurar e veja se o campo correspondente (trazendo direto do banco, não usando um CalcField) está com o valor correto, mesmo não exibindo no grid. E o grid, é um DBGrid convencional?
GOSTEI 0
Allan Ramos
13/02/2012
Vou continuar tentando achar esse erro, mas por enquanto o campo calculado funcionou e eu achei o erro da listagem, ele listava em ordem num select mas entrava em outro e desordenava, ja corrigi isso e ta funcionando perfeito agora. Agradeço a ajuda pessoal, foi de grande valia. Muito obrigado.
Ps. Mão consigo botar o tópico como concluido, da erro quando entro no status.
Ps. Mão consigo botar o tópico como concluido, da erro quando entro no status.
GOSTEI 0
Marco Salles
13/02/2012
O Allan , vou colocar o tópico concluido . ja que o Internalcalc resolveu o seu problema
sobre esta outra sitação , caso queira abra um novo chamado com esta nova dúvida . Ok
sobre esta outra sitação , caso queira abra um novo chamado com esta nova dúvida . Ok
GOSTEI 0