Generar reporte de base de datos con información repetida

Para James Bond

Cordial saludo,

Nuevamente recurro a su excelente dominio del tema de macros en excel, para solicitarle que de ser posible me colabore con el siguiente tema:

En esta ocasión necesito construir un reporte con la información contenida en una hoja de un archivo que contiene los siguientes encabezados:

No. Orden Emitida, Proveedor al que se le asignó la orden, Fecha de la orden, Valor Bruto, Valor Iva, Valor Total, Item, Cant, Det, los encabezados anteriores están a partir de la columna B, la información se registra a partir de la celda B3, la dificultad se me presenta debido a que la información para Item, Cant, Det, se repite en un total máximo de 130 columnas para cada uno y en el mismo orden, item es un código numérico, Cant, es la cantidad para ese item y Det, es la descripción del item, por lo tanto un mismo item puede estar en varias columnas. Lo que necesito en el informe es poder tener información para cada uno de los items, de en que orden se encuentra, que cantidad se solicitó, y a que proveedor se le asignó la orden, el archivo contiene una hoja donde están todos los items con su código y descripción, y la información para el informe se encentra en otra hoja de nombre producto (Hoja5), el nombre de la hoja contiene la información es Relacion_Ordenes (Hoja8). Si es neceaario le puedo enviar el achivo de trabajo.

Espero haber sido los suficientemente claro con la exposición de mi necesidad.

1 Respuesta

Respuesta
1

Sube una captura de pantalla de tu información me quedan algunas dudas por aclarar antes de darte una respuesta o pedirte el archivo

¿Esto es lo que buscas?, la macro esta abajo de la imagen, solo cambia el nombre de la hojas en los worksheets por el nombre de las hojas que manejes

Sub ANALIZAR_INFORMACION()
Set H1 = Worksheets("HOJA1")
Set h2 = Worksheets("HOJA2")
Set DATOS = H1.Range("B2").CurrentRegion
h2.Cells.Clear
With DATOS
    COLUMNA = H1.Range("G1").Column
    COLUMNAS = .Columns.Count
    DIFERENCIA = COLUMNAS - COLUMNA
    Set DATOS = .Rows(2).Resize(.Rows.Count - 1)
    Set DATOS2 = .Columns(COLUMNA).Resize(.Rows.Count, DIFERENCIA + 1)
    Set DATOS3 = .Resize(.Rows.Count, COLUMNA - 1)
    DIVIDIR = (DIFERENCIA + 1) / 3: FILAS = .Rows.Count
End With
With DATOS3
    For I = 1 To DIVIDIR
        If I = 1 Then
            Set DESTINO = h2.Range("B3").Resize(FILAS, COLUMNA - 1)
            Set PRODUCTO = .Columns(COLUMNA).Resize(FILAS, 3)
        End If
        If I > 1 Then
            Set DESTINO = DESTINO.Rows(FILAS + 1).Resize(FILAS, COLUMNA - 1)
            Set PRODUCTO = PRODUCTO.Columns(4).Resize(FILAS, 3)
        End If
        DESTINO.Value = .Value
        DESTINO.Columns(COLUMNA).Resize(FILAS, 3).Value = _
        PRODUCTO.Value
    Next I
End With
With DESTINO.CurrentRegion
    .Name = "PRODUCTOS"
    .Sort KEY1:=h2.Range(.Columns(7).Address), ORDER1:=xlAscending
    .Rows(0).Value = DATOS3.Rows(0).Value
    .EntireColumn.AutoFit
    .Cells(0, 7) = "Item"
    .Cells(0, 8) = "Cant"
    .Cells(0, 9) = "det"
End With
End Sub

Hola James Bond, buenas tardes:

Primero que todo muchas gracias por la celeridad con la que ha dado respuesta a mi consulta.

