Notifications
Clear all

Colocar ordem crescente coluna data

12 Posts
4 Usuários
0 Reactions
2,114 Visualizações
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

Amigos
tenho um listview com várias colunas e uma das colunas é data e preciso colocar em ordem crescente ou decrescente, conforme a minha necessidade, utilizando o comando conhecido e descrito abaixo:

Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
' ordena a coluna ao clicar no título da mesma
ListView1.Sorted = False
    ListView1.SortKey = ColumnHeader.Index - 1
   
    If ListView1.SortOrder = lvwAscending Then
        ListView1.SortOrder = lvwDescending
        Else
        ListView1.SortOrder = lvwAscending
    End If
   
    ListView1.Sorted = True
    
End Sub

acontece que a coluna data não atende ao comando.

Obs.: Coloquei a coluna na planilha como formato de número e aí funciona corretamente, porém não consigo formatar a coluna como data. Assim que coloco para formatar a coluna em data, as datas ficam embaralhadas.
Segue abaixo as formatações utilizadas. A formatação funciona, porém não coloca em ordem crescente e decrescente corretamente.

li.ListSubItems.Add Text:=Format(CDate(rst.Fields(1).Value))
li.ListSubItems.Add Text:=Format(rst.Fields(1).Value, "dd/mm/yyyy")
li.ListSubItems.Add Text:=Format(rst.Fields(1).Value, "cdata")

o que devo fazer?

 
Postado : 13/08/2016 10:33 am
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

Será que é possível gravar na planilha em formato de número e no listview mostrar formato data? Se isto for possível talvez tenha como resolver esta questão. ...

 
Postado : 14/08/2016 11:52 am
(@osvaldomp)
Posts: 858
Prominent Member
 

Conforme indicado no site abaixo não é possível ordenar por data diretamente. Transcrevi abaixo o trecho de interesse.
https://support.microsoft.com/en-us/kb/170884
"When using a Listview control, you can set the Sorted property for the control to sort the list alphabetically. However, the Listview control does not expose a property or method for sorting a list by date."

Uma forma de contornar é acrescentar no seu código comandos para formatar as datas como números, ordenar e depois retornar para o formato data, conforme abaixo.

http://www.vbforums.com/showthread.php?285543-RESOLVED-Sorting-Date-Time-in-ListView
You have to do 3 Steps:
1. Change the format of the data in the columns ( you can figuer it out by the name of the column)

If ColumnHeader.Text = "DATE_COLUMN" Then
For Each oListItem In ListView.ListItems
oListItem.SubItems(iIndex) = _
Format$(oListItem.ListSubItems(iIndex).Text, _
"yyyymmddHHMMSS")
Next oListItem
End If

2. Sort it

3. change the format back:

If ColumnHeader.Text = "DATE_COLUMN" Then
For Each oListItem In ListView.ListItems
oListItem.SubItems(iIndex) = _
Format(CDate(Format(oListItem.ListSubItems(iIndex).Text, _
"####/##/## ##:##:##")), "mm/dd/yyyy hh:mm:ss AM/PM")
Next oListItem
End If

Osvaldo

 
Postado : 14/08/2016 5:22 pm
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Tem vezes que a MS me surpreende, o artigo que o colega indicou foi publicado em 04/2015, porem no modelo anexo que foi feito em 2012 eu já utilizava a rotina citada pelo NERIS para classificar o ListView por Datas e sempre funcionou como podem ver no modelo, até deixei as datas fora de ordem, é só clicar nas colunas e são classificadas pela mesma e com a coluna data não é diferente.

Na questão do colega NERIS pelo que deixa a entender nas linhas :
li.ListSubItems.Add Text:=Format(CDate(rst.Fields(1).Value))
li.ListSubItems.Add Text:=Format(rst.Fields(1).Value, "dd/mm/yyyy")
li.ListSubItems.Add Text:=Format(rst.Fields(1).Value, "cdata")

e :
não consigo formatar a coluna como data

pelo que entendi e acredito que o erro se de devido a estar utilizando uma query sql já que cita rst.Fields, e provavelmente a formatação não esteja de acordo, uma vez que no excel temos sistemas de datas diferentes e não assimiladas ao idioma portugues.

Segue o modelo:
Classificar ListView por datas

[]s

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 14/08/2016 9:12 pm
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

Bom dia Mauro
Veja só: o seu modelo funciona perfeitamente, mas tem um porém, coloca alguns dos seus ítens como mês 03 e veja o que ele faz:
14/02/2012
14/03/2012
15/02/2012, etc....
ele respeita somente o dia. Tem que respeitar o dia, mês e ano.

