martes, 16 de enero de 2018

Pasar una matriz de varias columnas a un vector de una sola columna

Hace algunos días me llegó a través de un comentario una cuestión clásica en Excel:
Cómo pasar una matriz de varias columnas a un vector de una sola columna



Lo haremos de un par de formas.
Una primera con fórmulas.
En primer lugar hemos asignado un nombre definido al rango de celdas con valores:
datos =Hoja2!$A$2:$B$11

A partir de ese nombre definido, en las celda E2:E21, añadimos la siguiente fórmula:
=INDICE(datos;1+ENTERO((FILA(A1)-1)/COLUMNAS(datos));RESIDUO(FILA(A1)-1+COLUMNAS(datos);COLUMNAS(datos))+1)
algo larga, pero lo relevante es que con la fórmula:
1+ENTERO((FILA(A1)-1)/COLUMNAS(datos))
obtenemos la posición de las filas a recuperar del rango 'datos', aumentando el número de fila de dos en dos.

De forma similar con
RESIDUO(FILA(A1)-1+COLUMNAS(datos);COLUMNAS(datos))+1
obtenemos la posición de la columna, para nuestro ejemplo, 1, 2, 1, 2, 1, 2, etc...

Según se ve en la imagen siguiente:



Se observa como los algoritmos empleados devuelven el recorrido ordenado de cada elemento de nuestra matriz...

Otra forma, quizá mas simple, sea empleando una macro, así añadiremos dentro de un módulo estándar de nuestro proyecto de VB:

Sub ConvertirMatrizVector()
'pedimos al usuario selecciona la primera celda donde desplegar el vector destino
Set celdadestino = Application.InputBox("Celda Inicio Destino:", Type:=8)

Dim fd As Long
fd = 0
'recorremos fila por fila del rango seleccionado
For Each fila In Selection.Rows
    'copiamos la fila completa
    fila.Copy
    'y pegamos en el destino adecuado
    celdadestino.Offset(fd, 0).PasteSpecial Paste:=xlValues, Transpose:=True
    'incrementando la posición de fila destino...
    fd = fd + fila.Columns.Count
Next fila
End Sub



O también esta otra macro.

Sub ConvertirMatrizVector_v2()
'pedimos al usuario selecciona la primera celda donde desplegar el vector destino
Set celdadestino = Application.InputBox("Celda Inicio Destino:", Type:=8)

Dim fd As Long
fd = 0
'recorremos las filas del rango seleccionado
For f = 1 To Selection.Rows.Count
    'y recorremos las columnas del rango seleccionado
    For c = 1 To Selection.Columns.Count
        'llevamos el valor de cada celda del rango a la celda destino
        celdadestino.Offset(fd, 0).Value = Selection.Cells(f, c).Value
        fd = fd + 1
    Next c
Next f
End Sub



Consiguiendo en cualquiera de los tres casos el objetivo: convertir una matriz en un vector

No hay comentarios:

Publicar un comentario