Ir para conteúdo
Fórum Script Brasil
  • 0

Ordenar coluna do listview


Flecha

Pergunta

Olá,

Tenho a sub abaixo para ordenar a coluna do listview:

Private Sub lvwCustomer_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
'-------------------------------------------------------------------------
    
    ' sort the listview on the column clicked
    With lvwCustomer
        If (.Sorted) And (ColumnHeader.SubItemIndex = .SortKey) Then
            If .SortOrder = lvwAscending Then
                .SortOrder = lvwDescending
            Else
                .SortOrder = lvwAscending
            End If
        Else
            .Sorted = True
            .SortKey = ColumnHeader.SubItemIndex
            .SortOrder = lvwAscending
        End If
        .Refresh
    End With
        
    ' If an item was selected prior to the sort,
    ' make sure it is still visible now that the sort is done.
    If Not lvwCustomer.SelectedItem Is Nothing Then
        lvwCustomer.SelectedItem.EnsureVisible
    End If

End Sub

Nas colunas com campo texto sem problemas, mas quando quero ordenar uma coluna que o tipo é numerica não dá certo.

fica assim:

1

10

100

101

109

11

111

112

....

...

9

90

92

99

O que tem que alterar, para ordenar como texto?

Flecha

Editado por Flecha
Link para o comentário
Compartilhar em outros sites

3 respostass a esta questão

Posts Recomendados

  • 0

é, flecha, os itens da listview são todos strings. apesar de estar escrito 100, ele interpreta como "100". como se fosse texto.

não sei se tem uma forma de driblar isso, mas tem umas gambiarras q da pra fazer.

tipo, você podia escrever "001" em vez de "1". isso vai levar a ordenar do jeito q você quer.

ai se você não quer q apareca "001", então você pode escrever "1" normalmente, e escrever 001 numa coluna escondida. ai na hora q ele clicasse nessa coluna onde estao escrito os numeros, você mandava ordenar pela coluna oculta. so o problema é q se não me engano, as colunas do listbox não tem uma propriedade visible ou qualquer coisa assim e pra esconde-las você teria q por width = 0. so q se o cara puxar pra aumentar a coluna anterior, ele vai acabar revelando a coluna escondida.

uma outra opcao seria, na hora q o cara clicasse nessa coluna, você apagava todos os dados do listview e preenchia novamente já devidamente ordenado.

ou ainda, no momento do clique, você lia linha por linha adicionando os zeros na frente (trocando "1" por "001"), mandava ordenar e logo depois voltava pro texto sem zeros.

enfim, esse problema q você ta tendo é um q já aconteceu com mta gente, principalmente porque a ordenacao não esta sendo feita de forma errada. ele so le a string e ordena de acordo com os caracteres.

não sei se tem muito a se fazer nesses casos, mas dependendo do caso, normalmente se da um jeito pra driblar isso, nem q for com uma gambiarra.

Link para o comentário
Compartilhar em outros sites

  • 0

Kuroi,

Resolvido, achei uma sub que é exatamente para isso, ela reconhece se é "string" "date" ou "numero" pela propriedade TAG da listview

onde eu declaro o tamanho conforme abaixo

Private Sub SetupCustLVCols() 'Largura Nome e Ordem das colunas do ListView
'-----------------------------------------------------------------------------
                                 
    With lvwCustomer
        .ColumnHeaders.Clear
        .ColumnHeaders.Add(, , "Nome", .Width * 0.25).Tag = "string"
        .ColumnHeaders.Add(, , "RG", .Width * 0.11).Tag = "number"
