Ordenar valores de una matriz

Solo consultas sobre macros y código VBA Excel.

Reglas del Foro
1. Antes de hacer tu pregunta intenta con el buscador de este foro (muchas preguntas ya fueron respondidas antes!)
2. Si haces una nueva pregunta, es muy recomendable que adjuntes el ejemplo Excel para poder comprenderla mejor!
3. Realiza tu pregunta de forma clara, explicando bien cada paso de lo que haces y tendrás más probabilidad de respuesta!
Compartir en:
     

Ordenar valores de una matriz

Notapor trarubu2 » 10 Jul 2013 04:23

Buenos días,
Me estoy volviendo loco a la hora de ordenar los valores de 3 columnas con un orden determinado. Encontré una macro por la red que funciona, pero a la hora de la verdad, cuando hay más datos es muy lenta. Me explico:

En un excel tengo 3 columnas con datos: Modo, Frecuencia, Origen. Estos valores los paso a una matriz, y ahora quiero ordenar esta matriz de menor a mayor modo y frecuencia. Es decir, si tengo

Modo Frecuencia Origen
8 1560 Direct
7 1560 Direct
8 1560 Direct
8 1560 WEH
-2 1560 WEH
3 720 Direct
4 720 Direct
3 720 WEH

Que me los ordene:
Modo Frecuencia Origen
3 720 Direct
3 720 WEH
4 720 Direct
-2 1560 WEH
7 1560 Direct
8 1560 Direct
8 1560 Direct
8 1560 WEH

Es decir, que ordene las frecuencias de menor a mayor y dentro de cada frecuencia que ordene el modo de menor a mayor. Y lo que es importante, si dentro del mismo modo y frecuencia se repiten "direct" o "weh" que los ordene "ordenados" es decir,
8 1560 Direct
8 1560 Direct
8 1560 WEH

y que no haga por ejemplo

8 1560 Direct
8 1560 WEH
8 1560 DIRECT

Os adjunto la macro que utilizo yo para hacerlo, pero como ya os he dicho si hay muchos datos es muy lenta (lo que os mando es un ejemplo simplificado, pero realmente tengo 25 columnas)


Si me podeis ayudar os lo agradecería

Saludos
No tiene los permisos requeridos para ver los archivos adjuntos a este mensaje.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor Victor Luis » 10 Jul 2013 08:04

Holas...

Puedes acelerar tu Ordenamiento si usas una variable declarada para cargar los datos de la tabla. Ej
Type Dalista
modo As Integer
frecuencia As Long
origen As String * 50
pfr As Integer
End Type

○ Los cargar de la tabla a un Array o Vector
○ Defines la Secuencia de Orden:
► MODO-FRECUENCIA-ORIGEN
→Ordenas primero con Modo, luego Frecuencia y terminas con Origen.
► ORIGEN-MODO-FRECUENCIA
→Ordenas A-Z con Origen, luego Modo y Frecuencia.

◘ OTRO MODO
○ Concatenas los 3 valores en una variable String, segun la secuencia que deseas y cargas a un vector o array
Dim vcp(), np

For g=1 To np-1
v1=vcp(g)
fg=g
For h=g+1 to np
v2=vcp(h)
if v2<v1 then v1=v2:fg=h
Next h
If fg<>g Then
vcp(fg)=vcp(g)
vcp(g)=v1
End If
Next g


Espero te sirva la sugerencia...

Atte. viluarte22@hotmail.com
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Victor Luis
Miembro Frecuente
Miembro Frecuente
 
Registrado: 27 Jun 2013 20:53

Re: Ordenar valores de una matriz

Notapor Antoni » 10 Jul 2013 08:21

Código: Seleccionar todo
Sub Ordenar()
   With ActiveSheet.Sort
    .SortFields.Clear
    .SortFields.Add Key:=Columns("B"), SortOn:=xlSortOnValues, Order:=xlAscending
    .SortFields.Add Key:=Columns("A"), SortOn:=xlSortOnValues, Order:=xlAscending
    .SortFields.Add Key:=Columns("C"), SortOn:=xlSortOnValues, Order:=xlAscending
    .SetRange ActiveSheet.UsedRange
    .Header = xlYes
    .MatchCase = True
    .Apply
   End With