Vamos ver o que alterar para que isto aconteça.
vou procurando também, se encontrar, eu posto.
abraço

 
Postado : 15/08/2016 8:07 am
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

Amigo Oswaldo
Não entendi onde devo inserir o comando citado no seu post

Tentei fazer o seguinte:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
With ListView1

If ColumnHeader.Text = "DATE_COLUMN" Then
For Each oListItem In ListView.ListItems
oListItem.SubItems(iIndex) = _
Format$(oListItem.ListSubItems(iIndex).Text, _
"yyyymmddHHMMSS")
Next oListItem
End If

If .SortKey = ColumnHeader.Index - 1 Then
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
Else
.SortKey = ColumnHeader.Index - 1
End If
.Sorted = True
End With

If ColumnHeader.Text = "DATE_COLUMN" Then
For Each oListItem In ListView.ListItems
oListItem.SubItems(iIndex) = _
Format(CDate(Format(oListItem.ListSubItems(iIndex).Text, _
"####/##/## ##:##:##")), "mm/dd/yyyy hh:mm:ss AM/PM")
Next oListItem
End If

End Sub

Acho que não é assim.... não entendi.
Além disto, dá erro no oListItem

Pode ajudar mais um pouco?
Vamos vendo tb com o Mauro....
Acharemos a solução.

 
Postado : 15/08/2016 8:15 am
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

outra resposta que achei foi a seguinte:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)

Dim Item As ListItem

If ColumnHeader.Index = 2 Then
For Each Item In ListView1.ListItems
Item.SubItems(1) = Format$(Item.ListSubItems(1), "yyyymmdd")
Next Item
End If

With ListView1
.SortKey = ColumnHeader.Index - 1
.Sorted = True
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
End With

If ColumnHeader.Index = 2 Then
For Each Item In ListView1.ListItems
Item.SubItems(1) = Format$(Item.ListSubItems(1), "yyyy/mm/dd")
Next Item
End If
End Sub

transforma o dia em número pelo ano/mês/dia e faz a ordem e retorna ao normal. Porém está dando um erro ao retornar.....

 
Postado : 15/08/2016 9:26 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

Verdade NERIS, como na época o modelo enviado tinham somente estas datas não me dei conta, e pelo jeito nem quem havia solicitado, se não já teria percebido esta falha.

Temos um outro recurso que é utilizando TAGs para definir os tipos de dados e classificar, não tenho no momento as referencias de onde foi tirado, mas no anexo tem alguns links que foi utilizado, baixe o modelo e veja que a classificação ocorre corretamente por dia, mes e ano.
Veja se consegue adapatr ao seu modelo.

Classificar Listview por Datas

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 15/08/2016 9:38 am
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

A resposta que achei está abaixo e funciona, porém eu preciso que ela seja feita mais 5 colunas. Alguém sabe como fazer?
https://www.gittprogram.com/question/53 ... -date.html

Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
'Dim Item As ListItem 'Item is a reserved word; not a good idea to use as variable
Dim lstItem As ListItem 'Using Prefixes avoids reserved words
Dim arrSplit

If ColumnHeader.Index = 2 Then
For Each lstItem In ListView1.ListItems
'Including the slashes permits the use of Split function further down.
lstItem.SubItems(1) = Format$(lstItem.ListSubItems(1), "yyyy/mm/dd")

Next lstItem
End If

With ListView1
.SortKey = ColumnHeader.Index - 1
.Sorted = True
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
End With

If ColumnHeader.Index = 2 Then
For Each lstItem In ListView1.ListItems
'Split function creates a zero based array irrespective of option base setting
arrSplit = Split(lstItem.SubItems(1), "/")
lstItem.SubItems(1) = Format$(DateSerial(arrSplit(0), arrSplit(1), arrSplit(2)), "dd/mm/yyyy")

Next lstItem
End If

End Sub

Sei que o Mauro está se empenhando para me ajudar... mas enquanto ele fazia a alteração eu achei esta e tb funciona. Eu nao consegui fazer a macro dele funcionar corretamente....não sei onde errei.

Vejam só: além da coluna do subItem(1) tenho a subItem 8,9, 10 e 11.

Aceito sugestões.
Obrigado

 
Postado : 15/08/2016 10:25 am
(@edcronos2)
Posts: 346
Reputable Member
 

eu sou o ultimo que devia falar isso
mas o certo seria postar o seu modelo

tinha reparado que não era em apenas a coluna de data afinal são datas de alguma coisa
mas não seria mais facil ordenar antes de mandar para o listview ?
de onde vem os dados e qual o processo de preenchimento da listview ?

