Ejemplo de uso de Cuadro de lista y Cuadro combinado en la obtención de un reporte

Abra el archivo FPedidos.xlsx haciendo clic aquí

Como puede ver, contiene las dos hojas vistas anteriormente y además, la hoja Empleados que contiene la lista de los empleados y una nueva hoja: Tempo. Allí guardaremos todos los registros extraídos de la hoja Detalle, tomando en cuenta dos criterios:

a) Dado un código de pedido, guardaremos todos los productos contenidos en el pedido y que se encuentran en la hoja Detalle; los pasaremos a una lista y desde allí, a todos los seleccionados, los transferiremos hacia la hoja Tempo.

b) De la lista de los empleados que se ha cargado cuando se dio inicio el formulario, seleccionaremos a un empleado y a todos los clientes atendidos por este empleado, los listarmeos en la lista inferior, para luego de seleccionar a uno de ellos, transferir todo su pedido a la hoja Tempo.

Después de cada transferencia, se podrá realizar otra para lo cual se deberá limpiar ciertos objetos contenedores.

Puesto que son dos opciones no tan claras, las indicaciones se deberán emitor en un recuadro de comentario al momento de iniciar la ejecución del formulario. Para ver este comentario, se deberá pasar el cursor por encima del recuadro del comentario.

Igualmente, la lista de los empleados deberá cargarse una sola vez, para ello, debemos cargarlo en el momento de inicialiarse el formulario.

Empecemos grabando este libro, habilitado para macros, como ConsPedido.xlsm.

Bien, vaya al editor e inserte un formulario de usuario, su [Name] FrmConsulta, su [Caption] Formulario de consulta de pedidos.

Inserte los siguientes botones de control:

- Inserte un botón de [Etiqueta] en la parte superior que ocupe 8 líneas y 50 columnas. Su [Name] Lab01, su [Caption] Deslice el mouse por esta zona.
- Un [Cuadro de texto], su [Name] TxtPedido
- A su costado, un botón [Comando], su [Name] CmdCons, su [Caption] Consultar
- A su costado, un [Cuadro combinado], su [Name] CboEMpleados
- A su derecha, un botón de [Comando], su [Name], CmdLoad
- Encima de TxtPedido, una [Etiqueta] con [Caption] Nro pedido
- Encima de CboEmpleados, una [Etiqueta] con [Caption] Lista de empleados
- Cinco líneas más abajo un [Cuadro de lista] debajo de TxtPedido, su [Name] LstProductos
- A la misma altura y debajo de CboLista, un [Cuadro de Lista], su [Name] LstClientes
- A la derecha un botón de [Comando] su [Name] CmdNuevo, su [Caption] Otra consulta
- Por encima de CboLista, una [Etiqueta] con [Caption] Lista de productos en el pedido
- Por encima de LstClientes, una [Etiqueta] con [Caption] Lista de clientes atendidos por el empleado
- Debajo de CboLista, un botón de [Comando], su [Name] CmdTransf01, su [Caption] Transferir
- Debajo de CboClientes, botón de [Comando], su [Name] CmdTransf02, su [Caption] Transferir
- Al final y a la derecha, un botón de [Comando], su [Name] CmdFin, su [Caption Salir

Una imagen de este formulario se muestra el final de este texto. Allí, como puede ver, hemos insertado una imagen , para ello seleccionamos en la ventana de propiedades y elegimos una imagen que lo adjuntamos en la misma dirección arriba mencionada.

Programemos estos botones:

Doble clic en el botón [Salir]
Ingrese la instrcción: End
Doble clic en la etiqueta Lab01:

Estando en su procedimiento, despliegue la lista de los procedimientos (la segunda imagen adjunta lo indica) y seleccione [MouseMove], ubique dicho procedimiento y en ella digite su contenido, que debe quedar como lo mostramos aquí:

Private Sub Lab01_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

Lab01.Caption = "Este formulario permite realizar consultas desde el archivo Pedidos.xlsx" + Chr(13) + _
"Las consultas se pueden hacer ingresando el número de pedido o seleccionando un empleado de la lista." + Chr(13) + _
Chr(13) + _
"Todas las consultas son copiadas hacia la hoja Tempo del Excel."
End Sub
 

Compruebe una vez más que el contenido del formulario sea el que se muestra en la primera imagen adjunta.

Como dijimos líneas arriba, al inciarse la ejecución del formulario, se debe activar el libro ConsPedido.xlsm y se debe activar también la hoja Pedidos.

Del mismo modo, el cuadro combinado CboEmpleados se debe cargar desde la hoja Empleados.

Para ello debemos codificar el procedimiento privado correspondiente al formulario. Para ello, haga doble clic en cualquier parte del formulario.

Debe obtener lo siguiente:

Private Sub UserForm_Click()
End Sub
 

Pero este procedimiento se ejecutará sólo cuando hagamos clic en cualquier del formulario.

Nosotros queremos que se autoejecute al iniciar el formulario. Por ello desplieque la lista de los procedimientos de la barra que se muestra en la segunda imagen adjunta y de esa lista seleccione [Initialize], con lo cual tendrá

Private Sub UserForm_Initialize()
End Sub
 

Este procedimiento debe hacer lo dicho en el párrafo anterior, con lo cual debe quedar así:

Private Sub UserForm_Initialize()
End Sub

Workbooks("ConsPedidos.xlsm").Activate
Sheets("Empleados").Select
Range("A2").Select
nF = Selection.End(xlDown).Row
For i = 1 To nF
CboEmpleados.AddItem Cells(i + 1, 2)
Next
Sheets("Tempo").Select
Range("A2").Select
Range("A3") = "Nro pedido"
Range("B3") = "Producto"
Range("C3") = "Pr.unit"
Range("D3") = "Cantidad"
Range("E3") = "Descuento"
Range("F3") = "Monto"
End Sub
 

Note que también estamos ingresando la cabecera en la fila 3 de la hoja Tempo, en donde se va a recibir lo transferido de la hoja Detalle via el formulario.

Bien, veamos qué debe suceder al usar la opción de búsqueda

a). Al digitarse el código de un pedido, se debe ir a la hoja Detalle para buscar dicho código, buscarlo en la columna A y, cada vez que ActiveCell sea igual a dicho código, lo añadiremos a la lista LstProductos.