End Sub
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Antoni
Miembro Frecuente
Miembro Frecuente
 
Registrado: 22 Dic 2009 04:58
Ubicación: GALICIA (ESPAÑA)

Re: Ordenar valores de una matriz

Notapor trarubu2 » 10 Jul 2013 09:55

Muchas gracias,

El caso es que la propuesta que me dais de ordenar directamente desde el excel no me vale porque luego no lo tendré escrito en el excel, los valores lso tendé dentro del vector Presion radial(i,j) y quiero que se me ordene dentro de este vector

Y la última opción que me habeis puesto (for i=...) es la que ya tengo puesta en el excel que os he pasado. pero cuando son muchos datos va muy lenta

Segun he leido hay una función quicksort que sirve para ordenar estas cosas. Lo he probado, pero no termina de ordenarme bien la columna de "origen". Me los ordena así

8 1560 Direct
8 1560 WEH
8 1560 DIRECT


Las funciones que he utilizado son:

Sub QuickSortmodo(arr, Lo As Integer, Hi As Integer)
Dim varPivot As Variant
Dim varTmp As Variant
Dim tmpLow As Integer
Dim tmpHi As Integer
tmpLow = Lo
tmpHi = Hi
varPivot = arr((Lo + Hi) \ 2, 1)
Do While tmpLow <= tmpHi
Do While arr(tmpLow, 1) < varPivot And tmpLow < Hi
tmpLow = tmpLow + 1
Loop
Do While varPivot < arr(tmpHi, 1) And tmpHi > Lo
tmpHi = tmpHi - 1
Loop
If tmpLow <= tmpHi Then
For K = 1 To 3
varTmp = arr(tmpLow, K)
arr(tmpLow, K) = arr(tmpHi, K)
arr(tmpHi, K) = varTmp
Next K
tmpLow = tmpLow + 1
tmpHi = tmpHi - 1
End If
Loop
If Lo < tmpHi Then QuickSortmodo arr, Lo, tmpHi
If tmpLow < Hi Then QuickSortmodo arr, tmpLow, Hi
End Sub

Sub quicksortfrecuencia(arr, Lo As Integer, Hi As Integer)
Dim varPivot As Variant
Dim varTmp As Variant
Dim tmpLow As Integer
Dim tmpHi As Integer
tmpLow = Lo
tmpHi = Hi
varPivot = arr((Lo + Hi) \ 2, 2)
Do While tmpLow <= tmpHi
Do While arr(tmpLow, 2) < varPivot And tmpLow < Hi
tmpLow = tmpLow + 1
Loop
Do While varPivot < arr(tmpHi, 2) And tmpHi > Lo
tmpHi = tmpHi - 1
Loop
If tmpLow <= tmpHi Then
For K = 1 To 3
varTmp = arr(tmpLow, K)
arr(tmpLow, K) = arr(tmpHi, K)
arr(tmpHi, K) = varTmp
Next K
tmpLow = tmpLow + 1
tmpHi = tmpHi - 1
End If
Loop
If Lo < tmpHi Then quicksortfrecuencia arr, Lo, tmpHi
If tmpLow < Hi Then quicksortfrecuencia arr, tmpLow, Hi
End Sub


Pero lo dicho, la columna origen me la pone mal
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor Cacho R » 10 Jul 2013 17:52

Hola! trarubu2 (Víctor y Antoni)
El método quickSort que muestras ordena una sola columna de datos y no tres como es tu caso.

Permíteme reafirmar la idea transmitida por Antoni en el sentido que los dos comandos más poderosos del Excel (y por lo tanto: insuperables -en términos de eficiencia- comparados con sus "remedos" vía VBA) son el filtro avanzado y el ordenador.

