POPULANDO UM DATATABLE USANDO O LISTVIEW

ELMORICARDOATANZI 08/02/2024 10:37:00
#503027
Oi pessoal,

Estou tentando popular um DataTable utilizando o ListView em meu sistema, até consegui fazer através da função abaixo, mais ele só pega o primeiro registro que está no meu banco de dado do MYSQL.

Como faço para que a função pule para o próximo registro do banco de dados?

Private Function ObeterDados() As DataTable
'*
'* Abrindo o banco de dados
'*
Dim dr_Funcs As MySqlDataReader
Dim Con_Funcs As New MySqlConnection(StrSenha)
Dim Cmd_Funcs As New MySqlCommand(NewOpcao, Con_Funcs)
Con_Funcs.Open()
dr_Funcs = Cmd_Funcs.ExecuteReader
'*
'* Declarando campos do DataTable
'*
Dim Dt As DataTable = New DataTable()
Dt.Columns.Add("Codigo")
Dt.Columns.Add("RazSoc")
Dt.Columns.Add("DatCad")
Dt.Columns.Add("TipoClin")
Dt.Columns.Add("TipoPes")
Dt.Columns.Add("Enderec")
Dt.Columns.Add("Bairros")
Dt.Columns.Add("Cidades")
Dt.Columns.Add("Estados")
Dt.Columns.Add("Ceps")
Dt.Columns.Add("Fones")
Dt.Columns.Add("Celular")
Dt.Columns.Add("Emails")
Dt.Columns.Add("PJFisica")
Dt.Columns.Add("InsEsta")
Dt.Columns.Add("InsMuni")
Dt.Columns.Add("Contato")
Dt.Columns.Add("TipCont")

Try
If dr_Funcs.HasRows Then
If dr_Funcs.Read Then
For w As Integer = 0 To ListView1.Items.Count - 1
If ListView1.Items(w).Checked = True Then ' Verifica se o CheckBox foi marcado
Dt.Rows.Add(dr_Funcs.Item("XPCodigo").ToString(), dr_Funcs.Item("XPRazSoc").ToString(), dr_Funcs.Item("XPDatCad").ToString(),
dr_Funcs.Item("XPTipoClin").ToString(), dr_Funcs.Item("XPTipoPes").ToString(), dr_Funcs.Item("XPEnderec").ToString(),
dr_Funcs.Item("XPBairros").ToString(), dr_Funcs.Item("XPCidades").ToString(), dr_Funcs.Item("XPEstados").ToString(),
dr_Funcs.Item("XPCeps").ToString(), dr_Funcs.Item("XPFones").ToString(), dr_Funcs.Item("XPCelular").ToString(),
dr_Funcs.Item("XPEmails").ToString(), dr_Funcs.Item("XPPJFisica").ToString(), dr_Funcs.Item("XPInsEsta").ToString(),
dr_Funcs.Item("XPInsMuni").ToString(), dr_Funcs.Item("XPContato").ToString(), dr_Funcs.Item("XPTipCont").ToString())
End If
Next
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
dr_Funcs.Close()
Con_Funcs.Close()
End Try
Return Dt
End Function

Se alguém puder me dar uma força ficarei grato.

Obrigado.
KERPLUNK 08/02/2024 14:31:03
#503029
O que você prefere: realmente aprender o que fazer ou só o código que resolve seu problema pontual?
ELMORICARDOATANZI 08/02/2024 17:37:12
#503031
KERPLUNK - muito obrigado por ter respondido, mais consegui fazer o que eu queria, da forma que estava fazendo não estava retirando os dados do ListView mais sim do banco de dados que tenho.

Isso é para um relatório de cadastro de Clientes que estou fazendo, onde escolho no ListView o(s) cliente(s) que quero fazer a impressão através de um CheckBox e depois envio os dados do DataTable para o relatório do ReportViewer.

Agora tenho uma dúvida, como fazer que o ReportViewer repita em uma página vários cadastros que escolhi no ListView. Se puder me ajudar nesta questão ou se tiver uma ideia melhor de como fazer este relatório ficarei grato.

Obrigado.
KERPLUNK 08/02/2024 19:58:45
#503032
A pergunta é a mesma... quer aprender o que e como fazer, ou só resolver o problema pontual?
ELMORICARDOATANZI 09/02/2024 08:00:56
#503033
KERPLUNK bom dia, a resposta é AMBOS, se não aprender não vou conseguir fazer, assim sendo, gostaria muito de aprender para fazer.
KERPLUNK 09/02/2024 08:27:37
#503034
Ok. Vamos lá:
O DataReader é um objeto que contêm o resultado da sua query. Para ler um registro, você usa o método Read, como você está fazendo. Cada vez que ele é executado, um registro é avançado.
Então o que você precisa é de um loop para passar os dados para sua ListView.

