Fórum Master Sources em relatório #384635

25/08/2010

0

Pessoal, estou precisando fazer um relatorio, que imagino que tenho que utilizar um master source, mas não estou conseguindo:As tabelas:Tenho tabelas de entrada e saida:Entrada produto Pai (Entrada_pai) com cód. data e cliente, esta relacionada com Tabela Entrada Produto (Entrada_produto) que contem a quantia.Da mesma forma Saida Pai com cód. data e cliente, relacionada com Saida Pai Produtos, onde estão os produtos.
Nesse caso, ja utilizo master source nas 2 tabelas entrada e nas 2 tabelas saida.
Bom agora, que não sei como fazer: No relatório tenho que colocar, tanto a entrada quanto a saida do produto. Ou seja, na data que tenha registro da entrada vai no relatorio, e na data com saida, também apareça no relatório.
Estou usando Quick report. com ADOtable e ADOquery.Ja tentei utilizar master source para isso, mas não consegui. Tentei com campo virtual, tb não consegui, pq ele registra apenas o 1º registro.
Não sei se fui claro, se alguem tiver alguma idéia, põe aeeeeeeeeeeeeeeeeeeee!!!valew
Maiquelnet

Maiquelnet

Responder

Posts

26/08/2010

Eriley Barbosa

Acho que não precisa Master Source, no seu ADOquery na propriedade SQL, coloque este código:   SELECT   'Entrada' "MOVIMENTO",    COD, DATA, CLIENTE FROM   ENTRADA_PRODUTO UNION ALL SELECT   'Saída' "MOVIMENTO",    COD, DATA, CLIENTE FROM   SAIDA_PRODUTO   Veja que você tem 2 selects unidos por um union all, se tiver alguma condição (Where, and) deve ser colocado para os dois selects.
Responder

Gostei + 0

26/08/2010

Maiquelnet


Acho que não precisa Master Source, no seu ADOquery na propriedade SQL, coloque este código:
SELECT
...
  SAIDA_PRODUTO
...
 

Bueno!!!Tentei como vc disse, mas axo que não dara certo. Primeiro deu o erro: Não foi encontrado o valor XXX na ADOQuery... o que achei estranho... e Segundo, utilizarei apenas 2 tabelas.
O código q usai foi mais ou menos isso:
ADOQuery.Close;ADOQuery.SQL.Clear;ADOQuery.SQL.Add('select codigo_entrada_med, Quantia_entrada from entrada_med union all');ADOQuery.SQL.Add('select cod_saida, Quantia_saida  from saida_med');ADOQuery.Open;QuickRep.Preview;

Da maneira que estava tentando era:
ADOQuery.Close;ADOQuery.SQL.Clear;ADOQuery.SQL.Add('select * from saida_pai, saida_med, entrada_pai, medicamento where');ADOQuery.SQL.Add('saida_pai.Cod_saida_pai=saida_med.cod_saida_filho_pai and');ADOQuery.SQL.Add('saida_med.medicamento=medicamento.cod_med and');ADOQuery.SQL.Add('saida_med.medicamento=:Texto0 and');ADOQuery.SQL.Add('saida_pai.Data_saida>=:Data1 and');ADOQuery.SQL.Add('saida_pai.Data_saida<=:Data2 order by saida_pai.Data_saida');ADOQuery.Parameters[0].Value:=DBEdit1.Text;ADOQuery.Parameters[1].value:=DateTimeToStr(DateTimePicker1.Date);ADOQuery.Parameters[2].Value:=DateTimeToStr(DateTimePicker2.Date);ADOQuery.Open;QuickRep.Preview;
Nesse caso estava usando 1 AdoQuery e 1 AdoTable, relacionados pelo Master Source, Field.
Mas o que pude perceber, é que usando o Union All, ele estaria trabalhando com 2 Tabelas, e precisaria Trabalhar com 4 Tabelas.
Para ser mais claro, coloquei uma print do modelo ER do banco com os dados que preciso grifados...


Oqe seria mais adequado? Apenas SQL na query, Master Source, ou teria alguma outra alternativa para isto?E agradeço a ajuda dos companheiros!!!!!Ateh...
Responder

Gostei + 0

01/09/2010