De modo que a la sugerencia que te muestra Antoni, sólo te resta incorporarle:

- Pasar tus datos de tu matriz a una hoja auxiliar;
- Ordenar los datos;
- E incorporar los datos ordenados a tu matriz

Una forma sencilla sería:

Código: Seleccionar todo
Sub Ordenar_Matriz()
Dim Presion_radial, Q&

' Con lo siguiente, pongo los datos (que están en las celdas) en la matriz:
Presion_radial = Range([a2], [c2].End(xlDown))

'Ahora empieza el método de ordenamiento:
Q = UBound(Presion_radial, 1)
With Workbooks.Add(xlWBATWorksheet).ActiveSheet
  .[a1:c1].Resize(Q) = Presion_radial
  .[a1:c1].Resize(Q).Sort _
    key1:=.[b1], order1:=xlAscending, _
    key2:=.[a1], order2:=xlAscending, _
    key3:=.[c1], order3:=xlAscending, Header:=False

'Tu matriz queda ordenada mediante:
  Presion_radial = .[a1:c1].Resize(Q)
  .Parent.Close False
End With
End Sub

Evalúa los tiempos de proceso y nos cuentas, ¿OK?
Saludos, Cacho R.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Cacho R
Miembro Frecuente
Miembro Frecuente
 
Registrado: 23 Jun 2011 17:15
Ubicación: Buenos Aires

Re: Ordenar valores de una matriz

Notapor trarubu2 » 11 Jul 2013 03:50

Ok! Yo lo decia por si habia alguna forma sin tener que copiarlos en excel. Pero si es más rápido me vale de sobra

Muchas gracias!
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor Antoni » 11 Jul 2013 05:18

Gran Cacho eres el "number one and simply the best !!
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Antoni
Miembro Frecuente
Miembro Frecuente
 
Registrado: 22 Dic 2009 04:58
Ubicación: GALICIA (ESPAÑA)

Re: Ordenar valores de una matriz

Notapor trarubu2 » 11 Jul 2013 05:37

Otra pregunta: Tal y como tengo la macro hecha y para hacer lo que ovosotrs me proponeis lo que tengo que hacer es:

1.Pegar los valores de mi matriz en una hoja excel
2.Ordenar los valores
3.Copiar los valores ordenados en mi matriz

Alguna forma rápida de copiar y pegar estos valores? No estoy muy puesto en estos temas y lo que estoy haciendo es
for i=1 to linea
for j=1 to 3

next j
next i

Gracias!
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor Cacho R » 11 Jul 2013 13:23

Antoni escribió:Gran Cacho eres el "number one and simply the best !!

Diría:
Antoni (a) El Generoso.
(gracias, Amigo)


trarubu2 escribió:... ¿Alguna forma rápida de copiar y pegar estos valores? No estoy muy puesto en estos temas y lo que estoy haciendo es
for i=1 to linea
for j=1 to 3
...
next j
next i

Permíteme una pregunta, trarubu2:
¿Es posible que ni te hayas tomado el trabajo de analizar el código que te he pasado?...
Lo digo puesto que ese código hace -exactamente- aquello de lo que estamos hablando.

Saludos, Cacho R.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Cacho R
Miembro Frecuente
Miembro Frecuente
 
Registrado: 23 Jun 2011 17:15
Ubicación: Buenos Aires

Re: Ordenar valores de una matriz

Notapor trarubu2 » 12 Jul 2013 03:21

Por supuesto que te permito la pregunta, la segunda parte la de meterlo a la matriz después de estar ordenada si que está hecho. Yo lo que preguntaba era la primera parte: de la matriz pegarlo a la hoja auxiliar para ordenarlo, si habia alguna manera más rápida de hacerla que mediante 2 for

Pero tienes razón, disculpa las molestías, la pregunta principal ya está contestada, ahora lo otro ya me buscaré las castañas

muchas gracias a todos!

Saludos
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor trarubu2 » 12 Jul 2013 07:16