If dr_Funcs.HasRows Then
while dr_Funcs.Read
For w As Integer = 0 To ListView1.Items.Count - 1
If ListView1.Items(w).Checked = True Then ' Verifica se o CheckBox foi marcado
Dt.Rows.Add(dr_Funcs.Item("XPCodigo").ToString(), dr_Funcs.Item("XPRazSoc").ToString(), dr_Funcs.Item("XPDatCad").ToString(),
dr_Funcs.Item("XPTipoClin").ToString(), dr_Funcs.Item("XPTipoPes").ToString(), dr_Funcs.Item("XPEnderec").ToString(),
dr_Funcs.Item("XPBairros").ToString(), dr_Funcs.Item("XPCidades").ToString(), dr_Funcs.Item("XPEstados").ToString(),
dr_Funcs.Item("XPCeps").ToString(), dr_Funcs.Item("XPFones").ToString(), dr_Funcs.Item("XPCelular").ToString(),
dr_Funcs.Item("XPEmails").ToString(), dr_Funcs.Item("XPPJFisica").ToString(), dr_Funcs.Item("XPInsEsta").ToString(),
dr_Funcs.Item("XPInsMuni").ToString(), dr_Funcs.Item("XPContato").ToString(), dr_Funcs.Item("XPTipCont").ToString())
End If
Next
End While
End If


Só isso já deve resolver seu problema. Mas qual o porém aqui?
Você deveria urgentemente aprender POO, ou, programação orientada à objetos. Isso é um assunto muito extenso pra ser abordado em um só post e precisa um bom tempo de dedicação.

Tenho um canal no Youtube onde explico isso e muito mais em detalhes. Dedique um tempo para se aprimorar.
ELMORICARDOATANZI 09/02/2024 09:40:46
#503035
KERPLUNK fiz de uma outa maneira, já que tenho um ListView com CheckBox onde o cliente vai escolher quais dados serão impressos, então fiz com que o sistema verifique no ListView quais registros estão marcados e a partir daí será alimentado o DATATABLE. Veja como ficou a função:

Private Function ObeterDados() As DataTable
Dim Dt As DataTable = New DataTable()
Dt.Columns.Add("Codigo")
Dt.Columns.Add("RazSoc")
Dt.Columns.Add("DatCad")
Dt.Columns.Add("TipoClin")
Dt.Columns.Add("TipoPes")
Dt.Columns.Add("Enderec")
Dt.Columns.Add("Bairros")
Dt.Columns.Add("Cidades")
Dt.Columns.Add("Estados")
Dt.Columns.Add("Ceps")
Dt.Columns.Add("Fones")
Dt.Columns.Add("Celular")
Dt.Columns.Add("Emails")
Dt.Columns.Add("PJFisica")
Dt.Columns.Add("InsEsta")
Dt.Columns.Add("InsMuni")
Dt.Columns.Add("Contato")
Dt.Columns.Add("TipCont")

Try
For w As Integer = 0 To ListView1.Items.Count - 1
If ListView1.Items(w).Checked = True Then
Dt.Rows.Add(ListView1.Items(w).SubItems(0).Text, ' Código
ListView1.Items(w).SubItems(1).Text, ' Razão Social
ListView1.Items(w).SubItems(8).Text, ' Data Cadastramento
ListView1.Items(w).SubItems(9).Text, ' Tipo Cliente
ListView1.Items(w).SubItems(10).Text, ' Tipo Pessoal
ListView1.Items(w).SubItems(2).Text, ' Endereço
ListView1.Items(w).SubItems(3).Text, ' Bairro
ListView1.Items(w).SubItems(4).Text, ' Cidade
ListView1.Items(w).SubItems(16).Text, ' Estado
ListView1.Items(w).SubItems(17).Text, ' Cep
ListView1.Items(w).SubItems(5).Text, ' Fone Fixo
ListView1.Items(w).SubItems(6).Text, ' Celular
ListView1.Items(w).SubItems(11).Text, ' Email
ListView1.Items(w).SubItems(7).Text, ' CNPJ
ListView1.Items(w).SubItems(12).Text, ' Insc. Estadual
ListView1.Items(w).SubItems(13).Text, ' Insc. Municipal
ListView1.Items(w).SubItems(14).Text, ' Contatos
ListView1.Items(w).SubItems(15).Text) ' Tipo Contrato
End If
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
Return Dt
End Function

Agora vem a segunda parte, é colocar os dados do DATATABLE no ReportViewer, mais o DATATABLE poderá ter uma ou várias linhas, ai tenho que fazer que o ReportViewer importe os dados, mais não estou utilizando TABLEA ou MATRIZ, vou ter que criar um objeto no DATASET para fazer isso. Será que a minha linha de raciocínio está certa?

