none
Como ordenar uma coluna num DataGridView vb.net RRS feed

  • 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

    quinta-feira, 11 de março de 2021 05:49

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.

    quinta-feira, 11 de março de 2021 06:25
  • 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

    quinta-feira, 11 de março de 2021 12:41
  • 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

    quinta-feira, 11 de março de 2021 20:41
  • 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

    quinta-feira, 11 de março de 2021 22:05
  • 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

     

    sexta-feira, 12 de março de 2021 00:43
  • 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

    sexta-feira, 12 de março de 2021 12:03
  • 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


    sábado, 13 de março de 2021 04:58
  • 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

    sábado, 13 de março de 2021 13:28
  • 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 Class

    o 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

    domingo, 14 de março de 2021 05:37
  • 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....

    domingo, 14 de março de 2021 07:23
  • 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

    segunda-feira, 15 de março de 2021 11:58