PROBLEMAS NO CRYSTAL REPORT
Ola senhores! Bom Dia! - Já cansei (estou há duas semanas pesquisando e não consegui nada!) e estou pedindo ajuda: O cenário: Um relatorio em Crystal, VB.NET no VS2010. é um relatorio que tem tres datatable. Um com dados de cliente outro com dados de um aparelho enviado para conserto e outro com as eventuais pecas usadas no conserto deste aparelho. Pois bem, devo imprimir o relatorio onde constarão os dados do cliente e do aparelho e - ai vem o problema - as peças porventura usadas.
Bom, quado há peças, nenhum problema. o relatorio sai perfeito. Agora quando não há peças o relatorio é impresso sem nenhum dado! Nem do cliente nem do aparelho!.
Percebi que quando o datatable das pecas retorna vazio o Crystal nao imprime nada...
Como contornar esse problema? Já tentei de tudo: checar se ha pecas e se nao ha colocar no dataset um registro ficticio informando [Ô]nao há peças[Ô] e refazendo o Fill mas nao funcionou... e por ai vai... já fiz coisas que nem me lembro... Alguma sugestão? Tem algum [Ô]pulo-do-gato[Ô] que desconheço? Obrigado de antemão pela possÃvel ajuda.
Segue o codigo que carrega o relatorio:
Private Sub ImprimeRetGarantia(ByVal IDORC As Integer, ByVal IDCLI As Integer)
Dim stringConexao As String = My.Settings.Caminho.ToString
Dim conn As New OleDbConnection(stringConexao)
[ô]MsgBox([Ô]Orçamento nro [Ô] & IDORC & [Ô] impresso![Ô])
Dim daCliente As New OleDbDataAdapter([Ô]Select * from Clientes Where ID_CLI = [Ô] & IDCLI, conn)
Dim daOrcam As New OleDbDataAdapter([Ô]Select * from Orcamentos Where ID_ORC = [Ô] & IDORC, conn)
Dim daPecasOrc As New OleDbDataAdapter([Ô]SELECT * FROM PECASORC WHERE IDORC= [Ô] & IDORC, conn)
Dim dsRelatorio As New dsEntrGar
conn.Open()
daCliente.Fill(dsRelatorio.CLIENTES)
daOrcam.Fill(dsRelatorio.ORCAMENTOS)
daPecasOrc.Fill(dsRelatorio.PECASORC)
conn.Close()
If dsRelatorio.PECASORC.Count = 0 Then
Dim rowNew As DataRow
rowNew = dsRelatorio.Tables(2).NewRow
rowNew([Ô]CODPRODU[Ô]) = [Ô]Sem peças![Ô]
dsRelatorio.Tables(2).Rows.Add(rowNew)
dsRelatorio.AcceptChanges()
daPecasOrc.Fill(dsRelatorio.PECASORC)
End If
Dim relatorio As New crEntrGar
CrystalDecisions.
Dim parametros As New CrystalDecisions.Shared.ParameterFields
Dim parametro1 As New CrystalDecisions.Shared.ParameterField
Dim dis_param1 As New CrystalDecisions.Shared.ParameterDiscreteValue
Dim parametro2 As New CrystalDecisions.Shared.ParameterField
Dim dis_param2 As New CrystalDecisions.Shared.ParameterDiscreteValue
parametro1.ParameterFieldName = [Ô]enderloja[Ô]
dis_param1.Value = EMPRESA
parametro1.CurrentValues.Add(dis_param1)
parametros.Add(parametro1)
parametro2.ParameterFieldName = [Ô]Garantia[Ô]
dis_param2.Value = [Ô]ORÇAMENTO NRO. [Ô] & IDORC & [Ô] EM GARANTIA[Ô]
parametro2.CurrentValues.Add(dis_param2)
parametros.Add(parametro2)
relatorio.SetDataSource(dsRelatorio)
Dim f As New frmRelatorio(relatorio)
f.crvRelatorio.ParameterFieldInfo = parametros
f.Show()
End Sub
Bom, quado há peças, nenhum problema. o relatorio sai perfeito. Agora quando não há peças o relatorio é impresso sem nenhum dado! Nem do cliente nem do aparelho!.
Percebi que quando o datatable das pecas retorna vazio o Crystal nao imprime nada...
Como contornar esse problema? Já tentei de tudo: checar se ha pecas e se nao ha colocar no dataset um registro ficticio informando [Ô]nao há peças[Ô] e refazendo o Fill mas nao funcionou... e por ai vai... já fiz coisas que nem me lembro... Alguma sugestão? Tem algum [Ô]pulo-do-gato[Ô] que desconheço? Obrigado de antemão pela possÃvel ajuda.
Segue o codigo que carrega o relatorio:
Private Sub ImprimeRetGarantia(ByVal IDORC As Integer, ByVal IDCLI As Integer)
Dim stringConexao As String = My.Settings.Caminho.ToString
Dim conn As New OleDbConnection(stringConexao)
[ô]MsgBox([Ô]Orçamento nro [Ô] & IDORC & [Ô] impresso![Ô])
Dim daCliente As New OleDbDataAdapter([Ô]Select * from Clientes Where ID_CLI = [Ô] & IDCLI, conn)
Dim daOrcam As New OleDbDataAdapter([Ô]Select * from Orcamentos Where ID_ORC = [Ô] & IDORC, conn)
Dim daPecasOrc As New OleDbDataAdapter([Ô]SELECT * FROM PECASORC WHERE IDORC= [Ô] & IDORC, conn)
Dim dsRelatorio As New dsEntrGar
conn.Open()
daCliente.Fill(dsRelatorio.CLIENTES)
daOrcam.Fill(dsRelatorio.ORCAMENTOS)
daPecasOrc.Fill(dsRelatorio.PECASORC)
conn.Close()
If dsRelatorio.PECASORC.Count = 0 Then
Dim rowNew As DataRow
rowNew = dsRelatorio.Tables(2).NewRow
rowNew([Ô]CODPRODU[Ô]) = [Ô]Sem peças![Ô]
dsRelatorio.Tables(2).Rows.Add(rowNew)
dsRelatorio.AcceptChanges()
daPecasOrc.Fill(dsRelatorio.PECASORC)
End If
Dim relatorio As New crEntrGar
CrystalDecisions.
Dim parametros As New CrystalDecisions.Shared.ParameterFields
Dim parametro1 As New CrystalDecisions.Shared.ParameterField
Dim dis_param1 As New CrystalDecisions.Shared.ParameterDiscreteValue
Dim parametro2 As New CrystalDecisions.Shared.ParameterField
Dim dis_param2 As New CrystalDecisions.Shared.ParameterDiscreteValue
parametro1.ParameterFieldName = [Ô]enderloja[Ô]
dis_param1.Value = EMPRESA
parametro1.CurrentValues.Add(dis_param1)
parametros.Add(parametro1)
parametro2.ParameterFieldName = [Ô]Garantia[Ô]
dis_param2.Value = [Ô]ORÇAMENTO NRO. [Ô] & IDORC & [Ô] EM GARANTIA[Ô]
parametro2.CurrentValues.Add(dis_param2)
parametros.Add(parametro2)
relatorio.SetDataSource(dsRelatorio)
Dim f As New frmRelatorio(relatorio)
f.crvRelatorio.ParameterFieldInfo = parametros
f.Show()
End Sub
Faz um select com Iner Jhoin entre as tabelas e seta um datasource só.
OK... Mas, com inner join, se nao existir peca tambem vai zerar o select...
Agente tem a tendencia de achar que o que o outro faz é mais complicado, até mesmo por trabalhar de forma diferente, mas estou achando meio complicado mesmo, rsrsrs.
No exemplo abaixo trago a ficha do cliente e utilizo um sub relatorio para mostrar os dados dos dependentes, esse sub relatori vai na seção 3 detalhes.
se não tiver dependentes a seção fica vazia.
esta para chamar um banco mysql, mas access é só alterar para oledb.
Agora, tem uma falha de planejamento, não sei se vc pode mudar, mas 3 tabelas para trazer um relatorio é complicado.
Não necessariamente, mas o normal é duas, orçamento e itens do orçamento(peças), os dados do cliente deveriam estar no orçamento, mas cada caso é um caso, pode ser que vc tenha seus motivos.
Dim cmd As New MySqlCommand
Dim da As New MySqlDataAdapter
Dim ds As New NAG2DataSet
cmd = CONEXAO.CreateCommand
cmd.CommandText = [Ô]Select *FROM CLIENTES WHERE NUM_ASSO = [Ô] & NUM_ASSO & [Ô][Ô]
da.SelectCommand = cmd
da.Fill(ds, [Ô]CLIENTES[Ô])
cmd.CommandText = [Ô] select *from DEPENDENTES WHERE COD_ASSOCIADO2 = [Ô] & NUM_ASSO & [Ô][Ô]
da.SelectCommand = cmd
da.Fill(ds, [Ô]DEPENDENTES[Ô])
Dim rpt As New CLIENTES_RPORT
rpt.SetDataSource(ds)
REL_CLIENTES.CrystalReportViewer1.ReportSource = rpt
REL_CLIENTES.Show()
No exemplo abaixo trago a ficha do cliente e utilizo um sub relatorio para mostrar os dados dos dependentes, esse sub relatori vai na seção 3 detalhes.
se não tiver dependentes a seção fica vazia.
esta para chamar um banco mysql, mas access é só alterar para oledb.
Agora, tem uma falha de planejamento, não sei se vc pode mudar, mas 3 tabelas para trazer um relatorio é complicado.
Não necessariamente, mas o normal é duas, orçamento e itens do orçamento(peças), os dados do cliente deveriam estar no orçamento, mas cada caso é um caso, pode ser que vc tenha seus motivos.
Dim cmd As New MySqlCommand
Dim da As New MySqlDataAdapter
Dim ds As New NAG2DataSet
cmd = CONEXAO.CreateCommand
cmd.CommandText = [Ô]Select *FROM CLIENTES WHERE NUM_ASSO = [Ô] & NUM_ASSO & [Ô][Ô]
da.SelectCommand = cmd
da.Fill(ds, [Ô]CLIENTES[Ô])
cmd.CommandText = [Ô] select *from DEPENDENTES WHERE COD_ASSOCIADO2 = [Ô] & NUM_ASSO & [Ô][Ô]
da.SelectCommand = cmd
da.Fill(ds, [Ô]DEPENDENTES[Ô])
Dim rpt As New CLIENTES_RPORT
rpt.SetDataSource(ds)
REL_CLIENTES.CrystalReportViewer1.ReportSource = rpt
REL_CLIENTES.Show()
Ola, Nilson. Primeiramente obrigado pela resposta em pleno domingo... O lance das tres tabelas foi porque, fazendo uma unica com os dados, qdo nao tinha peca dava o tal erro - e, no desespero, optei pelas tres tabelas que podem muito bem ser duas. Acho que a solução do problema está no subrelatorio que vc citou... nao trabalho com ele. Sou relativamente novo nessa historia de VB.NET... Vou procurar saber como fazer e agradeço mesmo a ajuda. Valeu.
No crystal tem a opção de inserir sub relatorios, ele serve para esse tipo de situação, onde vc tem um orçamento e os itens dele.
então vc cria um relatorio separado, por exemplo:RelItensDoOrça e um outro RelOrça.
No RelOrça, Quando vc for em inserir o sub relatorio, o crystal pede para vc informa qual sera esse sub rel, então vc informa o RelItensDoOrça.
Nesse caso vc coloca o RelItensDoOrça na seção detalhes do RelOrça..
No RelItensDoOrça vc coloca apenas os campos dos itens.
O Crystal é uma ferramenta fantastica, não desista dele, da um trabalho danado e agente sempre tem a aprender com ele, mas no final do trabalho vc ve que valeu a pena.
então vc cria um relatorio separado, por exemplo:RelItensDoOrça e um outro RelOrça.
No RelOrça, Quando vc for em inserir o sub relatorio, o crystal pede para vc informa qual sera esse sub rel, então vc informa o RelItensDoOrça.
Nesse caso vc coloca o RelItensDoOrça na seção detalhes do RelOrça..
No RelItensDoOrça vc coloca apenas os campos dos itens.
O Crystal é uma ferramenta fantastica, não desista dele, da um trabalho danado e agente sempre tem a aprender com ele, mas no final do trabalho vc ve que valeu a pena.
Citação::
No crystal tem a opção de inserir sub relatorios, ele serve para esse tipo de situação, onde vc tem um orçamento e os itens dele.
então vc cria um relatorio separado, por exemplo:RelItensDoOrça e um outro RelOrça.
No RelOrça, Quando vc for em inserir o sub relatorio, o crystal pede para vc informa qual sera esse sub rel, então vc informa o RelItensDoOrça.
Nesse caso vc coloca o RelItensDoOrça na seção detalhes do RelOrça..
No RelItensDoOrça vc coloca apenas os campos dos itens.
O Crystal é uma ferramenta fantastica, não desista dele, da um trabalho danado e agente sempre tem a aprender com ele, mas no final do trabalho vc ve que valeu a pena.
Ola amigo, boa tarde...
Pesquisei um bocado... vi varios exemplos mas nada que me ajudasse sobremaneira...
De fato, como vc disse acima, criei o relatorioä parte, fui no principal e incluii o subrelatorio, colocando-o na seçao de detalhes... Tudo funciona mas as pecas nao aparecem... Acho que falta alguma ligação entre o relatorio prioncipal e o sub relatorio...
Veja como ficou:
Dim stringConexao As String = My.Settings.Caminho.ToString
Dim conn As New System.Data.OleDb.OleDbConnection(stringConexao)
[ô]Dataset Relatorio Principal
Dim dsRelatorio As New dsEntrGar
[ô]Dataset Sub relatorio
Dim dsPecas As New dsPecas
[ô]Dataadapters relatorio principal...
Dim daCliente As New System.Data.OleDb.OleDbDataAdapter([Ô]Select * from Clientes Where ID_CLI = [Ô] & IDCLI, conn)
Dim daOrcam As New System.Data.OleDb.OleDbDataAdapter([Ô]Select * from Orcamentos Where ID_ORC = [Ô] & IDORC, conn)
[ô]Dataadapter subrelatorio...
Dim daPecasOrc As New System.Data.OleDb.OleDbDataAdapter([Ô]Select PECASORC.CODLINHA, PECASORC.CODPRODU, PECASORC.USADA, [Ô] & _
[Ô]ESTOQUE.DESCRICAO, PECASORC.QUANTID, PECASORC.VALOR, [Ô] & _
[Ô](PECASORC.VALOR*PECASORC.QUANTID) AS Total [Ô] & _
[Ô]FROM ESTOQUE INNER JOIN PECASORC ON ESTOQUE.ID_EST = PECASORC.IDPRO [Ô] & _
[Ô]WHERE PECASORC.IDORC= [Ô] & IDORC & [Ô] [Ô], conn)
conn.Open()
[ô]Alimentacao do dataset dsRelatorio
daCliente.Fill(dsRelatorio.CLIENTES)
daOrcam.Fill(dsRelatorio.ORCAMENTOS)
[ô]Alimentacao do dataset dsPecas (subrelatorio)
daPecasOrc.Fill(dsPecas.PECASORC)
conn.Close()
Dim relatorio As New crGarantia
Dim subrelPecas As New crSubPecas
[ô]apenas para debugar se há peças no orçamento...
If dsPecas.PECASORC.Count = 0 Then
MsgBox([Ô]Não há peças neste orçamento![Ô])
End If
relatorio.SetDataSource(dsRelatorio)
relatorio.OpenSubreport([Ô]crSubPecas.rpt[Ô])
Dim parametros As New CrystalDecisions.Shared.ParameterFields
Dim parametro1 As New CrystalDecisions.Shared.ParameterField
Dim dis_param1 As New CrystalDecisions.Shared.ParameterDiscreteValue
Dim parametro2 As New CrystalDecisions.Shared.ParameterField
Dim dis_param2 As New CrystalDecisions.Shared.ParameterDiscreteValue
Dim parametro3 As New CrystalDecisions.Shared.ParameterField
Dim dis_param3 As New CrystalDecisions.Shared.ParameterDiscreteValue
parametro1.ParameterFieldName = [Ô]enderloja[Ô]
dis_param1.Value = EMPRESA
parametro1.CurrentValues.Add(dis_param1)
parametros.Add(parametro1)
parametro2.ParameterFieldName = [Ô]Garantia[Ô]
dis_param2.Value = [Ô]GARANTIA DO SERVIÇO EXECUTADO - ORC. [Ô] & IDORC
parametro2.CurrentValues.Add(dis_param2)
parametros.Add(parametro2)
parametro3.ParameterFieldName = [Ô]Validade[Ô]
dis_param3.Value = [Ô]GARANTIA VÃLIDA ATé: [Ô] & CStr(DataAte)
parametro3.CurrentValues.Add(dis_param3)
parametros.Add(parametro3)
Dim f As New frmRelatorio(relatorio)
f.crvRelatorio.ParameterFieldInfo = parametros
f.Show()
Agora, independente de haver ou nao peças (que era meu problema anterior...) mostra os dados do cliente e do aparelho mas,agora, mesmo que tenha pecas o subrelatorio aparece em branco - so aparece a linha de titulo...
Obrigado por qualquer ajuda.
Duas coisas que não sei bem se é isso que esta errado.
Veja no meu exemplo, eu utilizo um dataset só, pois dessa ds tem os datatable, outra coisa vc esta criando instancia do sub relatorio, que não é necessario.
Veja no meu exemplo, eu utilizo um dataset só, pois dessa ds tem os datatable, outra coisa vc esta criando instancia do sub relatorio, que não é necessario.
Faça seu login para responder