Obrigado

KERPLUNK 09/02/2024 11:59:14
#503036
Bem, na verdade até poderia funcionar, mas vai ficar muito mais complexo. Essa é uma das razões da OOP se destacar tanto.
Com ela você vai ter algo como:

ListView1.DataSource = Cliente.GetClientes();

E só isso. Então seu Listview vai estar com os dados todos prontinhos, exibidos certinho e tal.
Daí você vai marcar no quais os que você quer no relatório. Com isso, você vai ter o DataSource já alterado e pra passar pro relatório seria algo como:

Relatorio.DataSource = (List<Cliente>)ListView1.DataSource.Where(x => x.CheckBox == Checked);


E pronto. É por isso que o seu approach, apesar de ser possível fazer funcionar, é bem mais complicado.
A ideia do OOP é separar as funcionalidaes. Da mais trabalho de fazer? No início, sim. Mas com o passar do tempo as vantagens sobrepõem as desvantagens de forma avassaladora.
KERPLUNK 10/02/2024 08:54:51
#503038
Fiz mais ou menos o que estou sugerindo, usando o ChatGPT:

Imports MySql.Data.MySqlClient
Imports System.Collections.Generic

Public Class MinhaClasseDeLeitura

Private connectionString As String

Public Sub New(connectionStr As String)
Me.connectionString = connectionStr
End Sub

Public Function LerClientes() As List(Of Cliente)

Dim clientes As New List(Of Cliente)()

Using conexao As New MySqlConnection(connectionString)
conexao.Open()
Dim query As String = "SELECT * FROM sua_tabela"
Using comando As New MySqlCommand(query, conexao)
Using leitor As MySqlDataReader = comando.ExecuteReader()
While leitor.Read()
Dim cliente As New Cliente()
cliente.Codigo = Convert.ToInt32(leitor("Codigo"))
cliente.RazSoc = leitor("RazSoc").ToString()
cliente.DatCad = Convert.ToDateTime(leitor("DatCad"))
cliente.TipoClin = leitor("TipoClin").ToString()
cliente.TipoPes = leitor("TipoPes").ToString()
cliente.Enderec = leitor("Enderec").ToString()
cliente.Bairros = leitor("Bairros").ToString()
cliente.Cidades = leitor("Cidades").ToString()
cliente.Estados = leitor("Estados").ToString()
cliente.Ceps = leitor("Ceps").ToString()
cliente.Fones = leitor("Fones").ToString()
cliente.Celular = leitor("Celular").ToString()
cliente.Emails = leitor("Emails").ToString()
cliente.PJFisica = leitor("PJFisica").ToString()
cliente.InsEsta = leitor("InsEsta").ToString()
cliente.InsMuni = leitor("InsMuni").ToString()
cliente.Contato = leitor("Contato").ToString()
cliente.TipCont = leitor("TipCont").ToString()
clientes.Add(cliente)
End While
End Using
End Using
End Using

Return clientes
End Function
End Class

Public Class Cliente
Public Property Codigo As Integer
Public Property RazSoc As String
Public Property DatCad As DateTime
Public Property TipoClin As String
Public Property TipoPes As String
Public Property Enderec As String
Public Property Bairros As String
Public Property Cidades As String
Public Property Estados As String
Public Property Ceps As String
Public Property Fones As String
Public Property Celular As String
Public Property Emails As String
Public Property PJFisica As String
Public Property InsEsta As String
Public Property InsMuni As String
Public Property Contato As String
Public Property TipCont As String
End Class


Isso tudo acima, coloque em uma classe. Depois você pode passar os dados para o listview e coloquei também um evento de clique que pega os selecionados:

Private Sub PreencherListView()
For Each cliente As Cliente In clientes
Dim item As New ListViewItem(cliente.Codigo.ToString())
item.SubItems.Add(cliente.RazSoc)
item.SubItems.Add(cliente.DatCad.ToShortDateString())
' Adicione os outros campos conforme necessário

Dim checkBox As New CheckBox()
Dim checkBoxCell As New DataGridViewCheckBoxCell()
checkBoxCell.Value = False
item.Tag = cliente
item.Checked = False
listView1.Items.Add(item)
listView1.CheckBoxes = True
Next
End Sub

Private Sub btnGerarRelatorio_Click(sender As Object, e As EventArgs) Handles btnGerarRelatorio.Click
Dim clientesSelecionados As New List(Of Cliente)()

For Each item As ListViewItem In listView1.Items
If item.Checked Then
clientesSelecionados.Add(DirectCast(item.Tag, Cliente))
End If
Next

' Agora você pode passar a lista clientesSelecionados para o relatório
' e exibi-lo no ReportViewer
End Sub
Faça seu login para responder