Si bien en la hoja Pedidos, hay un solo registro para cada código de pedido, en la hoja Detalle, hay más de uno, como el caso del código 11077 que tiene más de 10 registros.

Por ello se debe hacer uso del While para buscar todos ellos. Esto debe ocurrir al presionar el botón (CmdCons).

Por tanto, haga doble clic en el botón e ingrese el siguiente código que aquí se muestra:

Private Sub CmdCons_Click()
Workbooks("ConsPedidos.xlsm").Activate
Sheets("Detalle").Select
xCod = Val(TxtPedido.Text)
Range("A2").Select
k = 0
While ActiveCell <> ""
If xCod = ActiveCell Then
LstProductos.AddItem Cells(ActiveCell.Row, 2)
k = k + 1
xFila(k) = ActiveCell.Row
End If
ActiveCell.Offset(1, 0).Select
Wend
Range("A1").Select
Sheets("Pedidos").Select
Range("A1").Select
End Sub
 

Ahora, deseamos transferir a la hoja Tempo todos aquellos que querramos. Para ello se debe hacer clic en los productos que se desee, uno o más; consecutivos o no.

Lo más importante, de acuerdo a nuestro estilo de programación, será saber qué producto y de qué fila de la hoja Detalle se está seleccionando. Para ello, paralelamente a guardar en la lista LstProductos, hemos guardado el nro d fila en donde se encontró, lo que se hizo en el procedimiento anterior, que lo guardamos en una tabla xFila().

Bien, después de seleccionar los que se desee, se debe hacer clic en el botón de la parte inferior. Este botón deberá disponer del número de productos seleccionados y, mediante un For … Next para buscarlo en la hoja Detalle y extraer toda la fila hacia la hoja Tempo, a partir de la fila 3, para lo cual usaremos un contador K, que se debe incrementar en uno, cada vez que se encuentra uno (K = K +1).

El código es el siguiente:

