arrays excel excel-vba transpose vba

arrays - Agregar, clasificar y transponer filas en columnas



excel excel-vba (3)

Esta opción incorpora matrices. Desde el punto de vista del rendimiento, es mucho más rápido leer una vez los datos de la hoja de trabajo en una matriz, realizar sus procedimientos directamente en VBE y escribir los resultados en las hojas de trabajo en comparación con los procedimientos en la hoja de trabajo celda por celda.

Sub transposing() Const sDestination As String = "D2" Dim ar1() As Variant Dim ar2() As Variant Dim i As Long ''counter ar1 = ActiveSheet.Range("A2:B" & ActiveSheet.UsedRange.Rows.Count).Value ReDim ar2(1 To 1, 1 To 2) ar2(1, 1) = ar1(1, 1): ar2(1, 2) = ar1(1, 2) For i = 2 To UBound(ar1, 1) If ar1(i, 1) = ar2(UBound(ar2, 1), 1) Then ar2(UBound(ar2, 1), 2) = ar2(UBound(ar2, 1), 2) & ar1(i, 2) ElseIf ar1(i, 1) = vbNullString Then ar2(UBound(ar2, 1), 2) = ar2(UBound(ar2, 1), 2) & " " Else ar2 = Application.Transpose(ar2) ReDim Preserve ar2(1 To 2, 1 To UBound(ar2, 2) + 1) ar2 = Application.Transpose(ar2) ar2(UBound(ar2, 1), 1) = ar1(i, 1) ar2(UBound(ar2, 1), 2) = ar2(UBound(ar2, 1), 2) & ar1(i, 2) End If Next ActiveSheet.Range(sDestination).Resize(UBound(ar2, 1), UBound(ar2, 2)).Value = ar2 End Sub

El resultado se verá así:

La línea Const sDestination As String = "D2" indica el comienzo de la salida. Cámbielo a la celda que desee.

Tengo la siguiente tabla

Id Letter 1001 A 1001 H 1001 H 1001 H 1001 B 1001 H 1001 H 1001 H 1001 H 1001 H 1001 H 1001 A 1001 H 1001 H 1001 H 1001 B 1001 A 1001 H 1001 H 1001 H 1001 B 1001 B 1001 H 1001 H 1001 H 1001 B 1001 H 1001 A 1001 G 1001 H 1001 H 1001 A 1001 B 1002 B 1002 H 1002 H 1002 B 1002 G 1002 H 1002 B 1002 G 1002 G 1002 H 1002 B 1002 G 1002 H 1002 H 1002 G 1002 H 1002 H 1002 H 1002 H 1002 H 1002 M 1002 N 1002 G 1002 H 1002 H 1002 M 1002 M 1002 A 1002 H 1002 H 1002 H 1002 A 1002 B 1002 B 1002 H 1002 H 1002 H 1002 B 1002 H 1002 H 1002 H 1002 A 1002 A 1002 A 1002 H 1002 H 1002 H 1002 H 1002 B 1002 H 1003 G 1003 H 1003 H 1003 N 1003 M

Y estoy tratando de transponerlo para que cada ID diferente en la primera columna y todas las letras en la segunda columna con un espacio en blanco para cada fila en blanco en la tabla original:

1001 AHHH BHHH HHH AHHHB AHHHB BHHHB H AGHHAB 1002 BHHB GH BGGH BGHH GHH HHHMN GHHMM AHHHAB BHHH BHHHAA AHHHHB H 1003 GHHNM

Tengo alrededor de 100 ID diferentes. Traté de hacer con una fórmula usando TRANSPOSE y TRIM. También probé con una macro y VLOOKUP parece ser la forma más fácil, pero no puedo descubrir cómo


No puede concatenar un rango de celdas (también conocido como Letras ) utilizando funciones de hoja de cálculo nativas sin conocer el alcance de antemano. Como su colección de cadenas en grupos tiene números aleatorios de elementos, un enfoque de bucle VBA parece la mejor (si no la única) forma de abordar el problema. El bucle puede hacer determinaciones en el camino en que una función de hoja de trabajo es simplemente incapaz de realizar.