Depois com essa sub e a função abaixo resolve o problema
Private Sub lvwCustomer_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
'-------------------------------------------------------------------------
    
   On Error Resume Next
    
     
   
    
    ' Começa ordenar o listview pela coluna clicada
    
    With lvwCustomer
    
        ' Display the hourglass cursor whilst sorting
        
        Dim lngCursor As Long
        lngCursor = .MousePointer
        .MousePointer = vbHourglass
        
        ' Prevent the ListView control from updating on screen -
        ' this is to hide the changes being made to the listitems
        ' and also to speed up the sort
        
        
        
        ' Check the data type of the column being sorted,
        ' and act accordingly
        
        Dim l As Long
        Dim strFormat As String
        Dim strData() As String
        
        Dim lngIndex As Long
        lngIndex = ColumnHeader.Index - 1
    
        Select Case UCase$(ColumnHeader.Tag)
        Case "DATE"
        
            ' Sort by date.
            
            strFormat = "YYYYMMDDHhNnSs"
        
            ' Loop through the values in this column. Re-format
            ' the dates so as they can be sorted alphabetically,
            ' having already stored their visible values in the
            ' tag, along with the tag's original value
        
            With .ListItems
                If (lngIndex > 0) Then
                    For l = 1 To .Count
                        With .Item(l).ListSubItems(lngIndex)
                            .Tag = .text & Chr$(0) & .Tag
                            If IsDate(.text) Then
                                .text = Format(CDate(.text), _
                                                    strFormat)
                            Else
                                .text = ""
                            End If
                        End With
                    Next l
                Else
                    For l = 1 To .Count
                        With .Item(l)
                            .Tag = .text & Chr$(0) & .Tag
                            If IsDate(.text) Then
                                .text = Format(CDate(.text), _
                                                    strFormat)
                            Else
                                .text = ""
                            End If
                        End With
                    Next l
                End If
            End With
            
            ' Sort the list alphabetically by this column
            
            .SortOrder = (.SortOrder + 1) Mod 2
            .SortKey = ColumnHeader.Index - 1
            .Sorted = True
            
            ' Restore the previous values to the 'cells' in this
            ' column of the list from the tags, and also restore
            ' the tags to their original values
            
            With .ListItems
                If (lngIndex > 0) Then
                    For l = 1 To .Count
                        With .Item(l).ListSubItems(lngIndex)
                            strData = Split(.Tag, Chr$(0))
                            .text = strData(0)
                            .Tag = strData(1)
                        End With
                    Next l
                Else
                    For l = 1 To .Count
                        With .Item(l)
                            strData = Split(.Tag, Chr$(0))
                            .text = strData(0)
                            .Tag = strData(1)
                        End With
                    Next l
                End If
            End With
            
        Case "NUMBER"
        
            ' Sort Numerically
        
            strFormat = String(30, "0") & "." & String(30, "0")
        
            ' Loop through the values in this column. Re-format the values so as they
            ' can be sorted alphabetically, having already stored their visible
            ' values in the tag, along with the tag's original value
        
            With .ListItems
                If (lngIndex > 0) Then
                    For l = 1 To .Count
                        With .Item(l).ListSubItems(lngIndex)
                            .Tag = .text & Chr$(0) & .Tag
                            If IsNumeric(.text) Then
                                If CDbl(.text) >= 0 Then
                                    .text = Format(CDbl(.text), _
                                        strFormat)
                                Else
                                    .text = "&" & InvNumber( _
                                        Format(0 - CDbl(.text), _
                                        strFormat))
                                End If
                            Else
                                .text = ""
                            End If
                        End With
                    Next l
                Else
                    For l = 1 To .Count
                        With .Item(l)
                            .Tag = .text & Chr$(0) & .Tag
                            If IsNumeric(.text) Then
                                If CDbl(.text) >= 0 Then
                                    .text = Format(CDbl(.text), _
                                        strFormat)
                                Else
                                    .text = "&" & InvNumber( _
                                        Format(0 - CDbl(.text), _
                                        strFormat))
                                End If
                            Else
                                .text = ""
                            End If
                        End With
                    Next l
                End If
            End With
            
            ' Sort the list alphabetically by this column
            
            .SortOrder = (.SortOrder + 1) Mod 2
            .SortKey = ColumnHeader.Index - 1
            .Sorted = True
            
            ' Restore the previous values to the 'cells' in this
            ' column of the list from the tags, and also restore
            ' the tags to their original values
            
            With .ListItems
                If (lngIndex > 0) Then
                    For l = 1 To .Count
                        With .Item(l).ListSubItems(lngIndex)
                            strData = Split(.Tag, Chr$(0))
                            .text = strData(0)
                            .Tag = strData(1)
                        End With
                    Next l
                Else
                    For l = 1 To .Count
                        With .Item(l)
                            strData = Split(.Tag, Chr$(0))
                            .text = strData(0)
                            .Tag = strData(1)
                        End With
                    Next l
                End If
            End With
        
        Case Else   ' Assume sort by string
            
            ' Sort alphabetically. This is the only sort provided
            ' by the MS ListView control (at this time), and as
            ' such we don't really need to do much here
        
            .SortOrder = (.SortOrder + 1) Mod 2
            .SortKey = ColumnHeader.Index - 1
            .Sorted = True
            
        End Select
    
       
        
        .MousePointer = lngCursor
    
    End With
    
    
   
    
 '******************************************************************
        
ESSA ERA A SUB ANTIGA PARA ORDENAR    
    ' sort the listview on the column clicked
    
'
'    With lvwCustomer
'        If (.Sorted) And (ColumnHeader.SubItemIndex = .SortKey) Then
'            If .SortOrder = lvwAscending Then
'                .SortOrder = lvwDescending
'            Else
'                .SortOrder = lvwAscending
'            End If
'        Else
'            .Sorted = True
'            .SortKey = ColumnHeader.SubItemIndex
'            .SortOrder = lvwAscending
'        End If
'        .Refresh
'    End With
        
            ' If an item was selected prior to the sort,
            ' make sure it is still visible now that the sort is done.
'    If Not lvwCustomer.SelectedItem Is Nothing Then
'        lvwCustomer.SelectedItem.EnsureVisible
'    End If

End Sub


'****************************************************************
' InvNumber
' Function used to enable negative numbers to be sorted
' alphabetically by switching the characters
'----------------------------------------------------------------

Private Function InvNumber(ByVal Number As String) As String
    Static i As Integer
    For i = 1 To Len(Number)
        Select Case Mid$(Number, i, 1)
        Case "-": Mid$(Number, i, 1) = " "
        Case "0": Mid$(Number, i, 1) = "9"
        Case "1": Mid$(Number, i, 1) = "8"
        Case "2": Mid$(Number, i, 1) = "7"
        Case "3": Mid$(Number, i, 1) = "6"
        Case "4": Mid$(Number, i, 1) = "5"
        Case "5": Mid$(Number, i, 1) = "4"
        Case "6": Mid$(Number, i, 1) = "3"
        Case "7": Mid$(Number, i, 1) = "2"
        Case "8": Mid$(Number, i, 1) = "1"
        Case "9": Mid$(Number, i, 1) = "0"
        End Select
    Next
    InvNumber = Number
End Function

Flecha

Editado por Flecha
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      652k
×
×
  • Criar Novo...