Private Sub CmdTransf01_Click()
nL = LstProductos.ListIndex
k = 0
Sheets("Detalle").Select
With Sheets("Detalle")
For i = 0 To nL
If LstProductos.Selected(i) Then
nF = xFila(i + 1)
k = k + 1
Sheets("Tempo").Cells(3 + k, 1) = .Cells(nF, 1)
Sheets("Tempo").Cells(3 + k, 2) = .Cells(nF, 2)
Sheets("Tempo").Cells(3 + k, 3) = .Cells(nF, 3)
Sheets("Tempo").Cells(3 + k, 4) = .Cells(nF, 4)
Sheets("Tempo").Cells(3 + k, 5) = .Cells(nF, 5)
Sheets("Tempo").Cells(3 + k, 6) = .Cells(nF, 6)
End If
Next
End With
Sheets("Tempo").Select
Range("A1").Select
End Sub

En cuanto a la segunda opción, aquella que consiste en extraer los productos pertenecientes a un cliente atendido por un empleado, el procedimiento es el siguiente:

Como ya la tabla CboEmpleados se ha cargado al inciarse la ejecución del formulario, ahora debemo seleccionar a uno de los empleados para que, al hacer clic en el botón [Cargar lista], se coloquen en la lsita LstClientes, los nombres de todos los clientes atendidos por dicho empleado. Para ello haga doble clic en el botón y digite el siguiente código:

Private Sub CmdLoad_Click()

xEmp = CboEmpleados.List(CboEmpleados.ListIndex)
Sheets("Pedidos").Select
Range("C2").Select
While ActiveCell <> ""
If ActiveCell = xEmp Then
LstClientes.AddItem Cells(ActiveCell.Row, 2)
End If
ActiveCell.Offset(1, 0).Select
Wend
Sheets("Pedidos").Select
Range("A1").Select
End Sub

de la parte inferior.

En consecuencia, al hacer clic en este botón, capturamos el nombre del cliente, nos vamos a la hoja Pedido, buscamos dicho nombre en la columna B y al encontrarlo, extraemos el código de pedido xCod, para luego irnos a la hoja Detalle y realizar la búsqueda de este código.

Cada vez que se encuentra, se debe extraer la fila hacia la hoja Tempo.

El código de este botón es el siguiente:

Private Sub CmdTransf02_Click()
Sheets("Pedidos").Select
xClie = LstClientes.List(LstClientes.ListIndex)
Range("B2").Select
While ActiveCell <> xClie
ActiveCell.Offset(1, 0).Select
Wend
xCod = Cells(ActiveCell.Row, 1)
Sheets("Detalle").Select
k = 0
Range("A2").Select
With Sheets("Detalle")
While ActiveCell <> ""
If xCod = ActiveCell Then
nF = ActiveCell.Row
k = k + 1
Sheets("Tempo").Cells(3 + k, 1) = .Cells(nF, 1)
Sheets("Tempo").Cells(3 + k, 2) = .Cells(nF, 2)
Sheets("Tempo").Cells(3 + k, 3) = .Cells(nF, 3)
Sheets("Tempo").Cells(3 + k, 4) = .Cells(nF, 4)
Sheets("Tempo").Cells(3 + k, 5) = .Cells(nF, 5)
Sheets("Tempo").Cells(3 + k, 6) = .Cells(nF, 6)
End If
ActiveCell.Offset(1, 0).Select
Wend
End With
Sheets("Tempo").Select
Range("A1").Select
End Sub
 

Observación:

Observe que, en ambos casos de transferencia, hemos usado la sentencia With con la intención de reducir la extensión de la instrucción y facilitar su procesamiento. Por ello es que, en el segundo miembro de cada línea sólo aparece “.Cells…”, se obvia Sheets(“Detalle”).

El último botón que falta programar es . Su código es simple:

Private Sub CmdNuevo_Click()
Sheets("Tempo").Select
Range("A4:Z50").ClearContents
TxtPedido.Text = ""
LstProductos.Clear
LstClientes.Clear
TxtPedido.SetFocus
End Sub
 

Finalmente y lo más importante, como hay variables o tablas que se emplean en algunos procedimientos deben ser usado en otros y, siendo estos procedimientos privados, debemos declarar estas variables o tablas como globales por ello, hemos declarado lo mínimo indispensable mediante DIM al inicio de todo:

Dim xCod As Variant
Dim xFila(831) As Variant

Grabe el archive con el nombre ConsPedidos.xlsm. Si desea verlo, haga clic aquí

La siguiente imagen muestra el formulario descrito

Para ir a la siguiente sesión, haga clic aquí