vuelvo a rectificar, teneistoda la razón del mundo, los copia de la matriz al excel, yo le daba a correr la macro pero con tantas ventanas abiertas en el escritorio no veia que creara hoja. y como no estoy muy puesto en vba excel tampoco entendía el código muy bien. Me lo han explicado y todo correcto

Muchas gracias a todos!
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor Cacho R » 12 Jul 2013 12:15

trarubu2 escribió:vuelvo a rectificar, teneis toda la razón del mundo, los copia de la matriz al excel... Me lo han explicado y todo correcto ...

Pufffff... :idea:
¡Menos mal que "le encontraste la vuelta"!

Hasta la próxima, entonces.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Cacho R
Miembro Frecuente
Miembro Frecuente
 
Registrado: 23 Jun 2011 17:15
Ubicación: Buenos Aires

Re: Ordenar valores de una matriz

Notapor trarubu2 » 17 Jul 2013 05:08

Vaya,
Parece que habia terminado con este tema pero como no controlo mucho de este tema (más bien me estoy dando cuenta de que nada) cuando quiero implantarme el código en mi función no consigo pasarme los datos ordenados a mi matriz inicial.
Me explico:
Tengo mi matriz inicial PresionRadial con los datos desordenados. Esta matriz la he declarado como Public PresionRadial(2000,25)

Lo que hago es llamar a vuestra función

call ordenar_matriz

Código: Seleccionar todo
Sub Ordenar_Matriz()
Dim QQQ&

' Con lo siguiente, pongo los datos (que están en las celdas) en la matriz:
'Presion_radial = Range([a2], [c2].End(xlDown))

'Ahora empieza el método de ordenamiento:
QQQ = linea 'Linea es el número de datos que tengo
With Workbooks.Add(xlWBATWorksheet).ActiveSheet
  .[a1:z1].Resize(QQQ) = PresionRadial
  .[b1:z1].Resize(QQQ).Sort _
    key1:=.[c1], order1:=xlAscending, _
    key2:=.[b1], order2:=xlAscending, Header:=False

'Tu matriz queda ordenada mediante:
  PresionRadial = .[a1:z1].Resize(QQQ)
  .Parent.Close False
End With



End Sub



Pero me da error de "Error de compilacion: No se puede asignar a una matriz"

Como podría hacerlo ?

Saludos
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39

Re: Ordenar valores de una matriz

Notapor trarubu2 » 17 Jul 2013 10:32

Buenas tardes,

Al final lo que he hecho es pasar mi matriz PresionRadial como parámetro en la función y al final de la función con bucles for igualo los valores de la matriz. El código me ha quedado:

Código: Seleccionar todo
Function Ordenar_Matriz(Presion_Radial)
Dim QQQ&

' Con lo siguiente, pongo los datos (que están en las celdas) en la matriz:
'Presion_radial = Range([a2], [c2].End(xlDown))

'Ahora empieza el método de ordenamiento:
QQQ = linea + 1 'Linea es el número de datos que tengo
With Workbooks.Add(xlWBATWorksheet).ActiveSheet
  .[a1:z1].Resize(QQQ) = Presion_Radial
  .[b1:z1].Resize(QQQ).Sort _
    key1:=.[c1], order1:=xlAscending, _
    key2:=.[b1], order2:=xlAscending, Header:=False

'Tu matriz queda ordenada mediante:
  Presion_Radial = .[b1:z1].Resize(QQQ - 1)
  .Parent.Close False
End With

'Dim Presion_Radial() As System.Windows.Forms.Form
'Dim PresionRadial() As System.Windows.Forms.Control
'PresionRadial = Presion_Radial
For i = 1 To QQQ - 1
    For j = 1 To 25
    PresionRadial(i, j) = Presion_Radial(i, j)
    Next j
Next i
End Function


Y me va perfecto!
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
trarubu2
Miembro Frecuente
Miembro Frecuente
 
Registrado: 10 Ene 2012 08:39


Compartir en:
     

  • Anuncio
Manual Excel avanzado

Volver a Macros

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 7 invitados