Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
2
respuestas

Desafío: crea tus propios desafíos

Desafío: Sistema de Ventas y Reportes en Excel con VBA
Contexto
Una empresa de tecnología necesita simular y analizar sus ventas mensuales para entrenar a su equipo en el uso de Excel y VBA. El gerente quiere dos cosas:

Una base de datos de ventas aleatorias con formato de tabla y filtros para poder explorar la información.

Un informe resumido que muestre el total de ventas por vendedor, ordenado de mayor a menor, con formato profesional.

Prompt utilizado para poder resolver el desafio: Crea en Excel un sistema de ventas con VBA que genere automáticamente 100 registros aleatorios en una hoja llamada Ventas (con fecha, vendedor, producto, cantidad y precio unitario), convierta esos datos en una tabla con formato y filtros, y luego produzca un informe en la hoja Informe que muestre el total de ventas por vendedor ordenado de mayor a menor con estilo profesional; además, incluye un formulario con un TextBox que permita filtrar dinámicamente la tabla de ventas por nombre de vendedor.

Solución del desafío:

Código para realizar la tabla con datos aleatorios:
Option Explicit

' Genera datos aleatorios en la hoja "Ventas" con formato y filtros
Sub GenerarDatosAleatoriosConFormato()
Dim ws As Worksheet
Dim i As Long
Dim vendedores As Variant, productos As Variant

' Crear o limpiar hoja Ventas
On Error Resume Next
Set ws = ThisWorkbook.Sheets("Ventas")
If ws Is Nothing Then
    Set ws = ThisWorkbook.Sheets.Add
    ws.Name = "Ventas"
Else
    ws.Cells.Clear
End If
On Error GoTo 0

' Dejar 4 filas en blanco y poner encabezados en fila 5
ws.Range("A5:E5").Value = Array("Fecha", "Vendedor", "Producto", "Cantidad", "Precio Unitario")

' Listas de vendedores y productos
vendedores = Array("Ana", "Luis", "Carlos", "Marta", "Sofía")
productos = Array("Laptop", "Mouse", "Teclado", "Monitor", "Impresora")

' Generar 100 filas de datos aleatorios desde la fila 6
For i = 6 To 105
    ws.Cells(i, 1).Value = DateSerial(2025, Int((12 * Rnd) + 1), Int((28 * Rnd) + 1)) ' Fecha aleatoria
    ws.Cells(i, 2).Value = vendedores(Int(Rnd * (UBound(vendedores) + 1)))             ' Vendedor aleatorio
    ws.Cells(i, 3).Value = productos(Int(Rnd * (UBound(productos) + 1)))               ' Producto aleatorio
    ws.Cells(i, 4).Value = Int((20 * Rnd) + 1)                                         ' Cantidad aleatoria
    ws.Cells(i, 5).Value = Round((50 + Rnd * 450), 2)                                  ' Precio aleatorio
Next i

' Aplicar formato de tabla
Dim ultimaFila As Long
ultimaFila = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

Dim rng As Range
Set rng = ws.Range("A5:E" & ultimaFila)

' Convertir a tabla con estilo
Dim tbl As ListObject
Set tbl = ws.ListObjects.Add(xlSrcRange, rng, , xlYes)
tbl.Name = "TablaVentas"
tbl.TableStyle = "TableStyleMedium9"

' Ajustar columnas
ws.Columns("A:E").AutoFit

' Formato de columnas
ws.Columns("A").NumberFormat = "dd/mm/yyyy"
ws.Columns("D").NumberFormat = "0"
ws.Columns("E").NumberFormat = "$#,##0.00"

' Activar autofiltro automáticamente
tbl.Range.AutoFilter

End Sub

Código para generar el filtro:
Private Sub TextBox1_Change()
Dim filtro As String
filtro = "" & Me.TextBox1.Text & ""

With Sheets("Ventas").ListObjects("TablaVentas")
    If Me.TextBox1.Text = "" Then
        .Range.AutoFilter Field:=2 ' Mostrar todo si está vacío
    Else
        .Range.AutoFilter Field:=2, Criteria1:=filtro
    End If
End With

End Sub

Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad

2 respuestas

Código para generar el informe resumen de ventas:
' Genera el informe en la hoja "Informe" con formato mejorado pero sin filtros
Sub GenerarInforme()
Dim wsVentas As Worksheet, wsInforme As Worksheet
Dim dict As Object
Dim ultimaFila As Long, i As Long
Dim vendedor As String, total As Double
Dim vendedoresValidos As Variant

' Lista de vendedores válidos
vendedoresValidos = Array("Carlos", "Sofía", "Luis", "Marta", "Ana")

' Referencia a hoja Ventas
Set wsVentas = ThisWorkbook.Sheets("Ventas")
ultimaFila = wsVentas.Cells(wsVentas.Rows.Count, "A").End(xlUp).Row

' Crear o limpiar hoja Informe
On Error Resume Next
Set wsInforme = ThisWorkbook.Sheets("Informe")
If wsInforme Is Nothing Then
    Set wsInforme = ThisWorkbook.Sheets.Add
    wsInforme.Name = "Informe"
Else
    wsInforme.Cells.Clear
End If
On Error GoTo 0

' Usar diccionario para acumular ventas por vendedor
Set dict = CreateObject("Scripting.Dictionary")

For i = 6 To ultimaFila
    vendedor = wsVentas.Cells(i, 2).Value
    total = wsVentas.Cells(i, 4).Value * wsVentas.Cells(i, 5).Value
    
    ' Solo acumular si el vendedor está en la lista válida
    If Not IsError(Application.Match(vendedor, vendedoresValidos, 0)) Then
        If dict.Exists(vendedor) Then
            dict(vendedor) = dict(vendedor) + total
        Else
            dict.Add vendedor, total
        End If
    End If
Next i

' Encabezados en fila 5
wsInforme.Range("A5:B5").Value = Array("Vendedor", "Total Ventas")

' Resultados desde fila 6
For i = 0 To dict.Count - 1
    wsInforme.Cells(i + 6, 1).Value = dict.Keys()(i)
    wsInforme.Cells(i + 6, 2).Value = Round(dict.Items()(i), 2)
Next i

' Ordenar de mayor a menor
wsInforme.Range("A5:B" & dict.Count + 5).Sort Key1:=wsInforme.Range("B6"), _
    Order1:=xlDescending, Header:=xlYes

' Formato mejorado
wsInforme.Columns("A:B").AutoFit
wsInforme.Range("A5:B5").Font.Bold = True
wsInforme.Range("A5:B5").Interior.Color = RGB(200, 200, 200) ' Encabezado gris claro
wsInforme.Columns("B").NumberFormat = "$#,##0.00"

' Bordes a la tabla
With wsInforme.Range("A5:B" & dict.Count + 5).Borders
    .LineStyle = xlContinuous
    .Color = RGB(0, 0, 0)
    .Weight = xlThin
End With

MsgBox "Informe generado con formato mejorado.", vbInformation

End Sub

Resultado obtenido:
Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad

Hola Andrés, espero que estés bien

¡Qué interesante desafío estás abordando! Vamos a desglosar lo que necesitas hacer para completar tu sistema de ventas y reportes en Excel con VBA.

Generación de Datos Aleatorios

Ya tienes un buen comienzo con el código que genera datos aleatorios en la hoja "Ventas". Asegúrate de que cada columna esté correctamente formateada y que los filtros estén funcionando adecuadamente.

Creación del Informe Resumido

Para crear el informe que muestre el total de ventas por vendedor, puedes seguir estos pasos:

  1. Crear una nueva hoja llamada "Informe": Si no existe, créala y asegúrate de que esté limpia.

  2. Calcular el total de ventas por vendedor:

    • Puedes usar una tabla dinámica para resumir los datos. Aquí tienes un ejemplo de cómo hacerlo con VBA:
    Sub CrearInforme()
        Dim wsVentas As Worksheet
        Dim wsInforme As Worksheet
        Dim tbl As ListObject
        Dim pvtCache As PivotCache
        Dim pvtTable As PivotTable
        Dim rng As Range
    
        Set wsVentas = ThisWorkbook.Sheets("Ventas")
        On Error Resume Next
        Set wsInforme = ThisWorkbook.Sheets("Informe")
        If wsInforme Is Nothing Then
            Set wsInforme = ThisWorkbook.Sheets.Add
            wsInforme.Name = "Informe"
        Else
            wsInforme.Cells.Clear
        End If
        On Error GoTo 0
    
        Set tbl = wsVentas.ListObjects("TablaVentas")
        Set rng = tbl.Range
    
        ' Crear caché de tabla dinámica
        Set pvtCache = ThisWorkbook.PivotCaches.Create(xlDatabase, rng)
    
        ' Crear tabla dinámica
        Set pvtTable = pvtCache.CreatePivotTable(wsInforme.Cells(1, 1), "InformeVentas")
    
        ' Configurar la tabla dinámica
        With pvtTable
            .PivotFields("Vendedor").Orientation = xlRowField
            .PivotFields("Precio Unitario").Orientation = xlDataField
            .PivotFields("Precio Unitario").Function = xlSum
            .PivotFields("Precio Unitario").NumberFormat = "$#,##0.00"
            .DataBodyRange.Sort .PivotFields("Sum of Precio Unitario"), xlDescending
        End With
    
        ' Formato profesional
        wsInforme.Columns.AutoFit
    End Sub
    
  3. Formulario de Búsqueda: Ya tienes el código para el TextBox que filtra por vendedor. Asegúrate de que el formulario esté bien vinculado y que el filtro funcione correctamente.

Con estos pasos, deberías poder completar tu desafío. Si necesitas ajustar el formato o los detalles del informe, puedes hacerlo directamente en Excel después de que el informe sea generado.

Espero haber ayudado y ¡buenos estudios!