Jump to content

Crystal Report / Section


williamjda
 Share

Go to solution Solved by williamjda,

Recommended Posts

Amigos, bom dia.

Estou em mais uma jornada do Crystal Report.

Tenho um form com 3 DataGridView. Preciso que o mesmo CrystalReportViewer, mostre as informações dos três DataGridView.

O código que tenho é este:

 Dim dv As DataView = New DataView()
    Dim dt As New DataTable
    Dim R As New Cadastro_Produto_Produto_Print_CRV
    Dim cr As New CRV_Cadastro_Produto_Print
    dv = DirectCast(Me.DataGrid_Dados_Componente.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados 'havia aqui um erro de digitação
    dt = dv.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
    For Each dr In dv.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
	    dt.ImportRow(dr) 'importa cada row para a DataTable dt
    Next
    cr.SetDataSource(dt)
    R.CRV_Print_Cadastro_Produto.ReportSource = cr
    R.ShowDialog()

Com ele consigo fazer o Crystal Report mostrar as informações de um DataGrid. Mas como fazer ele mostrar as informações dos 3 DataGrid em um único CrystalReportViewer.

Eu criei sections para anexar as informações de cada Grid. Pois cada um deles é preenchido com informações de tabelas diferentes do mesmo banco de dados.

Obrigado.

Link to comment
Share on other sites

Amigo não estou conseguindo mostrar esta estrutura. Fica o form em branco. Acredito que eu esteja fazendo algo errado. Tenho algumas dificuldades com o Crystal Report pois conheci a pouco tempo o Crystal Report.

Fiz desta forma. Porem sem sucesso o form aparece em branco. Também fiz de varias outras formas mas para não colocar todas, pois nenhuma delas funcionou.

Dim dvPerfil As DataView = New DataView()
	Dim dtPerfil As New DataTable
	Dim RPerfil As New Cadastro_Produto_Perfil_Print_CRV
	Dim crPerfil As New CRV_Cadastro_Produto_Print
	dvPerfil = DirectCast(Me.DataGrid_Dados_Perfil.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dvPerfil = DirectCast(Me.DataGrid_Dados_Componente.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dtPerfil = dvPerfil.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each drPerfil In dvPerfil.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dtPerfil.ImportRow(drPerfil) 'importa cada row para a DataTable dt
	Next
	dtPerfil = dvPerfil.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each drPerfil In dvPerfil.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dtPerfil.ImportRow(drPerfil) 'importa cada row para a DataTable dt
	Next
	crPerfil.SetDataSource(dtPerfil)
	RPerfil.CRV_Print_Cadastro_Produto.ReportSource = crPerfil
	RPerfil.ShowDialog()

Lembrando que cada grid trás a informação de um tabela diferente no Form. São três tabelas que quero que seja apresentada em um único CrystalReportViewer.

O código abaixo mostra 3 reports. Mas ai eu teria que imprimir folhas para um único documento. Então a necessidade de ser colocar tudo em uma unica folha.

Dim dvComponente As DataView = New DataView()
	Dim dtComponente As New DataTable
	Dim RComponente As New Cadastro_Produto_Componente_Print_CRV
	Dim crComponente As New CRV_Cadastro_Componente_Print
	dvComponente = DirectCast(Me.DataGrid_Dados_Componente.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dtComponente = dvComponente.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each drComponente In dvComponente.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dtComponente.ImportRow(drComponente) 'importa cada row para a DataTable dt
	Next
	crComponente.SetDataSource(dtComponente)
	RComponente.CRV_Print_Cadastro_Produto.ReportSource = crComponente
	RComponente.ShowDialog()
	Dim dvPerfil As DataView = New DataView()
	Dim dtPerfil As New DataTable
	Dim RPerfil As New Cadastro_Produto_Perfil_Print_CRV
	Dim crPerfil As New CRV_Cadastro_Produto_Print
	dvPerfil = DirectCast(Me.DataGrid_Dados_Perfil.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dtPerfil = dvPerfil.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each drPerfil In dvPerfil.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dtPerfil.ImportRow(drPerfil) 'importa cada row para a DataTable dt
	Next
	crPerfil.SetDataSource(dtPerfil)
	RPerfil.CRV_Print_Cadastro_Produto.ReportSource = crPerfil
	RPerfil.ShowDialog()
	Dim dvVidro As DataView = New DataView()
	Dim dtVidro As New DataTable
	Dim RVidro As New Cadastro_Produto_Vidro_Print_CRV
	Dim crVidro As New CRV_Cadastro_Vidro_Print
	dvVidro = DirectCast(Me.DataGrid_Dados_Vidro.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dtVidro = dvVidro.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each drVidro In dvVidro.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dtVidro.ImportRow(drVidro) 'importa cada row para a DataTable dt
	Next
	crVidro.SetDataSource(dtVidro)
	RVidro.CRV_Print_Cadastro_Produto.ReportSource = crVidro
	RVidro.ShowDialog()

Talvez eu esteja montando o CrystalReport de forma errada. Eu vi alguns videos que ensinam a montar o crystal report mas nenhum deles é da maneira que preciso.

Por isso consegui chegar até aqui, mas apenas com um report por Grid.

Link to comment
Share on other sites

Eu disse acima:

Mas atenção que a estrutura dt já não pode ser alterada, por isso, as consultas têm de ter o mesmo tipo de informação.

Ora tu estás sempre a clonar o dt. Só o podes fazer uma primeira vez.

Tu vais conseguir visualizar um report de três tabelas com o mesmo tipo de informação. Se não tiverem nenhuma analogia, esquece este método.

Pela imagem que colocaste, parece que as tabelas têm os mesmos tipos de dados.

Se não voltares a clonar, deve funcionar.

Link to comment
Share on other sites

As tabelas contem informações diferentes. Por isso não posso crias uma unica tabelas para os 3 Grid. Eu até tentei criar uma tabela que recebesse as informações dos 3 produtos que desejo porem na hora de consultar os dados fica inviavel. Por isso tive que criar tabelas diferente. Embora os dados sejam parecidos os nomes dos campos são diferentes para consulta.

Pelo que entendi, não é possível trazer três tabelas diferentes para o mesmo CrystalReport correto?

Vou ter que bola uma forma então de fazer tudo em uma unica tabela.

Link to comment
Share on other sites

Então é ai que esta o problema. Cada produto tem campos diferentes. E apenas algumas campos em comum, tipo codigo, descricao, e valor que da para deixar igual. Sendo quem em um é valor do peso da barra, em outro é valor do metro da barra. São diferentes estou a bolar para ver se consigo. Mas ao que vejo terei 3 select um para cada grid.

Link to comment
Share on other sites

Esse é o comando para adicionar os dados no baco. Lembrando que para cada um dos itens tem um select pois são três tabelas do mesmo banco de dados. Mas o insert é o mesmo só muda os campos e o nome da tabela.

 ''' <summary>
   ''' GRAVA OS DADOS DA LINHA SELECIONADA NO DATAGRID. ANTES DE GARAVAR OS DADOS SÃO ADCIONADOS NAS CLASSE
   ''' Classe_Cadastro_Produto_Perfil. ATRAVÉS DAS CLASSES QUE OS DADOS SÃO ADICIONADO AO BANCO
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub Gravar_Dados()
    'CHECA A CONECTION STRING PARA GRAVAR OS DADOS NO BANCO DE DADOS
    Dim cmd As SqlCommand = ConectionBD.CreateCommand
    'QUERY PARA GRAVAR OS DADOS NO FOMRULARIO NO BANCO DE DADOS
    cmd.CommandText = ("INSERT INTO Cadastro_Produto_Perfil (codigoproduto, codigoperfil, descricaoperfil, pesometrobarraperfil, valormetrobarraperfil)" _
								 & " VALUES(" _
								 & "'" & Classe_Cadastro_Produto_Perfil.codigoproduto & "'," _
								 & "'" & Classe_Cadastro_Produto_Perfil.codigoperfil & "'," _
								 & "'" & Classe_Cadastro_Produto_Perfil.descricaoperfil & "'," _
								 & "'" & Classe_Cadastro_Produto_Perfil.pesometrobarraperfil & "'," _
								 & "'" & Classe_Cadastro_Produto_Perfil.valormetrobarraperfil.Replace(".", "").Replace(",", ".") & "')")
    Try
	    'ABRE A CONEXÃO DO BANCO DE DADOS
	    ConectionBD.Open()
	    'CONSULTA A ESTRUTURA DO BANCO DE DADOS OU CRIA OBJETOS DE BANCO DE DADOS COMO TABELAS
	    cmd.ExecuteNonQuery()
	    'RETORNA O MENSAGE DE OK APOS GRAVAR NO BANCO
	    MsgBox("Cadastro gravado com sucesso.")
	    'FECHA A CONEXÃO COM O BANCO
	    ConectionBD.Close()
	    'LIMPA OS CAMPOS DO FORMULARIOS APOS GRAVAR O REGISTRO.
	    Classe_Cadastro_Produto_Perfil.codigoproduto = String.Empty
	    Classe_Cadastro_Produto_Perfil.codigoperfil = String.Empty
	    Classe_Cadastro_Produto_Perfil.descricaoperfil = String.Empty
	    Classe_Cadastro_Produto_Perfil.pesometrobarraperfil = String.Empty
	    Classe_Cadastro_Produto_Perfil.valormetrobarraperfil = String.Empty
    Catch erro As Exception
	    'EM CASO DE ERRO NA GRAVAÇÃO DO REGISTRO O SISTEMA RETORNA UMA MENSAGEM DE ERRO.
	    MsgBox(erro.ToString, MsgBoxStyle.Exclamation, "INSERT_Cadastro_Produto_Perfil")
    Finally

	    'APÓS REALIZAR O INSERT NO BANCO DE DADOS REALIZA O SELECT PARA ATUALIZAR O DATAGRID
	    Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutoperfil'Reg.', codigoperfil, descricaoperfil, pesometrobarraperfil, valormetrobarraperfil" _
											  & " FROM Cadastro_Produto_Perfil" _
											  & " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)
	    'GUARDA A CONSULTA REALIZADA NO DATA SET
	    Dim sqlDados As New DataSet
	    'RECEBE OS DADOS DO DATA SET
	    SQLConsulta.Fill(sqlDados)
	    'RECEBE OS DADOS DA CONSULTA REALIZADA
	    Cadastro_Produto.DataGrid_Dados_Perfil.DataSource = sqlDados.Tables(0).DefaultView
	    'DEFINE O LAYOUT DO DATAGRID DADOS
	    DATAGRID_Layout_Cadastro_Produto_Perfil.DataGrid_Dados()
	    'SE O DATAGRID ESTIVER SELECIONADO NÃO FAZ NADA
	    If Cadastro_Produto.DataGrid_Dados_Perfil.Focused = True Then
	    Else
		    'FAZ COM QUE O DATA GRID INICIE COM A SELEÇÃO DESATIVADA
		    If Cadastro_Produto.DataGrid_Dados_Perfil.SelectedRows.Count > 0 Then
			    Cadastro_Produto.DataGrid_Dados_Perfil.ClearSelection()
		    End If
	    End If
    End Try
Link to comment
Share on other sites

Boa tarde.

Amigo consegui fazer assim:

Unifiquei as três tabelas. Para que a mesma tivesse campos distintos conforme me disse no inicio.

Não era do jeito que eu queria pois algumas colunas do relatório ficam em branco. Pois isso que havia feito uma tabela para cada Grid. Para que que isso não ocorresse.

Montei um relatório personalizado, assim consegui fazer a separação por grupo. No caso o Tipo.

Se tiver uma ideia de como faço para conseguir montar um relatório com tabelas diferente da maneira que imaginei, por favor mande-me uma dica.

Link to comment
Share on other sites

Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutoperfil'Reg.', codigoperfil, descricaoperfil, pesometrobarraperfil, valormetrobarraperfil" _
& " FROM Cadastro_Produto_Perfil" _
& " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1",

Ok.

Mostra o comando equivalente a este a cima para os outros dois datagrid.

Nota: isto foi escrito antes de ler teu último post.

Chegaste a um ponto que funciona.

A outra maneira de fazer implica muitos passos, e não é fácil comunicarmos à distância, visto envolver código e também a própria concepção do Crystal Report.

Link to comment
Share on other sites

PERFIL:

                'APÓS REALIZAR O INSERT NO BANCO DE DADOS REALIZA O SELECT PARA ATUALIZAR O DATAGRID
           Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutoperfil'Reg.', codigoperfil, descricaoperfil, pesometrobarraperfil, valormetrobarraperfil" _
                                                 & " FROM Cadastro_Produto_Perfil" _
                                                 & " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)

           'GUARDA A CONSULTA REALIZADA NO DATA SET
           Dim sqlDados As New DataSet

           'RECEBE OS DADOS DO DATA SET
           SQLConsulta.Fill(sqlDados)

           'RECEBE OS DADOS DA CONSULTA REALIZADA
           Cadastro_Produto.DataGrid_Dados_Perfil.DataSource = sqlDados.Tables(0).DefaultView


COMPONENTE:

'FAZ A CONSULTA NO BANCO
           Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutocomponente'Reg.', codigocomponente'Código', descricaocomponente'Descrição', valorunitariocomponente'Valor Unitário'" _
                                                 & " FROM Cadastro_Produto_Componente" _
                                                 & " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)

           'GUARDA A CONSULTA REALIZADA NO DATA SET
           Dim sqlDados As New DataSet

           'RECEBE OS DADOS DO DATA SET
           SQLConsulta.Fill(sqlDados)

           'RECEBE OS DADOS DA CONSULTA REALIZADA
           Cadastro_Produto.DataGrid_Dados_Componente.DataSource = sqlDados.Tables(0).DefaultView

VIDRO:

 'FAZ A CONSULTA NO BANCO
           Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutovidro'Reg.', codigovidro'Código', descricaovidro'Descrição', corvidro'Cor', milimetrovidro'MM'" _
                                                 & " FROM Cadastro_Produto_Vidro" _
                                                 & " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)

           'GUARDA A CONSULTA REALIZADA NO DATA SET
           Dim sqlDados As New DataSet

           'RECEBE OS DADOS DO DATA SET
           SQLConsulta.Fill(sqlDados)

           'RECEBE OS DADOS DA CONSULTA REALIZADA
           Cadastro_Produto.DataGrid_Dados_Vidro.DataSource = sqlDados.Tables(0).DefaultView

Edited by williamjda
Link to comment
Share on other sites

Não me vou adiantar muito mais, porque isto levava a muitas considerações futura.

Mas a ideia seria fazer um select dando designações iguais para todos os campos das 3 tabelas, designações essas que seriam as que estão diretamente na estrutura do crystal report.

Por exemplo, para o segundo datagrid:

Dim SQLConsulta As New SqlDataAdapter("SELECT idprodutocomponente'Reg.' as idprodutoperfil'Reg.', codigocomponente'Código' as codigoperfil, ... (etc)
& " FROM Cadastro_Produto_Componente" _
& " WHERE codigoproduto ='" & Cadastro_Produto.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)

A ideia é ir buscar o campo idprodutocomponente'Reg.' mas ter o nome idprodutoperfil'Reg.', etc.

Assim, as três tabelas vão ter campos com os mesmos nomes, com a mesma estrutura, e o crystal report já consegue reconhecer uma estrutura comum.

Edited by car4321
Link to comment
Share on other sites

Ok até ai eu entendi.

O que eu não entendi como seria o comando para gerar o crystal report com os 3 DataGrid.

Pois eu fiz de varias maneiras e todas elas retornava em branco.

Poderia mostrar como seria o código. Pois o código que eu tenho até o momento e funciona apenas para um DataGrid é este:

Dim dvPerfil As DataView = New DataView()
		    Dim dtPerfil As New DataTable
		    Dim RPerfil As New Cadastro_Produto_Perfil_Print_CRV
		    Dim crPerfil As New CRV_Cadastro_Produto_Print
		    dvPerfil = DirectCast(Me.DataGrid_Dados_Perfil.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
		    dtPerfil = dvPerfil.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
		    For Each drPerfil In dvPerfil.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
				    dtPerfil.ImportRow(drPerfil) 'importa cada row para a DataTable dt
		    Next
		    crPerfil.SetDataSource(dtPerfil)
		    RPerfil.CRV_Print_Cadastro_Produto.ReportSource = crPerfil
		    RPerfil.ShowDialog()
Link to comment
Share on other sites

Amigo, bom dia.

Estou realmente a quebrar a cabeça com esta questão. Fiz o select como mencionou e realmente ele funciona na questão de carregar o datatable.

'CONSULTA 01--------------------------------
 Dim SQLConsultat As New SqlDataAdapter("SELECT idprodutoperfil, codigoperfil, descricaoperfil, pesometrobarraperfil, valormetrobarraperfil, quantidade, valortotal" _
										  & " FROM Cadastro_Produto_Perfil" _
										  & " WHERE codigoproduto ='" & Cadastro_Produto_Novo.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)


'CONSULTA 02--------------------------------
	Dim SQLConsultac As New SqlDataAdapter("SELECT idprodutocomponente As idprodutoperfil, codigocomponente As codigoperfil, descricaocomponente As descricaoperfil, valorunitariocomponente  As valormetrobarraperfil, quantidade, valortotal" _
										  & " FROM Cadastro_Produto_Componente" _
										  & " WHERE codigoproduto ='" & Cadastro_Produto_Novo.txtnumeroProduto.Text & "'ORDER BY 1", ConectionBD.ConnectionString)

O datagrid 2 está com os nome de campos distintos igual ao datagrid 1. São tabelas diferentes conforme o Select adicionado acima.

Fiz o código seguindo suas orientações acima. Porém se eu retirar o Clone como mencionou o sistema da erro na hora de gerar com a seguinte informação: "Não há uma referencia para o objeto".

Então com o código abaixo eu consigo gerar o CR. Porem ele abre um report com a tabela perfil. E depois outro report com os dados da tabela componente.

'REPORT DO DATAGRID 1 - PERFIL
	Dim dv1Produto As DataView = New DataView()
	Dim dt1Produto As New DataTable
	Dim R1Produto As New Cadastro_Produto_CRV_Print
	Dim cr1Produto As New CRV_Cadastro_Produto_Print
	dv1Produto = DirectCast(Me.DataGridView1.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dt1Produto = dv1Produto.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each dr1Produto In dv1Produto.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dt1Produto.ImportRow(dr1Produto) 'importa cada row para a DataTable dt
	Next
	cr1Produto.SetDataSource(dt1Produto)
	R1Produto.CRV_Print_Cadastro_Produtos.ReportSource = cr1Produto
	R1Produto.ShowDialog()

	'REPORT DO DATAGRID 2 - COMPONENTE
	Dim dv2Produto As DataView = New DataView()
	Dim dt2Produto As New DataTable
	Dim R2Produto As New Cadastro_Produto_CRV_Print
	Dim cr2Produto As New CRV_Cadastro_Produto_Print
	dv2Produto = DirectCast(Me.DataGridView2.DataSource, DataView) 'crio uma DataView com os dados da DataSource da DataGrid_dados
	dt2Produto = dv2Produto.ToTable().Clone() 'clona a estrutura da DataView para a DataTable dt
	For Each dr2Produto In dv2Produto.ToTable().Select() 'percorre as rows da DataView e selecciona a actual
		dt2Produto.ImportRow(dr2Produto) 'importa cada row para a DataTable dt
	Next
	cr2Produto.SetDataSource(dt2Produto)
	R2Produto.CRV_Print_Cadastro_Produtos.ReportSource = cr2Produto
	R2Produto.ShowDialog()

Mas ele gera em dois Reports, por que no meu código tem dois ShowDialog(). Sendo um para cada código.

Mas um detalhe importe que consegui avançar, foi que o banco que adicionei no Design do Report foi apenas o banco Perfil. E ele me gerou com os dados do componente. Isso porque no select, fiz como me falou. Nomeando na consulta com nomes distintos os campos das tabelas.

Mas a questão que me cabe é a seguinte: Entendi que o código está gerando dados para dois datatable, também entendi que é possível fazer ele gerar dados para duas ou mais tabelas diferentes.

Mas como fazer isso tudo no mesmo Report? Pois até agora só consegui fazer ele gerar estes dados em CR separados. E em uma única tabela com todas as informações. Neste formato o report fica muito estranho conforme postei mais acima. Então a minha necessidade de fazer com tabelas diferentes para que eu possa personalizar o report e acrescentar alguns dados que no modelo que consegui personalizado não dá.

Acredito que estou perto de resolver pois até aqui já foi um grande avanço.

Mas como o meu código tem que ficar para gerar as informações em um único report?

E como terei que desenhar o Report para receber estes dados?

Pois é aqui que minha cabeça travou.

Poderia me ajudar, ficaria muito grato. Tenho que entregar esse projeto neste formato ainda esta semana e só falta isso para concluir esta etapa.

Estou detalhando aqui o máximo possível para que fique claro o que estou fazendo e para ajudar a outros que venha ter a mesma situação. Já que não achei nada parecido na internet.

Obrigado.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.