Inquiridor
Como ordenar uma coluna num DataGridView vb.net

Pergunta
-
Olá amigos, gostaria de aprender como ordenar uma coluna num DataGridView.
Tenho um DataGridView e uma das colunas é composta de números que estão desordenados, como faço uma rotina que ordene de forma crescente estes números?
Simples assim:
1.345.625
300.268
2.689.450
780
depois de rodar a rotina, quero que eles fiquem assim na coluna:
780
300.268
1.345.625
2.689.450
Grato/Durval
Todas as Respostas
-
Pessoal, depois de fazer a pergunta, achei este comando:
DataGridView1.Sort(DataGridView1.Columns(17), ComponentModel.ListSortDirection.Ascending)
Mas ele ordena baseado só no primeiro número, então a ordenação acima fica assim:
1.345.625
2.689.450
300.268
780
Teria que ficar ordenado obedecendo os valores integrais dos números.
-
Durval
basicamente você precisa definir o tipo de dado no momento da ordenção.
Adicione o trecho abaixo no evento SortCompare do seu datagridview.
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare e.SortResult = CInt(e.CellValue1).CompareTo(CInt(e.CellValue2)) e.Handled = True End Sub
Natan
-
Olá Natan, pode me dar uma orientação como proceder para usar a tua explicação.
Essa é a rotina que busca os dados num arquivo txt e coloca-os no DataGridView1, na coluna 17 é que estão os números desordenados.
'rotina que mostra a grade preenchida
Private Sub LbVerGrade_Click(sender As Object, e As EventArgs) Handles LbVerGrade.Click
Dim i As Integer
Dim numCombinacao As Integer
If Not File.Exists(Arquivo) Then
Using sw As FileStream = File.Create(Arquivo)
End Using
End If
For i = 0 To lista.Count - 1
If lista.Contains("") Then
While lista.Contains("")
lista.Remove("")
End While
End If
Next
Dim table As DataTable
table = New DataTable
DataGridView1.DataSource = table
Dim dr As DataRow
DataGridView1.Visible = True
table.Columns.Add("Teste Número")
table.Columns.Add("Data")
table.Columns.Add("01")
table.Columns.Add("02")
table.Columns.Add("03")
table.Columns.Add("04")
table.Columns.Add("05")
table.Columns.Add("06")
table.Columns.Add("07")
table.Columns.Add("08")
table.Columns.Add("09")
table.Columns.Add("10")
table.Columns.Add("11")
table.Columns.Add("12")
table.Columns.Add("13")
table.Columns.Add("14")
table.Columns.Add("15")
table.Columns.Add("Número Combinação")
DataGridView1.[ReadOnly] = True
DataGridView1.Size = New Size(588, 910)
DataGridView1.RowHeadersVisible = False 'apaga a frente da grade
'define a largura das colunas
DataGridView1.Columns(0).Width = 53
DataGridView1.Columns(1).Width = 90
DataGridView1.Columns(17).Width = 90
DataGridView1.EnableHeadersVisualStyles = False
For u = 2 To 16
DataGridView1.Columns(u).Width = 22 'colunas das dezenas
Next
For u = 0 To 17
DataGridView1.Columns(u).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter 'culunas dos dados
DataGridView1.Columns(u).HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter 'colunas do cabeçalho
Next'rotina que percorre o arquivo
Using sr As StreamReader = File.OpenText(Arquivo)
Do While sr.Peek() >= 0
lista.Add(sr.ReadLine)
numTeste = CInt(lista(lista.Count - 1).Substring(0, 6))
dataTeste = CStr(lista(lista.Count - 1).Substring(6, 8))
i = 0
For u = 14 To 44 Step 2
i += 1
dez(i) = CInt(lista(lista.Count - 1).Substring(u, 2))
Next
numCombinacao = CInt(lista(lista.Count - 1).Substring(44, 7))
dr = table.NewRow
table.Rows.Add(dr)
dr(0) = numTeste.ToString("#,#")
dr(1) = dataTeste
For u = 1 To 15
dr(u + 1) = dez(u).ToString().PadLeft(2, "0"c)
Next
dr(17) = FormatNumber(numCombinacao, 0, 0)
Loop
End Using
End Sub -
Fala Durval
Seu método que popula o Datagridview é indiferente.
Mas no final, você deve manter o método que você encontrou:
DataGridView1.Sort(DataGridView1.Columns(17), ComponentModel.ListSortDirection.Ascending)
Além disso, você precisa incluir o trecho que comentei no evento SortCompare. Pra isso, selecione seu datagridview e vá na janela de eventos.
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare e.SortResult = CInt(e.CellValue1).CompareTo(CInt(e.CellValue2)) e.Handled = True End Sub
Natan
-
Olá Natan!
Fiz exatamente como me orientou, a ordenação ocorre, mas continua sendo da forma que expus lá no início. Ordena apenas baseado no primeiro digito, vou dar um exemplo:
Digamos que você tem 3 números dispostos numa coluna e quer ordenar, são eles:
61
49
288
Para haver uma ordenação correta, teriam que ficar assim:
49
61
288
mas com essa rotina, eles ficam assim:
288
49
61
Parece que ele entende que 288 é menor que todos, por começar por 2
-
Durval,
faz o seguinte, pra entender primeiro os métodos necessários.
Cria um novo form e adiciona apenas dois datagridviews.
No evento load do form, adiciona o trecho abaixo:
Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim col1 = New DataGridViewTextBoxColumn() col1.HeaderText = "Valor" Dim col2 = New DataGridViewTextBoxColumn() col2.HeaderText = "Valor" DataGridView1.Columns.Add(col1) DataGridView2.Columns.Add(col2) DataGridView1.Rows.Add("1.345.625") DataGridView1.Rows.Add("300.268") DataGridView1.Rows.Add("2.689.450") DataGridView1.Rows.Add("780") DataGridView2.Rows.Add("1.345.625") DataGridView2.Rows.Add("300.268") DataGridView2.Rows.Add("2.689.450") DataGridView2.Rows.Add("780") DataGridView1.Sort(DataGridView1.Columns(0), ComponentModel.ListSortDirection.Ascending) DataGridView2.Sort(DataGridView2.Columns(0), ComponentModel.ListSortDirection.Ascending) End Sub
Depois, apenas no datagridview1, adiciona o evento SortCompare conforme abaixo:
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare e.SortResult = CInt(e.CellValue1).CompareTo(CInt(e.CellValue2)) e.Handled = True End Sub
Esse deve ser o resultado:
Natan
-
Obrigado Natan pela paciência em me explicar e montar essa demonstração.
Peguei esse teu método e tentei adaptar para o que eu já tenho na minha rotina. O que me deixou um pouco confuso foi que você disse que o método de popular o DataGridView é indiferente, mas penso que é justamente isso que faz a diferença em não ordenar, veja a mistura que fiz e confirme que realmente pelo meu método de popular, não ordena.
Public Class Form1
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare
e.SortResult = CInt(e.CellValue1).CompareTo(CInt(e.CellValue2))
e.Handled = True
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As DataTable' <----- me refiro a esse método de popular a grade
table = New DataTable' será que existe uma outra saída para ordenar, mas usando este método?
DataGridView1.DataSource = table
Dim dr As DataRow
Dim mNum(3) As String
mNum(0) = "1345625"
mNum(1) = "300268"
mNum(2) = "2689450"
mNum(3) = "780"
table.Columns.Add("Valor")
Dim col1 = New DataGridViewTextBoxColumn()
col1.HeaderText = "Valor"
DataGridView1.Columns.Add(col1)
'DataGridView1.Rows.Add("1.345.625")
'DataGridView1.Rows.Add("300.268")
'DataGridView1.Rows.Add("2.689.450")
'DataGridView1.Rows.Add("780")
For u = 0 To 3
DataGridView1.Rows.Add(mNum(u))
Next
num(0) = mNum(0)
num(1) = mNum(1)
num(2) = mNum(2)
num(3) = mNum(3)
For u = 0 To 3
dr = table.NewRow
table.Rows.Add(dr)
dr(0) = mNum(u)
Next
DataGridView1.Sort(DataGridView1.Columns(0), ComponentModel.ListSortDirection.Ascending)
End Sub
End Class
-
Durval,
e realmente é indiferente.
A ordenação do datagridview pode ocorrer a qualquer momento após o objeto ter sido populado.
Imagina um dgv com 20 colunas, hora o usuário quer ordenar pela coluna 1, depois pela 15 e depois por outra coluna.
Não consigo testar isso que você postou agora, mas pra mim, apesar de não interferir no método de ordenação, não faz sentido você criar um datatable e depois enviar para o datagrid.
Uma coisa que me veio a mente foi se você apenas colou o evento SortCompare, não sei se no VB é assim também, mas no C# por exemplo, apenas colar o evento não o faz ser acionado, você deve atrelá-lo na janela de eventos conforme mostrei nas respostas anteriores.
Natan
-
Olá Natan, exclui o datatable, estava fazendo assim porque tinha seguido outras orientações e também por falta de experiência.
Montei agora seguindo tuas orientações, só estou me batendo para que cada dado fique na sua coluna, neste teu método, eu não aprendi como usar mais de uma coluna porque o teu exemplo é de 1 coluna só e o que estou fazendo usa 17 colunas.
Pode me dar mais essa força? Veja a rotina abaixo e me diga o que está faltando para que cada um dos 17 dados fique na sua devida coluna.
Imports System.IO
Public Class Form1
ReadOnly Arquivo As String = "C:\Usuario\Home\resultadosLotoFacil10.txt"
ReadOnly lista As New List(Of String)
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare
e.SortResult = CInt(e.CellValue1).CompareTo(CInt(e.CellValue2))
e.Handled = True
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim numTeste As String
Dim dataTeste As String
Dim numCombRe As String
Dim dez(25) As String
Dim i As Integer
If Not File.Exists(Arquivo) Then
Using sw As FileStream = File.Create(Arquivo)
End Using
End If
For i = 0 To lista.Count - 1
If lista.Contains("") Then
While lista.Contains("")
lista.Remove("")
End While
End If
Next
'rotina que percorre o arquivo e trás os dados
Using sr As StreamReader = File.OpenText(Arquivo)
Do While sr.Peek() >= 0
lista.Add(sr.ReadLine)
numTeste = CInt(lista(lista.Count - 1).Substring(0, 6))
DataGridView1.Rows.Add(FormatNumber(numTeste, 0, 0))
dataTeste = CStr(lista(lista.Count - 1).Substring(6, 8))
DataGridView1.Rows.Add(FormatNumber(dataTeste, 0, 0))
i = 0
For u = 14 To 44 Step 2
i += 1
dez(i) = CInt(lista(lista.Count - 1).Substring(u, 2))
'DataGridView1.Rows.Add(dez(i))
Next
numCombRe = CInt(lista(lista.Count - 1).Substring(44, 7))
'DataGridView1.Rows.Add(FormatNumber(numCombRe, 0, 0))
Loop
End Using
DataGridView1.Sort(DataGridView1.Columns(1), ComponentModel.ListSortDirection.Ascending)
End Sub
End Classo arquivo é este:
ele está em: ReadOnly Arquivo As String = "C:\Usuario\Home\resultadosLotoFacil10.txt"
00000129.09.030203050609101113141618202324252320460
00000206.10.030104050607091112131516192023241672792
00000313.10.030104060708091011121416172023241768502
00000420.10.030102040508101213161718192324250797917
00000527.10.030102040809111213151619202324250927594
00000603.11.030102040506071012151617192123250688694
00000710.11.030104070810121415161819212223251828417
00000817.11.030105060809101315161718192022251881427
00000924.11.030304050910111315161719202124252899886
00001001.12.030203040506080910111214192023242010674
00001108.12.030206070809101112161920222324252741364
00001215.12.030102040507080910111214161724250739667
00001322.12.030305060708091011131415161719232983663
00001429.12.030102050607091314151819202123250975798
00001505.01.040102040608101215161819212324250873999
00001612.01.040205060708101213151719212324252677246
00001719.01.040102030506070913141617181920210388862
00001826.01.040206070810111415171819202223242749567
00001902.02.040205060708101113141516172023242675366
00002009.02.040304060708091014161718192023242910574
00002116.02.040102040508111416181920222324250801162
00002225.02.040102030405060709101213141522250021492
00002301.03.040103040506081011121416171819201206559
00002408.03.040102030507101114171920212324250483671
00002515.03.040102030405060709131416202223240029500
00002622.03.040507080910111314161719202122233243161
00002729.03.040306081011121314151820212224253082588
00002805.04.040103070910111213141617181920211626983
00002912.04.040104050608091314161719202122241696216
00003019.04.040102030406070811141719202122230205685 -
Dei uma pesquisada e fiz assim:
DataGridView1.Rows.Add(FormatNumber(numTeste, 0, 0), dataTeste, dez(1).ToString().PadLeft(2, "0"c), dez(2).ToString().PadLeft(2, "0"c), dez(3).ToString().PadLeft(2, "0"c), dez(4).ToString().PadLeft(2, "0"c), dez(5).ToString().PadLeft(2, "0"c), dez(6).ToString().PadLeft(2, "0"c), dez(7).ToString().PadLeft(2, "0"c), dez(8).ToString().PadLeft(2, "0"c), dez(9).ToString().PadLeft(2, "0"c), dez(10).ToString().PadLeft(2, "0"c), dez(11).ToString().PadLeft(2, "0"c), dez(12).ToString().PadLeft(2, "0"c), dez(13).ToString().PadLeft(2, "0"c), dez(14).ToString().PadLeft(2, "0"c), dez(15).ToString().PadLeft(2, "0"c), FormatNumber(numCombRe, 0, 0))
Funcionou, mas não sei se é o modo mais correto....
-
Fala Durval!
Altere a última linha do seu método:
DataGridView1.Sort(DataGridView1.Columns(0), ComponentModel.ListSortDirection.Ascending)
Lembre-se que um array sempre inicia o contador no Zero, então, o índice da primeira coluna do seu datagridview é 0 e não 1.
Natan