modos acho que tem um monte
se pode tbm usar uma aba auxiliar para esse tipo de processo
particularmente eu passaria para um array ordenava e então passaria para o listview ,
para transformar datas em valores numericos se usa o datavalue

 
Postado : 15/08/2016 10:48 am
Fernando Fernandes
(@fernandofernandes)
Posts: 43750
Illustrious Member
 

O que o Edcronos comentou faz sentido e é mais simples, classificar antes na aba e depois carregar o listiview.
Enquanto você avalia a sugestão dele veja se o ajuste na rotina está da forma que pretende, pelo que entendi você tem 05 colunas do ListView com datas.

Observe com atenção que o numero da Coluna indicado em ColumnHeader.Index é diferente do "SubItems", isto porque para um o excel capta o numero na ordem iniciando em "1" e para outro iniciando em "0 - zero".
Para alterar para outras colunas é só ajustar nas duas linhas :
If ColumnHeader.Index = 2 Or ColumnHeader.Index = 3 Or ColumnHeader.Index = 5 Then

Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
    'Dim Item As ListItem 'Item is a reserved word; not a good idea to use as variable
    Dim lstItem As ListItem 'Using Prefixes avoids reserved words
    Dim arrSplit
    Dim sSub
    
    'Altere aqui as Colunas
    If ColumnHeader.Index = 2 Or ColumnHeader.Index = 3 Or ColumnHeader.Index = 5 Then
        'Armazenamos o numero da coluna clicada (Index) -1 para os SubItems
        sSub = ColumnHeader.Index - 1
        
        For Each lstItem In ListView1.ListItems
            'Including the slashes permits the use of Split function further down.
            lstItem.SubItems(sSub) = Format$(lstItem.ListSubItems(sSub), "yyyy/mm/dd")
        Next lstItem
    End If

    With ListView1
            .SortKey = ColumnHeader.Index - 1
            .Sorted = True
        If .SortOrder = lvwAscending Then
            .SortOrder = lvwDescending
        Else
            .SortOrder = lvwAscending
        End If
    End With
    
    'Altere aqui as Colunas
    If ColumnHeader.Index = 2 Or ColumnHeader.Index = 3 Or ColumnHeader.Index = 5 Then
        For Each lstItem In ListView1.ListItems
            'Split function creates a zero based array irrespective of option base setting
            arrSplit = Split(lstItem.SubItems(sSub), "/")
            lstItem.SubItems(sSub) = Format$(DateSerial(arrSplit(0), arrSplit(1), arrSplit(2)), "dd/mm/yyyy")
        Next lstItem
    End If

End Sub

[]s

Existem mil maneiras de preparar Neston. Invente a sua!
http://www.youtube.com/ExpressoExcel

 
Postado : 15/08/2016 11:21 am
NERI S
(@neri-s)
Posts: 0
Estimable Member
Topic starter
 

Agora está funcionando certo. Mas tive que colocar um "IF" pois nem todas as datas foram preenchidas.

Ficou assim:
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
'Dim Item As ListItem 'Item is a reserved word; not a good idea to use as variable
Dim lstItem As ListItem 'Using Prefixes avoids reserved words
Dim arrSplit
Dim sSub

'Altere aqui as Colunas
If ColumnHeader.Index = 2 Or ColumnHeader.Index = 9 Or ColumnHeader.Index = 10 Or ColumnHeader.Index = 11 Or ColumnHeader.Index = 12 Then
'Armazenamos o numero da coluna clicada (Index) -1 para os SubItems
sSub = ColumnHeader.Index - 1

For Each lstItem In ListView1.ListItems
'Including the slashes permits the use of Split function further down.
If lstItem.SubItems(sSub) <> "" Then
lstItem.SubItems(sSub) = Format$(lstItem.ListSubItems(sSub), "yyyy/mm/dd")
End If
Next lstItem
End If

With ListView1
.SortKey = ColumnHeader.Index - 1
.Sorted = True
If .SortOrder = lvwAscending Then
.SortOrder = lvwDescending
Else
.SortOrder = lvwAscending
End If
End With

'Altere aqui as Colunas
If ColumnHeader.Index = 2 Or ColumnHeader.Index = 9 Or ColumnHeader.Index = 10 Or ColumnHeader.Index = 11 Or ColumnHeader.Index = 12 Then
For Each lstItem In ListView1.ListItems
'Split function creates a zero based array irrespective of option base setting
If lstItem.SubItems(sSub) <> "" Then
arrSplit = Split(lstItem.SubItems(sSub), "/")
lstItem.SubItems(sSub) = Format$(DateSerial(arrSplit(0), arrSplit(1), arrSplit(2)), "dd/mm/yyyy")
End If
Next lstItem
End If

End Sub

Obrigado a todos pela ajuda....
Abraço

 
Postado : 15/08/2016 1:57 pm