Toque Alt + F11 y cuando se abra el Editor de Visual Basic (también conocido como VBE), use inmediatamente los menús desplegables para Insertar ► Módulo ( Alt + I , M ). Pegue uno o ambos de los siguientes en el nuevo panel titulado algo así como Libro1 - Módulo1 (Código) .

Para concatenar los grupos de cadenas delimitados por un espacio:

Sub concatenate_and_transpose_to_delim_string() Dim rw As Long, lr As Long, pid As Long, str As String Dim bPutInColumns As Boolean With ActiveSheet lr = .Cells(Rows.Count, 1).End(xlUp).row .Cells(1, 4).Resize(1, 2) = Array("Id", "Letters") pid = .Cells(2, 1).Value For rw = 2 To lr If IsEmpty(.Cells(rw, 1)) Then str = str & Chr(32) If pid <> .Cells(rw + 1, 1).Value Then .Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = pid .Cells(Rows.Count, 4).End(xlUp).Offset(0, 1) = str End If ElseIf pid <> .Cells(rw, 1).Value Then pid = .Cells(rw, 1).Value str = .Cells(rw, 2).Value Else str = str & .Cells(rw, 2).Value End If Next rw .Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = pid .Cells(Rows.Count, 4).End(xlUp).Offset(0, 1) = str End With End Sub

Para dividir los grupos de cadenas en columnas:

Sub concatenate_and_transpose_into_columns() Dim rw As Long, lr As Long, nr As Long, pid As Long, str As String With ActiveSheet lr = .Cells(Rows.Count, 1).End(xlUp).row .Cells(1, 4).Resize(1, 2) = Array("Id", "Letters") For rw = 2 To lr If IsEmpty(.Cells(rw, 1)) Then .Cells(nr, Columns.Count).End(xlToLeft).Offset(0, 1) = str str = vbNullString ElseIf pid <> .Cells(rw, 1).Value Then pid = .Cells(rw, 1).Value nr = .Cells(Rows.Count, 4).End(xlUp).Offset(1, 0).row .Cells(nr, 4) = pid str = .Cells(rw, 2).Value Else str = str & .Cells(rw, 2).Value End If Next rw .Cells(nr, Columns.Count).End(xlToLeft).Offset(0, 1) = str End With End Sub

Toque Alt + Q para volver a su hoja de trabajo. Con sus datos de muestra en la hoja de trabajo activa comenzando con Id en A1, toque Alt + F8 para abrir el cuadro de diálogo Macros y Ejecutar la macro.

Resultados de concatenate_and_transpose_to_delim_string:

Resultados de concatenate_and_transpose_into_columns:

Los resultados se escribirán en las celdas comenzando en D2. Probablemente sea mejor si no hubiera nada importante allí de antemano que pudiera sobrescribirse.

Apéndice:

Originalmente interpreté mal su solicitud y dividí los grupos de cadenas en columnas separadas. Lo rectifiqué con una rutina complementaria que sigue más de cerca su descripción de los requisitos, pero mantuvo ambas variaciones para que otros las consulten.


Para tareas como esta, Microsoft agregó "Obtener y transformar" a Excel 2016. Para usar esta funcionalidad en versiones anteriores, debe usar el complemento Power Query. El código M es muy corto:

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], FillIdDown = Table.FillDown(Source,{"Id"}), ReplaceNull = Table.ReplaceValue(FillIdDown,null," ",Replacer.ReplaceValue,{"Letter"}), Transform = Table.Group(ReplaceNull, {"Id"}, {{"Count", each Text.Combine(_[Letter])}}) in Transform

Sus datos deben estar en "Tabla1". https://www.dropbox.com/s/bnvchofmpvd048v/SO_AggregateCollateAndTransposeColsIntoRows.xlsx?dl=0