ERRO EM CÓDIGO

KELLY 13/11/2014 23:01:13
#442501
Boa noite pessoal, estou aqui novamente com um grande problema!

Fiz uma função para ordenar arrays que armazenam Strings e quero que ela também que ela ordene de forma correga números. Strings ela ordena normalmente, mas números não. Alguém poderia me ajudar para que eu possa ordenar tanto Strings como Números?

Segue meu código:

Public Function Ordenar(strLista() As String) As Variant
Dim x As Integer
Dim i As Integer
Dim ii As Integer
Dim j As Integer
Dim jj As Integer
Dim Linha As Integer
Dim minValue As Integer
Dim Cont As Integer
Dim tmpValue As String
Dim tmpArray() As String
Dim Elemento() As String

For i = LBound(strLista) To UBound(strLista)

minValue = i

For ii = i + 1 To UBound(strLista)

If strLista(ii) < strLista(minValue) Then minValue = ii

Next ii

If minValue <> i Then
tmpValue = strLista(minValue)
strLista(minValue) = strLista(i)
strLista(i) = tmpValue
End If

Next i

For x = LBound(strLista) To UBound(strLista)

ReDim Preserve tmpArray(x)
tmpArray(x) = strLista(x)

Next x

For j = 0 To UBound(strLista)

Linha = 0

For jj = 0 To UBound(strLista)

If strLista(j) = tmpArray(Linha) And jj <> j Then
strLista(jj) = [Ô][Ô]
End If

Linha = Linha + 1

Next jj

Next j

For i = LBound(strLista) To UBound(strLista)

If strLista(i) <> [Ô][Ô] Then

ReDim Preserve Elemento(Cont)
Elemento(Cont) = strLista(i)

Cont = Cont + 1

End If

Next i

Ordenar = Elemento

End Function
SINCLAIR 14/11/2014 09:31:11
#442504
Resposta escolhida
Bom dia, colega.

Números são tratados diferentemente de strings. O número 2 vem antes do número 10. Mas a string [Ô]2[Ô] vem depois da string [Ô][ô]10[Ô], porque no caso das strings se compara o caracter 2 (de [Ô]2[Ô]) com o caracter 1 (de [Ô]10[Ô]) e caracter [Ô]2[Ô] vem depois do caracter [Ô]1[Ô], logo a sequencia fica [Ô]10[Ô] e [Ô]2[Ô]. Se fossem numeros ficaria o 10 depois, sendo 2 e 10.

Solução aproveitando seu código, é usar a função Val nas comprações, assim:


  strLista(ii) < strLista(minValue) 


deve ficar

  Val(strLista(ii)) < val(strLista(minValue)) 


Veja todas as comparações em seu código e coloque (nestes casos) a função val no array strLista (lembrando, só quando está comparando, como no exemplo acima).

Você teve uma dúvida igual, já respondida anteriormente. A resposta, claro, seguiu sendo a mesma.

Sua outra dúvida igual foi em [txt-color=#0000f0]http://www.vbmania.com.br/index.php?modulo=forum&metodo=abrir&id=441865&pagina=1[/txt-color].

Poderá usar o que foi explicado lá também (e reexplicado aqui) de forma a conseguir seu objetivo.

Tudo de bom.
KELLY 15/11/2014 00:10:09
#442543
Boa noite Euzébio,

Foi olhando a outra resposta que eu consegui chegar até esse código, cheguei até colocar a sua sugestão antes, mas o código ordenava apenas números, quero fazer no mesmo código ser possível ordenar os dois. Cheguei a colocar condições em todos os lugares onde fazia as comparações, mas o código ficou muito estranho, queria uma outra maneira para o código ficar organizado sem repetir a mesma condição em pontos distintos do código.
MARCELO.TREZE 15/11/2014 09:14:45
#442545
testa uma coisa

Public Function Ordenar(strLista() As [txt-color=#0000f0]Variant[/txt-color]) As Variant

faz a alteração acima sugeria
SINCLAIR 15/11/2014 12:29:39
#442552
Prezada colega,

Creio ter resolvido. Mudar apenas para Variant não resolveu, fiz testes e não funcionou.

Precisou inserir/modificar código. Segue a função completa, que ordena tanto strings quanto números. A idéia foi preencher as strings (mesmo que sejam números) com uma certa quantidade de zeros à esquerda (20 menos o tamanho da string) de forma a que números sejam considerados como strings de quantidade fixa em tamanho, evitando assim, a comparação de códigos ASCII para números.

As mudanças que fiz estão em negrito.

Segue o código

  Public Function Ordenar(strLista() As String) As Variant

Dim x As Integer
Dim i As Integer
Dim ii As Integer
Dim j As Integer
Dim jj As Integer
Dim Linha As Integer
Dim minValue As Integer
Dim Cont As Integer
Dim tmpValue As String
Dim tmpArray() As String
Dim Elemento() As String


[ô]Inserir zeros à esquerda, para evitar comparações ASCII entre números
For i = LBound(strLista) To UBound(strLista)
strLista(i) = String(20 - Len(strLista(i)), [Ô]0[Ô]) & strLista(i)
Next i


For i = LBound(strLista) To UBound(strLista)

minValue = i

For ii = i + 1 To UBound(strLista)

[ô]Deve ser verificado se existem indices não preenchidos
If (strLista(ii) <> String(20, [Ô]0[Ô])) And (strLista(i) <> String(20, [Ô]0[Ô])) Then
If strLista(ii) < strLista(minValue) Then minValue = ii
End If

Next ii

If minValue <> i Then
tmpValue = strLista(minValue)
strLista(minValue) = strLista(i)
strLista(i) = tmpValue
End If

Next i

For x = LBound(strLista) To UBound(strLista)

ReDim Preserve tmpArray(x)
tmpArray(x) = strLista(x)

Next x

For j = 0 To UBound(strLista)

Linha = 0

For jj = 0 To UBound(strLista)

If strLista(j) = tmpArray(Linha) And jj <> j Then
strLista(jj) = [Ô][Ô]
End If

Linha = Linha + 1

Next jj

Next j

[ô]Retirar zeros à esquerda inseridos propositamente, para evitar comprações ASCII entre números
For i = LBound(strLista) To UBound(strLista)
If LTrim(RTrim(strLista(i))) <> [Ô][Ô] Then
If Left(strLista(i), 5) = String(5, [Ô]0[Ô]) Then
For x = 1 To Len(strLista(i))
If Mid(strLista(i), x, 1) <> [Ô]0[Ô] Then
strLista(i) = Mid(strLista(i), x)
Exit For
End If
Next x
End If
End If
Next i


For i = LBound(strLista) To UBound(strLista)

If strLista(i) <> [Ô][Ô] Then

ReDim Preserve Elemento(Cont)
Elemento(Cont) = strLista(i)

Cont = Cont + 1

End If

Next i

Ordenar = Elemento

End Function




Tudo de bom.
KELLY 18/11/2014 22:16:40
#442609
Euzébio, funcionou perfeitamente. Obrigada!

Agradeço a todos os amigos pela tentativa e boa vontade em me ajudar!

Tópico encerrado , respostas não são mais permitidas