Lo que me envía se aproxima mucho a mi necesidad, creo que en el texto de la consulta no mencioné que el informe me debe quedar en un nuevo libro de trabajo, el código que me envía me organiza la información dentro de la misma hoja donde esta la base de datos, ¿sera posible generar el informe en un nuevo libro de trabajo?, además abusando de su gentileza, lo que quiero es poder generar el informe por un código de item determinado, se me ocurre utilizando un formulario donde pueda ingresar el código para el cual se desea generar el reporte, ¿sera esto posible?.

Nuevamente muchas gracias por el tiempo dedicado para resolver nuestras consultas.

Primero crea el siguiente formulario, es un combobox, un listbox y un botón comando y le pegas el código que viene abajo y en un modulo estándar pegas el primer código que puse en la primera respuesta, ambos códigos harán lo que pides.

´

Private Sub ComboBox1_Change()
valor = ComboBox1.Value
Set productos = Range("productos")
Set funcion = WorksheetFunction
With productos
    fila = funcion.Match(Val(valor), .Columns(7), 0)
    cuenta = funcion.CountIf(.Columns(7), valor)
    Set articulo = .Rows(fila).Resize(cuenta, .Columns.Count)
    .Columns(.Columns.Count + 3).CurrentRegion.Clear
    Set DESTINO = .Columns(.Columns.Count + 3).Resize(cuenta, .Columns.Count)
    DESTINO.Value = articulo.Value
    DESTINO.Rows(0).Value = productos.Rows(0).Value
    With ListBox1
        .ColumnCount = productos.Columns.Count
        .ColumnHeads = True
        .ColumnWidths = "80;180;40;40;40;40;40;60;60;"
        .RowSource = "=" & DESTINO.Address
    End With
    DESTINO.Name = "DESTINO"
End With
End Sub
Private Sub CommandButton1_Click()
Set DESTINO = Range("DESTINO").CurrentRegion
LIBRO = ActiveWorkbook.Name
Set nuevo = Workbooks.Add
With DESTINO
    Range("B2").Resize(.Rows.Count, .Columns.Count).Value = _
    DESTINO.Value
    Range("B2").CurrentRegion.EntireColumn.AutoFit
End With
Workbooks(LIBRO).Activate
End Sub
Private Sub UserForm_Initialize()
Dim UNICOS As New Collection
ANALIZAR_INFORMACION
Set productos = Range("PRODUCTOS")
With productos
    For i = 1 To .Rows.Count
        Item = .Cells(i, 7)
        On Error Resume Next
            UNICOS.Add Item, CStr(Item)
            If Err.Number = 0 Then ComboBox1.AddItem Item
        On Error GoTo 0
    Next i
    ComboBox1.ListIndex = 0
End With
Set producto = Nothing
End Sub

Hola James Bond buenas tardes:

Aun me queda un detalle que posiblemente no lo expliqué muy bn en la consulta, y en la revisión anterior no lo observé, y es que en la hoja Productos se encuentra la relación de todos los items, idependiente de que esten o no en la hoja que contiene la base de datos, la idea es que el combobox pueda leer ya sea el código del item que esta en la columna A, o la descripción que esta en la columna B, seria maravilloso si en el combo se pudiran mostrar los dos datos concatenados, pero que la busqueda la realice por el código.

Actualmente me esta reemplazando la información de la hoja productos con la información de la hoja Relacion_Ordenes, la idea es que la información de ninguna de las hojas del archivo sea modificada, esta es la razón por la cual el informe debe ser generado en un libro nuevo, esta parte ya la hace muy bien.

Nuevamente agradezco su valioa colaboración.

adjunto imagen del la hoja Productos.

La idea es esta creas el formulario que te indique con un cambio el label2 ahora te indicara el nombre de producto que elijas del combobox, label3 la definió como resumen y en el formulario pegas el siguiente código

esta es la macro que debes pegar en el formulario, después en un modulo estándar pegas el código más abajo, la macro cargara los datos de la hoja producto ene l combobox y luego dependiendo de cual escojas te cargara en el listbox y en la hoja reporte un resumen del código a buscar y una vez que des click en el botón te lo enviara a un nuevo libro sin modificar nada en las hojas producto ni relacion_ordenes