Pietro Braga

Olá amigo... que tipo de data é o campo saida_med.medicamento?

Se entendi bem, primeiro na consulta você diz que ele deve ser igual a um campo medicamento.cod_med, que suponho seja Integer em segudia informa que deve também ser igual ao a Var Texto0. Não virá daí o problema?

Desculpe se falei alguma besteira...
Responder

Gostei + 0

01/09/2010

Pietro Braga

Perdão, acho que entendi o que é o campo saida_med.medicamento. Ja tive problemas com consultas envolvendo datas no firebird, pois o separador das datas deveria ser um '.' . ele está gerando algum erro ou não retorna nenhum dado?

tente isso:


ADOQuery.Close;ADOQuery.SQL.Clear;ADOQuery.SQL.Add('select * from saida_pai, saida_med, entrada_pai, medicamento where');ADOQuery.SQL.Add('saida_pai.Cod_saida_pai=saida_med.cod_saida_filho_pai and');ADOQuery.SQL.Add('saida_med.medicamento=medicamento.cod_med and');ADOQuery.SQL.Add('saida_med.medicamento=:Texto0 and');ADOQuery.SQL.Add('saida_pai.Data_saida Between :Data1 and :Data2);
ADOQuery.Parameters[0].Value:=DBEdit1.Text;ADOQuery.Parameters[1].value:=DateTimeToStr(DateTimePicker1.Date);ADOQuery.Parameters[2].Value:=DateTimeToStr(DateTimePicker2.Date);ADOQuery.Open;QuickRep.Preview;
Fiz essa função para formatar a data.

function FormataData(Str:String): String; stdcall; export;
Var
x : Integer;
Begin
For x := 1 to Length(Str) do
if (Pos(Str[x],#47)<>0) or (Pos(Str[x],#45) <> 0) Then
Str[x]:= #46;
Result := Str;
end;


Responder

Gostei + 0

01/09/2010

Maiquelnet


Olá amigo... que tipo de data é o campo saida_med.medicamento?

Se entendi bem, primeiro na consulta você diz que ele deve ser igual a um campo medicamento.cod_med, que suponho seja Integer em segudia informa que deve também ser igual ao a Var Texto0. Não virá daí o problema?

Desculpe se falei alguma besteira...

 
 


buenoo campo saida_med.medicamento é integer mesmo...vc pensou certo mesmo... é que eu to procurando pelo código do medicamento, pois assim eu evito mais relacionamentos ou campos virtuais...
Responder

Gostei + 0

01/09/2010

Maiquelnet


Perdão, acho que entendi o que é o campo saida_med.medicamento. Ja tive problemas com consultas...
Result := Str;
end;

 
 

Mas o problema é que o caso não é erro de retorno, etcc.....eu consigo fazer este relatório utilizando apenas 2 tabelas... exemplo: a saida_pai com saida_medicamento...
só que quando tento com 4 tabelas complica... isso pq as datas ficam na tabela_pai, mas os dados dos medicamentos nas tabelas_filho, ou seja, tabela_med....
Dae eu preciso lista no relatório tanto a entrada do medicamento, quanto a saida do medicamento.
alguma coisa tipo.
MEDICAMENTO   ---------   DATA ENTRADA   -- QUANTIA ENTRADA   ---------   DATA SAIDA   --- QUANTIA SAIDAPropanolol                        01/02/2010            100                                           ------                   --------Propanolol                                                                                                     05/02/2010         20----------------------------------------Estoque = 80 comprimidos.
Ae preciso relacionar as 4 tabelas que postei acima... a questão de tipo das variaves ta tudo certo, oque me faltou mesmo foi bagage pra fazer esse relatório...e estou usando quick report... não sei se tem outra ferramenta mais adequada pra isso... ou se só pelo SQL eu consigo filtrar estes dados...um camarada acima, me citou sobre o 'UNION ALL', mas não consegui fazer... e imaginei que esse comando fosse pra apenas 2 tabelas...Sera que por data source , data field eu consigo?ou isso não é pra mim, mesmo? eheh
Responder

Gostei + 0

02/09/2010

Eriley Barbosa

Pelo que passou o que você quer é isso: MEDICAMENTO   ---------   DATA ENTRADA   -- QUANTIA ENTRADA   ---------   DATA SAIDA   --- QUANTIA SAIDA
Propanolol                        01/02/2010            100                                           ------                   --------
Propanolol                                                                                                     05/02/2010         20
----------------------------------------
Estoque = 80 comprimidos.
ADOQuery.Close;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add('SELECT');
ADOQuery.SQL.Add('  M.DESCRICAO MEDICAMENTO,');
ADOQuery.SQL.Add('  E.DATA_ENTRADA                   ,');
ADOQuery.SQL.Add('  EM.QUANTIA_ENTRADA          ,');
ADOQuery.SQL.Add('  S.DATA_SAIDA                       ,');
ADOQuery.SQL.Add('  SM.QUANTIA_SAIDA');
ADOQuery.SQL.Add('FROM');
ADOQuery.SQL.Add('  MEDICAMENTO M  ,');
ADOQuery.SQL.Add('  ENTRADA_PAI E    ,');
ADOQuery.SQL.Add('  ENTRADA_MED EM,');
ADOQuery.SQL.Add('  SAIDA_PAI S         ,');
ADOQuery.SQL.Add('  SAIDA_MED SM');
ADOQuery.SQL.Add('WHERE');
ADOQuery.SQL.Add('  S.COD_SAIDA_PAI           = SM.COD_SAIDA');
ADOQuery.SQL.Add('AND SM.MEDICAMENTO      = M.COD_MED');
ADOQuery.SQL.Add('AND E.COD_ENTRADA_PAI = EM.CODIGO_ENTRADA_MED');
ADOQuery.SQL.Add('AND EM.MEDICAMENTO      = M.COD_MED');
ADOQuery.SQL.Add('AND SM.MEDICAMENTO      =:Texto0');
ADOQuery.SQL.Add('AND S.DATA_SAIDA            >=:Data1');
ADOQuery.SQL.Add('AND S.DATA_SAIDA            <=:Data2');
ADOQuery.SQL.Add('ORDER BY S.DATA_SAIDA');
ADOQuery.Parameters[0].Value:=DBEdit1.Text;
ADOQuery.Parameters[1].value:=DateTimeToStr(DateTimePicker1.Date);
ADOQuery.Parameters[2].Value:=DateTimeToStr(DateTimePicker2.Date);
ADOQuery.Open;
QuickRep.Preview;   Só o totalizador que tem que ser feito no braço, mas vamos por partes, vamos fazer exibir dados no relatório e depois fazemos o totalizador.   Leia meu artigo, pode ser de seu interesse, ou repasse a outras pessoas:   https://www.devmedia.com.br/post-17935-Criando-uma-barra-de-ferramentas-para-aplicacoes-MDI-com-as-operacoes-de-navegacao-incluir-excluir-salvar-e-cancelar.html  

Acho que não precisa Master Source, no seu ADOquery na propriedade SQL, coloque este código:
SELECT
...
  SAIDA_PRODUTO
...
 

Bueno!!! Tentei como vc disse, mas axo que não dara certo. Primeiro deu o erro: Não foi encontrado o valor XXX na ADOQuery... o que achei estranho... e Segundo, utilizarei apenas 2 tabelas.
O código q usai foi mais ou menos isso:

ADOQuery.Close;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add('select codigo_entrada_med, Quantia_entrada from entrada_med union all');
ADOQuery.SQL.Add('select cod_saida, Quantia_saida  from saida_med');
ADOQuery.Open;
QuickRep.Preview;

Da maneira que estava tentando era:

ADOQuery.Close;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add('select * from saida_pai, saida_med, entrada_pai, medicamento where');
ADOQuery.SQL.Add('saida_pai.Cod_saida_pai=saida_med.cod_saida_filho_pai and');
ADOQuery.SQL.Add('saida_med.medicamento=medicamento.cod_med and');
ADOQuery.SQL.Add('saida_med.medicamento=:Texto0 and');
ADOQuery.SQL.Add('saida_pai.Data_saida>=:Data1 and');
ADOQuery.SQL.Add('saida_pai.Data_saida<=:Data2 order by saida_pai.Data_saida');
ADOQuery.Parameters[0].Value:=DBEdit1.Text;
ADOQuery.Parameters[1].value:=DateTimeToStr(DateTimePicker1.Date);
ADOQuery.Parameters[2].Value:=DateTimeToStr(DateTimePicker2.Date);
ADOQuery.Open;
QuickRep.Preview;
Nesse caso estava usando 1 AdoQuery e 1 AdoTable, relacionados pelo Master Source, Field.
Mas o que pude perceber, é que usando o Union All, ele estaria trabalhando com 2 Tabelas, e precisaria Trabalhar com 4 Tabelas.
Para ser mais claro, coloquei uma print do modelo ER do banco com os dados que preciso grifados...


Oqe seria mais adequado? Apenas SQL na query, Master Source, ou teria alguma outra alternativa para isto? E agradeço a ajuda dos companheiros!!!!! Ateh...
Responder

Gostei + 0

02/09/2010

Maiquelnet


 

eriley, tentei o seu código...não esta dando erro, mas também não esta apresentando resultados...fiz algumas modificações:
ADOQuery.Close;ADOQuery.SQL.Clear;ADOQuery.SQL.Add('SELECT    MEDICAMENTO.cod_med, SAIDA_PAI.Data_saida, SAIDA_MED.medicamento, SAIDA_MED.quantia_saida,');ADOQuery.SQL.Add('                ENTRADA_PAI.Data_entrada, ENTRADA_MED.Medicamento, ENTRADA_MED.Quantia_entrada,');ADOQuery.SQL.Add('                SAIDA_PAI.Cod_saida_pai, SAIDA_MED.cod_saida, ENTRADA_PAI.Cod_entra_pai, ENTRADA_MED.codigo_entrada_med');
ADOQuery.SQL.Add('FROM        SAIDA_PAI, SAIDA_MED, ENTRADA_PAI, ENTRADA_MED, MEDICAMENTO');
ADOQuery.SQL.Add('WHERE     SAIDA_PAI.Cod_saida_pai=SAIDA_MED.cod_saida_filho_pai');ADOQuery.SQL.Add('AND          ENTRADA_PAI.Cod_entra_pai=ENTRADA_MED.codigo_entrada_med');ADOQuery.SQL.Add('AND          MEDICAMENTO.cod_med=saida_med.medicamento');ADOQuery.SQL.Add('AND          MEDICAMENTO.cod_med=entrada_med.medicamento');ADOQuery.SQL.Add('AND          MEDICAMENTO.cod_med=:Texto0');ADOQuery.SQL.Add('AND          SAIDA_PAI.Data_saida>=:Data1');ADOQuery.SQL.Add('AND          SAIDA_PAI.Data_saida<=:Data2');ADOQuery.SQL.Add('ORDER BY SAIDA_PAI.data_saida');
ADOQuery.Parameters[0].Value:=DBEdit1.Text;ADOQuery.Parameters[1].value:=DateTimeToStr(DateTimePicker1.Date);ADOQuery.Parameters[2].Value:=DateTimeToStr(DateTimePicker2.Date);ADOQuery.Open;QuickRep.Preview;

Então... inicialmente ele seleciona os campos em questão... depois ele faz os relacionamentos e por fim filtra pelo código do medicamento e pelas datas...
Desta forma o relatório sai em branco, como se nenhum valor foi aceito pelas condições... só q os valores estão cadastrados, Então fiz o teste de tirar a linha abaixo:
ADOQuery.SQL.Add('AND          ENTRADA_PAI.Cod_entra_pai=ENTRADA_MED.codigo_entrada_med');

E desta forma ele lista todas as saidas de medicamentos... um pouco duplicado, mas apresenta os resultados...nesta condição cheguei na seguinte dúvida:
Será que nenhum valor passou no código, por causa das data de entrada e data saida???Ou seja, só se a data de entrada e saida for igual, não sendo ele não aprenseta??
sempre com esse problema de usar 4 ou 5 tabelas, como neste caso!!!!

Responder

Gostei + 0

03/09/2010

Eriley Barbosa

Para mim o problema está nestas duas linhas: ADOQuery.SQL.Add('AND          SAIDA_PAI.Data_saida>=:Data1'); ADOQuery.SQL.Add('AND          SAIDA_PAI.Data_saida<=:Data2');   Pois para ser apresentado o medicamento ele tem que ter saído no período, se ele tiver entrado não vai aparecer, póis, você procura pela saída.   Já se você fizer o contrario procurar pela entrada: ADOQuery.SQL.Add('AND          ENTRADA_PAI.Data_entrada>=:Data1'); ADOQuery.SQL.Add('AND          ENTRADA_PAI.Data_entrada<=:Data2');   Serão listados os medicamentos que tiverão entrada e a data de saida será preenchida somente se tiver saído o medicamento.   O certo seria você ter 3 querys no seu relatório: Uma listando os medicamentos, outra listando as entradas e outra listando as saídas, dai no relatório, você faria assim: 1 banda Detail para listar os medicamentos; 1 banda childband para listar as entradas; 1 banda childband para listar as saídas
Responder

Gostei + 0

03/09/2010

Eriley Barbosa

Ah, esqueci, não retire aquela linha, pois, talvez sem ela os registros estejam sendo duplicados, tente faser um left join naquela linha.
Responder

Gostei + 0

04/09/2010

Maiquelnet



O certo seria você ter 3 querys no seu relatório:
Uma listando os medicamentos, outra listando as entradas e outra listando as saídas, dai no relatório, você faria assim:
1 banda Detail para listar os medicamentos;
1 banda childband para listar as entradas;
1 banda childband para listar as saídas
 

Ok, estou tentando fazer aki como vc me passou, só q estou com umas dúvidas:
Primeiro mudei o relatório, coloquei:1 Banda detail ligada a medicamento (Dataset: AdoQuery1);
1 childband para as entradas, (LinkBand: BandDetail1)  e os QRDBText ligados ao AdoQuery2) entrada_pai e entrada_med.
1 childband para as saidas. (LinkBand: BandDetail1)  e os QRDBText ligados ao AdoQuery3) saida_pai e saida_med.
O quick report o DataSet esta no AdoQuery1, que é medicamentos. Sera q esta certo??????????????????
Primeiro tentei fazer um teste só para ver. Mas no código coloquei apenas: Aki não sabia como fazer!!!!!
ADOQuery1.SQL.Add('select cod_med from medicamento');ADOQuery1.SQL.Add('where cod_med=:Texto0');
ADOQuery2.SQL.Add('select * from entrada_pai, entrada_med');
ADOQuery3.SQL.Add('select * from saida_pai, saida_med');
ADOQuery1.Parameters[0].Value:=DBEdit1.Text;QuickRep1.Preview;


fiz um teste, até porque nunca tinha usado mais querys em um mesmo relatório!!!Mas não apareceu nada no relatório.Tudo em branco!!!
Responder

Gostei + 0

04/09/2010

Eriley Barbosa

O linkband da childband2 tem que apontar para childband1. Adoquery2 e AdoQuery3, tem que receber por parametro o codigo do medicamento da Adoquery1 e as datas de entrada e saida, senão não tem sentido o relatório. Na Adoquery1 ta faltando o nome do medicamento. Faça isso no beforeprint da childband1 e da childband2 ou no afterscroll da adoquery1. No código que passou não tem o open das querys antes do preview.

ADOQuery1.SQL.Add('select cod_med from medicamento');
ADOQuery1.SQL.Add('where cod_med=:Texto0');


ADOQuery2.SQL.Add('select * from entrada_pai, entrada_med');


ADOQuery3.SQL.Add('select * from saida_pai, saida_med');


ADOQuery1.Parameters[0].Value:=DBEdit1.Text;
QuickRep1.Preview;
Cade o Adoquery1.open, Adoquery2.open e Adoquery3.open? Por isso seu relatório saiu em branco. Faça as alterações que passei e retorne se houver algum erro.
Responder

Gostei + 0

06/09/2010

Maiquelnet

O linkband da childband2 tem que apontar para childband1....
Faça as alterações que passei e retorne se houver algum erro.
 

tentei inúmeras vezes, com várias e várias alterações... mas nenhuma foi bem sucedida...Primeiro: fiz com 1 detail e 2 childs... usando 3 querys!!! Utilizando os códigos acima... corrigidos!!O resultado saia apenas o Detail... e nada nos childs.
Então, mudei... coloquei na query1 já o filtro que eu utilizaria na query2, ou seja, 
ADOQuery1.Close;ADOQuery1.SQL.Clear;ADOQuery1.SQL.Add('select * from entrada_pai, entrada_med, medicamento');ADOQuery1.SQL.Add('where entrada_pai.cod_entra_pai=entrada_med.codigo_entrada_med');ADOQuery1.SQL.Add('and medicamento.cod_med=entrada_med.medicamento');ADOQuery1.SQL.Add('and  medicamento.cod_med=:Texto0');ADOQuery1.Parameters[0].Value:=DBEdit1.Text;ADOQuery1.Open;QuickRep.Preview;

No QR utilizei 1 Detail e 1 ChildBand... Os dados da Childband não apareciam... mas o Detail sim, ou seja, se tivessem 4 registros na childband... o Detail aparecia 4 vezes, só os dados da child não apresentavam!!! Sendo que linkei a child ao detail...
Então mudei!!! Coloquei um QRGroup Footer e 1 Detail... Utilizando o mesmo código acima...Assim funcionou... No Groupfooter o nome do medicamento, e no Detail as datas e as quantidade entrada...  Assim funciona! Mas é como se fosse um relatório de entrada de medicamentos!!!
Mas ainda faltava as saidas!!!!!Dae sim... tentei de inúmeras vezes, sem sucesso!!!!Utilizando 2 querys...a 1ª query selecionava as entradas... a 2ª as saidas!! A 1ª query (DetailBand) linkada no Group e a 2ª Query (ChildBand) linkada na (DetailBand)
ADOQuery1.Close;ADOQuery1.SQL.Clear;ADOQuery1.SQL.Add('select * from entrada_pai, entrada_med, medicamento');ADOQuery1.SQL.Add('where entrada_pai.cod_entra_pai=entrada_med.codigo_entrada_med');ADOQuery1.SQL.Add('and medicamento.cod_med=entrada_med.medicamento');ADOQuery1.SQL.Add('and  medicamento.cod_med=:Texto0');  
ADOQuery2.Close;ADOQuery2.SQL.Clear;ADOQuery2.SQL.Add('select * from saida_pai, saida_med, medicamento');ADOQuery2.SQL.Add('where saida_pai.Cod_saida_pai=saida_med.cod_saida_filho_pai');ADOQuery2.SQL.Add('and medicamento.cod_med=saida_med.medicamento');ADOQuery2.SQL.Add('and  medicamento.cod_med=:Texto0');
ADOQuery1.Parameters[0].Value:=DBEdit1.Text;ADOQuery2.Parameters[0].Value:=DBEdit1.Text;ADOQuery1.Open;ADOQuery2.Open;
QuickRep.Preview;

Tambem fiz outros testes: linkar as 2 childsband na group... tb 2 childs na detail... A child1 no detail e a chil2 na child 1... A child1 no group e child2 no child1...Quando se usava o agrupamento pelo BandDetail ele lista apenas o Detail e nada nos childs! Como descrevi no início...Quando usava agrupamento pelo Group ele apresentava apenas 1 registro... Acho que o primeiro só!!!
Como não estava conseguindo... pensei em fazer apenas 1 Query com uma consulta aninhada!!!Filtrava as entradas e depois as aninhava as saidas na mesma query... só que dae essa query vai trabalhar com 5 tabelas... imagino que vai ficar bastante pesado!!!!!alguma idéia?
Responder

Gostei + 0

07/09/2010

Eriley Barbosa

A group só exibe um registro por vez, a childband exibe 1 registro para cada detalhe e não uma lista, como a detail. Tem que tentar fazer funcionar com aquele select que te passei, aquele que você tirou uma linha para fazer funcionar, lembra,? Tente fazer os relacionamentos com Left Join, de uma pesquisada na internet por left join no sql, eu poderia fazer isso para você, mas teria de ter suas 5 tabelas para fazer isso. Você teria de me passar o script com a criação das tabelas e o insert dos dados. Você ta usando Access ou SQL Server? Se estiver usando sql server podemos fazer com stored procedure, com tabela temporaria.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar