EXCEL: ¿Como pasar una tabla horizontal a una vertical (BD) para usar en tablas dinámicas?

Cesar Ayala 0 Puntos de reputación
2025-09-15T22:01:38.4066667+00:00

Hola.

Creo que debe ser de los errores mas habituales de Excel, pero me ha costado encontrar la solución. Todos sabemos que no todos utilizan las tablas de la misma manera y gran parte del tiempo se va en reorganizar las tablas que nos llegan. Poniendo un ejemplo claro, tengo la siguiente tabla (no está formato tabla porque tiene el doble encabezado) :

Captura de pantalla 2025-09-15 a la(s) 4.53.33 p.m.

La tabla es mas larga aun porque tiene los 12 meses y 30 negocios mas... esta es una muestra.

Para sacarle el jugo, es mejor hacer una tabla dinámica, pero para ella lo necesitaría organizado de la siguiente manera:

Captura de pantalla 2025-09-15 a la(s) 4.58.59 p.m.

¿Hay alguna forma de pasar "automáticamente" la tabla inicial al formato de la ultima tabla? Esta ultima tabla. la hice a punta de copiar, pegar y transponer... pero es poco eficiente.

La tabla No.1 no la puedo poner como dinámica porque quedan los datos desorganízanos por el doble cabezal de la tabla (mes y Presupuesto, Real y Diferencia)

Gracias por la ayuda.

Microsoft 365 y Office | Excel | Para el negocio | MacOS
0 comentarios No hay comentarios

2 respuestas