Private Sub ComboBox1_Change()
Set lista = Range("lista"): Set productos = Range("PRODUCTOS")
Set funcion = WorksheetFunction: valor = ComboBox1.Value
With lista
    If valor <> vbNullString Then
        fila = funcion.Match(Val(valor), .Columns(1), 0)
        Label2 = .Cells(fila, 2)
    End If
End With
With productos
    .Columns(.Columns.Count + 3).CurrentRegion.Clear
    On Error Resume Next
    fila = funcion.Match(Val(valor), .Columns(7), 0)
    On Error GoTo 0
    registros = funcion.CountIf(.Columns(7), Val(valor))
        If registros > 0 Then
            Set detalle = .Rows(fila).Resize(registros, .Columns.Count)
            Set articulos = .Columns(.Columns.Count + 3).Resize(registros, .Columns.Count)
            articulos.Rows(0).Value = .Rows(0).Value
            articulos.Value = detalle.Value
            articulos.CurrentRegion.Name = "destino"
            With ListBox1
                .ColumnCount = productos.Columns.Count
                .ColumnHeads = True
                .ColumnWidths = "80;160;80;60;60;60;40;40;180"
                .RowSource = "hoja_reporte!" & articulos.Address
            End With
        End If
End With
End Sub
Private Sub CommandButton1_Click()
Set DESTINO = Range("DESTINO")
LIBRO = ActiveWorkbook.Name
Set nuevo = Workbooks.Add
With DESTINO
    Range("B2").Resize(.Rows.Count, .Columns.Count).Value = _
    DESTINO.Value
End With
Workbooks(LIBRO).Activate
End Sub
Private Sub UserForm_Initialize()
Dim UNICOS As New Collection
ANALIZAR_INFORMACION
Set hp = Worksheets("productos")
Set productos = hp.Range("a1").CurrentRegion
With productos
    Set productos = .Rows(2).Resize(.Rows.Count - 1, 2)
    .Name = "lista"
    matriz = productos
    With ComboBox1
        .ColumnCount = productos.Columns.Count
        .ColumnWidths = "20;60"
        .List = matriz
        .ListIndex = 0
    End With
End With
Set producto = Nothing
End Sub
Sub ANALIZAR_INFORMACION()
Set H1 = Worksheets("relacion_ordenes")
Set h2 = Worksheets("Hoja_reporte")
Set datos = H1.Range("B2").CurrentRegion
h2.Cells.Clear
With datos
    COLUMNA = H1.Range("G1").Column
    COLUMNAS = .Columns.Count
    DIFERENCIA = COLUMNAS - COLUMNA
    Set datos = .Rows(2).Resize(.Rows.Count - 1)
    Set DATOS2 = .Columns(COLUMNA).Resize(.Rows.Count, DIFERENCIA + 1)
    Set DATOS3 = .Resize(.Rows.Count, COLUMNA - 1)
    DIVIDIR = (DIFERENCIA + 1) / 3: FILAS = .Rows.Count
End With
With DATOS3
    For i = 1 To DIVIDIR
        If i = 1 Then
            Set DESTINO = h2.Range("B3").Resize(FILAS, COLUMNA - 1)
            Set producto = .Columns(COLUMNA).Resize(FILAS, 3)
        End If
        If i > 1 Then
            Set DESTINO = DESTINO.Rows(FILAS + 1).Resize(FILAS, COLUMNA - 1)
            Set producto = producto.Columns(4).Resize(FILAS, 3)
        End If
        DESTINO.Value = .Value
        DESTINO.Columns(COLUMNA).Resize(FILAS, 3).Value = _
        producto.Value
    Next i
End With
With DESTINO.CurrentRegion
    .Name = "PRODUCTOS"
    .Sort KEY1:=h2.Range(.Columns(7).Address), ORDER1:=xlAscending
    .Rows(0).Value = DATOS3.Rows(0).Value
    .EntireColumn.AutoFit
    .Cells(0, 7) = "Item"
    .Cells(0, 8) = "Cant"
    .Cells(0, 9) = "det"
End With
End Sub

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas