ORDENAR ARRAY

ROBSON 07/10/2011 10:28:08
#386185
Olá Pessoal,
Eu preciso ordenar um conjunto de Arrays numericos do Maior para o Menor ou vice-versa.
Exemplo:
Array (1) = 150
Array (2) = 136
Array (3) = 110
Array (4) = 158
Array (5) = 180
Array (6) = 232
Array (7) = 50

Vale lembrar que a quantidade de Arrays não é fixo. Em determinados momentos eu terei 7, talvez apenas 5 ou até 50.
Neste caso eu defini uma variável Array no valor de 100 (Dim Conteudo_Array(100) As Integer),
Mas só preciso ordenar os valores que forem preenchidos.

Este trecho de codigo será usado em um sistema de vendas em que o cliente deseja saber quais produtos foram Mais vendidos em um determinado periodo.
Ja consegui resgatar os produtos dentro de periodo, ja consegui calcular a quantidade de vendas de cada produto e coloquei o resultado dentro do control Array e preciso apresentar o resultado dentro de um List Box. Eu poderia ate usar a propriedade Sorted do List Box, mas nao funciona pois o list box só ordena se for texto (string).
Pensei em colocar o resultado dentro de uma tabela temporária e assim bastava usar o ORDER BY, mas acredito que haja um solução mais simples.

Eu achei um codigo no VBWeb, mas estou meio enrrolado para usar.
Veja o codigo abaixo:
----------------------------------------------------------------------------------------------------------
Sub OrdemAlfa(sArray(), ByVal ini, ByVal fim) [ô]ORDENAR ARRAY

Dim i, j, aux
For i = ini To fim - 1
For j = i + 1 To fim
If StrComp(sArray(i), sArray(j), 1) = 1 Then
aux = sArray(i)
sArray(i) = sArray(j)
sArray(j) = aux
End If
Next
Next

End Sub

------------------------------------------------
Se alguem me passar alguma informação eu agradeço
FEDERHEN 07/10/2011 11:19:41
#386205
Resposta escolhida

Dim Vetor(5) as Integer
Dim I,Cont,X as Integer
Array (1) = 136
Array (2) = 110
Array (3) = 158
Array (4) = 180
Array (5) = 232
Array (6) = 50

[ô]Devemos comparar cada posição do vetor com as demais e se o valor for menor eles terão suas posições trocadas.
For i = 1 To 5
For cont = 1 To 5
If Array (i) < Array (cont) Then
X = Array (i)
Array (i) = Array (cont)
Array (cont) = X
End If
Next cont
Next i
MARCELO.TREZE 07/10/2011 11:26:04
#386209
Bom vou tentar explicar eainda fazer uma pequena alteração