Ordenar por: Lo más útil
  1. WordExperto 64,335 Puntos de reputación Moderador voluntario
    2025-09-18T13:45:55.8766667+00:00

    Hola a todos:

    En esta entrada, de mi curso gratuito, lo explico.

    WordExperto.

    ¿Le resultó útil esta respuesta?

    0 comentarios No hay comentarios

  2. Anónimo
    2025-09-16T04:14:25.19+00:00

    Estimado Cesar Ayala
    ¡Bienvenido/a y gracias por compartir tu problema en el foro de QA!

    Según la información que proporcionaste, entiendo que estás intentando convertir una tabla de datos horizontal en un formato vertical, organizado por mes. Sé que ya intentaste hacerlo manualmente copiando y pegando, pero ese método no es práctico cuando se trata de grandes volúmenes de datos.

    Para resolver esto, podemos usar una macro en VBA que automatice la transformación. Aquí te explico cómo hacerlo:

    Para usuarios de MacOS:

    Abre Excel.
    Imagen del usuario

    Presiona Fn + Option + F11 para abrir el Editor de VBA.
    Imagen del usuario

    Pega el siguiente código en un nuevo módulo:

    Sub TransformDataByMonth()
        ' --- SETUP ---
        ' Declare variables for our worksheets and loop counters
        Dim wsSource As Worksheet
        Dim wsDest As Worksheet
        Dim lastRow As Long
        Dim lastCol As Long
        Dim destRow As Long
        Dim r As Long ' For looping through source rows (businesses)
        Dim c As Long ' For looping through source columns (months)
        ' To make the macro run faster
        Application.ScreenUpdating = False
        ' Set your source worksheet. CHANGE "Raw Data" IF YOUR SHEET HAS A DIFFERENT NAME.
        On Error Resume Next
        Set wsSource = ThisWorkbook.Sheets("Raw Data")
        On Error GoTo 0
        If wsSource Is Nothing Then
            MsgBox "The source sheet named 'Raw Data' was not found. Please check the sheet name.", vbCritical
            Exit Sub
        End If
        ' Create or clear the destination worksheet
        On Error Resume Next
        Set wsDest = ThisWorkbook.Sheets("Formatted Data")
        On Error GoTo 0
        If wsDest Is Nothing Then
            Set wsDest = ThisWorkbook.Sheets.Add(After:=wsSource)
            wsDest.Name = "Formatted Data"
        Else
            wsDest.Cells.Clear
        End If
        ' --- CREATE HEADERS ---
        With wsDest
            .Cells(1, 1).Value = "Mes"
            .Cells(1, 2).Value = "Negocio"
            .Cells(1, 3).Value = "Datos"
            .Cells(1, 4).Value = "Ventas"
            .Range("A1:D4").Font.Bold = True ' Bold headers
        End With
        destRow = 2 ' Initialize the first row for data entry on the destination sheet
        ' --- PROCESS DATA ---
        ' Find the last used row and column on the source sheet
        lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
        lastCol = wsSource.Cells(2, wsSource.Columns.Count).End(xlToLeft).Column
        ' *** LOGIC CHANGE IS HERE: Loop by MONTH first, then by BUSINESS ***
        ' Loop through each month block (columns), stepping 3 columns at a time
        For c = 2 To lastCol Step 3
            ' For the current month, loop through each business row (e.g., Cali, Bogota)
            For r = 3 To lastRow
                ' Get the month and business name
                Dim monthName As String
                Dim businessName As String
                monthName = UCase(wsSource.Cells(1, c).Value)
                businessName = wsSource.Cells(r, 1).Value
                ' --- Write 3 rows for each data point ---
                ' 1. Presupuesto (Budget)
                wsDest.Cells(destRow, 1).Value = monthName
                wsDest.Cells(destRow, 2).Value = businessName
                wsDest.Cells(destRow, 3).Value = "Presupuesto"
                wsDest.Cells(destRow, 3).Font.Bold = True
                wsDest.Cells(destRow, 4).Value = wsSource.Cells(r, c).Value
                destRow = destRow + 1
                ' 2. Real (Actual)
                wsDest.Cells(destRow, 1).Value = monthName
                wsDest.Cells(destRow, 2).Value = businessName
                wsDest.Cells(destRow, 3).Value = "Real"
                wsDest.Cells(destRow, 3).Font.Bold = True
                wsDest.Cells(destRow, 4).Value = wsSource.Cells(r, c + 1).Value
                destRow = destRow + 1
                ' 3. Diferencia (Difference)
                wsDest.Cells(destRow, 1).Value = monthName
                wsDest.Cells(destRow, 2).Value = businessName
                wsDest.Cells(destRow, 3).Value = "Diferencia"
                wsDest.Cells(destRow, 3).Font.Bold = True
                wsDest.Cells(destRow, 4).Value = wsSource.Cells(r, c + 2).Value
                ' Apply formatting to the "Diferencia" value
                If wsDest.Cells(destRow, 4).Value < 0 Then
                    wsDest.Cells(destRow, 4).Font.Color = vbRed
                End If
                ' Add the bottom border to separate the block
                wsDest.Range("A" & destRow & ":D" & destRow).Borders(xlEdgeBottom).LineStyle = xlContinuous
                destRow = destRow + 1
            Next r ' Next business
        Next c ' Next month
        ' --- FINISH UP ---
        ' Autofit the columns for better readability
        wsDest.Columns("A:D").AutoFit
        ' Turn screen updating back on
        Application.ScreenUpdating = True
        wsDest.Activate
        MsgBox "Data transformation is complete!", vbInformation
    End Sub
    

    Presiona el botón Run para ejecutar la macro.
    Imagen del usuario

    Notas importantes: Asegúrate de que la hoja de datos original se llame "Raw Data".
    El código asume que cada mes tiene tres columnas: Presupuesto, Real y Diferencia. Por favor, asegúrate de que esta estructura se mantenga.
    Toda la información que te proporciono ha sido probada en un entorno de prueba y funciona correctamente. Si surge algún problema o tienes más preguntas, no dudes en compartirlas. ¡Estoy siempre disponible para ayudarte!


    "Si la respuesta es útil, haga clic en ""Aceptar respuesta"" y vote amablemente. Si tiene preguntas adicionales sobre esta respuesta, haga clic en ""Comentar"".

    Nota: Siga los pasos de [nuestra documentación] para habilitar las notificaciones por correo electrónico si desea recibir la notificación por correo electrónico relacionada con este hilo."

    ¿Le resultó útil esta respuesta?


Su respuesta

Las respuestas pueden ser marcadas como Respuestas aceptadas por el autor de la pregunta, lo que indica a los usuarios que la respuesta resolvió su problema.