Risolto Ordinare valori VBA

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
Questa routine che ho trovato su un sito specifico di programmazione, prometteva di funzionare, invece a me da il nulla assoluta.
Si tratterebbe semplicemente di ordinare il ordine progressivo tutti i numeri presenti nella colonna A.
Ho fatto varie prove ma non sono in grado di capire dove sta il problema.. non succede nulla.
Mi potete aiutare a modificare la routine e magari spiegare dove sta l'errore?
Grazie

Visual Basic:
For I = 1 To NumMax - 1
For A = I + 1 To NumMax
If Cells(A, 1) > Cells(I, 1) Then
Numero = Cells(I, 1)
Cells(I, 1) = Cells(A, 1)
Cells(A, 1) = Numero
End If
Next
Next
 

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
Allora, questa formula che ho trovato e modificata a dovere è in grado di:
Ordinare qualsiasi lista numerica o stringhe di testo, con intervallo dinamici e soprattutto, opera nel giro di pochi centesimi di secondo. Aggiungo che è composta da un'unica riga di istruzione VBA. In altre parole è perfetta.

La pubblico nel caso posso essere di aiuto a chi non ha grandi pretese ma vuole efficienza e velocità.

P.S. Era quello che cercavo quindi mi è sembrato giusto assegnarmi la migliore risposta.

Grazie a tutti per l'aiuto.

Visual Basic:
Sub OrdinamentoTabellare()

Range("A1:C20").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlYes

End Sub
 

Allegati

Marco Lauria

Utente assiduo
2 Gennaio 2017
1.423
95
Roma
www.artigianamaterassi.net
Excel 2016
159
In un Modulo inserisci:

Visual Basic:
Option Explicit

Sub Ordina()
    Dim ws As Worksheet
    
    Set ws = Worksheets("Foglio1")
    ws.Sort.SortFields.Clear
    ws.Sort.SortFields.Add Key:=Range("A1"), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ws.Sort
        .SetRange ws.Range("A:A")
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub
 

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
Vi ringrazio per le risposte ma non è quello che avevo chiesto.
Sono capace di registrare una macro ed usare il codice, per un fine così pratico.
Le risposte che avevo trovato sul web (con il relativo codice postato) creavano una sub routine senza l'inserimento di incomprensibili keyword del VBA. Era un modo per capirne il funzionamento.
 

dodo47

Utente abituale
Expert
18 Ottobre 2020
988
75
excel 2016
139
ciao
la risposta al codice da te sottoposto è: funziona perfettamente e ordina in modo decrescente la colonna A composta da numeri.
Cambiando:
If Cells(A, 1) > Cells(I, 1) Then
con
If Cells(A, 1) < Cells(I, 1) Then
ottieni l'ordine crescente

Ovviamente all'inizio manca: NumMax= Numero dell'ultima riga

saluti
 

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
[Overquote]


Grazie Dodo.
Era questo quello che chiedevo.
Capire come modificare questa semplice routine per renderla funzionale.
Mi mancava il passaggio del valore numMax che l'autore non aveva inserito (non so il perchè)
Adesso provo a vedere se funziona.

Ho inserito l'istruzione che mancava come da codice postato nel foglio in allegato.
Funziona alla perfezione. Era quello che chiedevo, però mancava la prima riga che ho inserito in una variabile.
Adesso noto un fortissimo rallentamento del processo (in parte lamentato anche dall'autore).
Soltanto 30 valori rendono il procedimento molto lento. Si può fare qualcosa?

P.S. I messaggi a seguire sono doppioni non so cosa sia successo.
Forse per errore ho digitato replica invece di modifica.
Io non sono moderatore e non posso cancellarli.
 

Allegati

dodo47

Utente abituale
Expert
18 Ottobre 2020
988
75
excel 2016
139
....Adesso noto un fortissimo rallentamento del processo (in parte lamentato anche dall'autore).
Soltanto 30 valori rendono il procedimento molto lento. Si può fare qualcosa?....
Ciao
ammesso che il foglio non contenga formule, il rallentamento della routine è dato dal fatto che per ogni numero, lui si spazzola l'intero elenco,

Soluzione: usa il sort suggerito

saluti
 

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
In effetti era quello il problema ... avevo usato "casuale.tra" per generare numeri random e l'elaborazione prendeva molto tempo.
Una volta risolta con formula con copia/incolla per valori, le formule spariscono e la routine esegue il processo con discreta velocità.

100 valori elaborati in meno di 2 secondi

Purtroppo il discorso cambia se i valori aumentano. Con 1.000 numeri si toccano i 15-18 secondi ed Excel tenta anche di andarsene in crash :-(

Riscrivo la formula completa, magari a qualcuno può risultare utile.

Visual Basic:
Option Explicit

Sub ordina()

Dim NumMax As Long, Numero As Long
Dim i As Integer, j As Integer

NumMax = Foglio1.Cells(Rows.Count, 1).End(xlUp).Row
    For i = 1 To NumMax - 1
        For j = i + 1 To NumMax
            If Cells(j, 1) > Cells(i, 1) Then
                Numero = Cells(i, 1)
                Cells(i, 1) = Cells(j, 1)
                Cells(j, 1) = Numero
            End If
        Next j
    Next i

MsgBox "Ordinamento terminato"

End Sub
 

Allegati

alfrimpa

VBA Expert
Supermoderatore
18 Dicembre 2015
38.926
2.445
67
Napoli
Office 365
1.258
Scusa ma perchè non usi gli strumenti che ti mette a disposizione Excel per l'ordinamento dei dati?

Confronta i tempi della tua ultima macro con quella che ti ha postato Marco Lauria @Marco Lauria (che saluto) tutte e due fanno la stessa cosa.

Quando Excel ha già a disposizione gli strumenti è inutile andare a cercare vie alternative che, con molta probabilità, funzionano peggio.
 
Ultima modifica:

dodo47

Utente abituale
Expert
18 Ottobre 2020
988
75
excel 2016
139
ciao
sicuramente ci sfugge qualcosa che tu non dici.

Non si capisce infatti il perchè tu ti ostini ad utilizzare quel metodo per ordinare una colonna.....

saluti
 

Marco Lauria

Utente assiduo
2 Gennaio 2017
1.423
95
Roma
www.artigianamaterassi.net
Excel 2016
159
Ok,
se ti piace l'ordinamento classico ti propongo un Sort chiamato QuickSort.
La macro ovviamente non è mia ma ti assicuro che funziona molto bene.
100.000 record li processa in 3 secondi:

Visual Basic:
Option Explicit

Sub ProcessData_Quicksort()
    'Example macro to show you how to add a column of data to an array
    'and sort the data from smallest to largest using VBA Quicksort.
    Dim MyData() As Variant
    Dim i As Long, LastRow As Long
    
    'Store column of data into array
    LastRow = Range("A" & Rows.Count).End(xlUp).Row
    ReDim MyData(1 To LastRow)
    For i = 1 To LastRow
        MyData(i) = Range("A" & i)
    Next i
    
    'Now sort your array using the VBA Quicksort macro
    Quicksort MyData(), LBound(MyData), UBound(MyData)
    '
    'From here on, your "MyData" array is sorted from smallest to largest
    
    For i = 1 To LastRow
        Range("A" & i) = MyData(i)
    Next
End Sub

Sub Quicksort(vArray As Variant, arrLbound As Long, arrUbound As Long)
    'Sorts a one-dimensional VBA array from smallest to largest
    'using a very fast quicksort algorithm variant.
    Dim pivotVal As Variant
    Dim vSwap    As Variant
    Dim tmpLow   As Long
    Dim tmpHi    As Long
    
    tmpLow = arrLbound
    tmpHi = arrUbound
    pivotVal = vArray((arrLbound + arrUbound) \ 2)
    
    While (tmpLow <= tmpHi) 'divide
       While (vArray(tmpLow) < pivotVal And tmpLow < arrUbound)
          tmpLow = tmpLow + 1
       Wend
      
       While (pivotVal < vArray(tmpHi) And tmpHi > arrLbound)
          tmpHi = tmpHi - 1
       Wend
    
       If (tmpLow <= tmpHi) Then
          vSwap = vArray(tmpLow)
          vArray(tmpLow) = vArray(tmpHi)
          vArray(tmpHi) = vSwap
          tmpLow = tmpLow + 1
          tmpHi = tmpHi - 1
       End If
    Wend
    
      If (arrLbound < tmpHi) Then Quicksort vArray, arrLbound, tmpHi 'conquer
      If (tmpLow < arrUbound) Then Quicksort vArray, tmpLow, arrUbound 'conquer
End Sub
La macro che fa partite il Sort è: ProcessData_Quicksort
 

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
Mai domo, sono andato avanti nelle ricerche e ho trovato questa formula da "paura"
Ordina valori e stringhe testuali con intervalli dinamici in pochi centesimi di secondo e in una sola riga di codice.
Sembra poterlo fare soltanto su di 1 colonna, sto valutando l'estensione ad intervalli maggiori.
Tutta per voi ...

Visual Basic:
Sub OrdinaNominativi()

Foglio1.Range("A1", Range("A1").End(xlDown)).Sort key1:=Range("A1"), Order1:=xlAscending, Header:=xlYes

End Sub
Questa formula che ho postato credo sia imbattibile per ordinare sia valori che stringhe a tempi di record e con una sola riga di codice VBA..

Allora quale è il problema?? quando cerco di estendere la classificazione a più colonne vengono generati degli errori che non sono in grado di risolvere.

Allego codice e foglio confidando in un vostro aiuto finale chiudere positivamente questo theard.

Grazie
Visual Basic:
Sub OrdinamentoTabellare()

With Foglio2.Sort
    .SortFields.Add Key:=Range("A1"), Order:=xlAscending
    .SortFields.Add Key:=Range("B1"), Order:=xlAscending
    .SetRange Range("A1:C20")
    .Header = xlYes
    .Apply
End With

End Sub
 

Allegati

Ultima modifica:

Inesperto1

Utente abituale
5 Aprile 2020
130
18
2016
1
Uguale?
La tua macro era composta da 13 righe di codice a causa del registratore.
Quella che ho postato io è una sintesi da 3 righe, di cui soltanto una di codice , il resto è apertura e chiusura sub.

Una riduzione del 95% di codice non mi sembra cosi insignificante .. questo è uno dei motivi per il quale non mi piace registrare una macro e usarla come consigliava alfrimpa @alfrimpa
 

alfrimpa

VBA Expert
Supermoderatore
18 Dicembre 2015
38.926
2.445
67
Napoli
Office 365
1.258
.. questo è uno dei motivi per il quale non mi piace registrare una macro e usarla come consigliava alfrimpa @alfrimpa
E' ovvio che il registratore di macro va solo usato per motivi "didattici" per sapere subito quali sono le istruzioni da utilizzare.

Ed è altrettanto ovvio che il codice risultante, nella maggior parte dei casi ridondante, va poi sfrondato, rifinito e corretto.

Comunque, come diceva Marco Lauria @Marco Lauria (che saluto) finchè il numero di righe del codice (a meno che non si parli di centinaia o più di istruzioni) non ha alcun impatto sull'efficienza del codice e sui suoi tempi di esecuzione. Questi dipendono dalla mole di dati che si devono elaborare.

Secondo me ti stai ponendo un falso problema.
 

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!