veja
[txt-color=#007100][ô] primeiro a sub pede o inicio da array e o fim 
[ô] mas poderiamos usar o ubound e lbound para isto[/txt-color]
Sub OrdemAlfa(sArray() As String)
Dim A, B, aux
For A = LBound(sArray) To UBound(sArray) - 1[txt-color=#007100] [ô]este laço irá verficar da primeira a penultima array[/txt-color]
For B = A + 1 To UBound(sArray)[txt-color=#007100] [ô] este laço verificará da segunda a ultima array[/txt-color]
If StrComp(sArray(A), sArray(B), 1) = 1 Then [txt-color=#007100][ô]se A for maior que B retornará 1 caso contrario retornará -1[/txt-color]
aux = sArray(A)[txt-color=#007100] [ô] como A é maior que B então armazena-se en aux o valor de A[/txt-color]
sArray(A) = sArray(B)[txt-color=#007100] [ô]o Valor de A é substituido pelo valor de B que é o menor[/txt-color]
sArray(B) = aux[txt-color=#007100] [ô] e B é substitudi pelo valor de A que é Maior criando assim a ordem[/txt-color]
End If
Next B
Next A
End Sub



espero não ter confundido sua cabeça, rs

KERPLUNK 07/10/2011 11:54:12
#386215
Bom, eu faria um recordset em memória e deixaria a ordenação a cargo do ADO:
Dim rs As New ADODB.Recordset
rs.Fields.Append [Ô]valor[Ô], adInteger
rs.Open
rs.Sort = [Ô]valor ASC[Ô]
rs.AddNew
rs([Ô]valor[Ô]) = 150
rs.AddNew
rs([Ô]valor[Ô]) = 150
rs.AddNew
rs([Ô]valor[Ô]) = 136
rs.AddNew
rs([Ô]valor[Ô]) = 110
rs.AddNew
rs([Ô]valor[Ô]) = 158
rs.AddNew
rs([Ô]valor[Ô]) = 180
rs.AddNew
rs([Ô]valor[Ô]) = 232
rs.AddNew
rs([Ô]valor[Ô]) = 50

Se conferir, esse recordset vai estar ordenado:
Do While Not rs.EOF
List1.AddItem rs([Ô]valor[Ô])
rs.MoveNext
Loop
KERPLUNK 07/10/2011 12:02:23
#386216
Dá até pra fazer uma função pra isso:
Private Function OrdenarArray(vetor As Variant) As Variant
Dim rs As New ADODB.Recordset
rs.Fields.Append [Ô]valor[Ô], adInteger
rs.Open
rs.Sort = [Ô]valor ASC[Ô]

Dim registros As Integer
For i% = 0 To UBound(vetor)
rs.AddNew
rs([Ô]valor[Ô]) = vetor(i%)
registros = registros + 1
Next i%

Dim retorno()
Dim regAtual As Integer
regAtual = 0
Do While Not rs.EOF
ReDim Preserve retorno(regAtual + 1)
retorno(regAtual) = rs([Ô]valor[Ô])
regAtual = regAtual + 1
rs.MoveNext
Loop
ReDim Preserve retorno(regAtual - 1)
OrdenarArray = retorno
End Function

E para chamar:
Dim items(6)

items(1) = 136
items(2) = 110
items(3) = 158
items(4) = 180
items(5) = 232
items(6) = 50

Dim ordenados
ordenados = OrdenarArray(items)
[ô]aqui o vetor [Ô]ordenados[Ô] vai estar em ordem...


ROBSON 07/10/2011 13:23:05
#386226
Olá Marcelo Treze
Sua explicação foi bastante elucidativa. Parabens.

Olá Kerplunk,
Sua ideia é bastante criativa, mas o numero de arrays é variavel, Em determinados momentos eu terei 7, talvez apenas 5 ou até 50.
Por isto eu defini uma Variavel Arrray acima do valor que irei usar (100). Já vi inclusive em outro momento uma maneira de definir um array em tempo de execução para não gastar memoria, mas vou deixar isto para depois. No momento agora só preciso ordenar o resultado e apresentar em um list box.

Estou estudado as sugestões de Federhen e do Marcelo Treze e transformar em um Função.
O principal objetivo é colocar o resultado dentro de um List box ordenado do Maior para o menor.

Ex.
nome do produto em 1º lugar em venda [espaco] valor total [espaco]. quantidade vendida [232]
nome do produto em 2º lugar em venda [espaco] valor total [espaco]. quantidade vendida [180]
nome do produto em 3º lugar em venda [espaco] valor total [espaco]. quantidade vendida [158]
nome do produto em 4º lugar em venda [espaco] valor total [espaco]. quantidade vendida [150]
nome do produto em 5º lugar em venda [espaco] valor total [espaco]. quantidade vendida [136]
nome do produto em 6º lugar em venda [espaco] valor total [espaco]. quantidade vendida [110]
etc...

KERPLUNK 07/10/2011 13:38:54
#386229
A função que te passei, não leva em conta o número de elementos no array, tanto faz se são 5 ou 5 milhões...
ROBSON 07/10/2011 13:48:04
#386232
Ola Kerplunk,
Voce está com a razão, a função que voce sugeriu nao tem limites de elementos do Array
ROBSON 09/10/2011 17:44:41
#386332

Olá Pessoal,
Usei o codigo do FEDERHEN e funcionou perfeitamente.

Agradeço ao Marcelo Treze pela [ô]aula[ô] em explicar o funcionamento da rotina.

Agradeço ao KERPLUNK pela sua sugestão em criar um Recordset em memoria. Anotei o codigo e usarei em uma situaçção mas complexa.
Tópico encerrado , respostas não são mais permitidas