sábado, 5 de febrero de 2022

VBA EXCEL 2022: COMBOBOX DEPENDIENTE DE OTRO COMBOBOX

(AMBOS SON DINAMICOS E IGNORAN CELDAS VACIAS)


Con este código podremos llenar un cuadro combinado (ComboBox) dependiendo de los datos de otro cuadro combinado. Ambos cuadros son DINAMICOS e IGNORAN CELDAS VACÍAS, por lo cual puedes saltarte una fila o una columna y no verás espacios vacíos en tu objeto.  Los datos están en columnas de una hoja, y no necesitan estar en una tabla. 

ANTES: Nuestro libro de excel debe estar habilitada para ejecutar macros, es decir, con la extención .xlsm y nuestra pestaña de programador debe estar en modo diseño para que podamos escribir código y editar los objetos que vamos a utilizar.


PASO 1: Para ejemplificar el caso, tomamos un horario de clases de niñas de los primeros ciclos de primaria (facilitado por una amiga profesora, muchas gracias por cierto 👍🧡). Cada día tiene sus asignaturas y gracias a esto podremos ver en acción nuestros cuadros combinados. En una columna escribimos nuestros datos. Por el bien de este ejemplo, podremos un encabezado y además separaremos uno de nuestros datos del resto, pero no es necesario.


Datos en columnas. No es una tabla.


PASO 2Creamos un botón de comando(CommandButton) en una de nuestras hojas, en este caso la primera hoja, y también creamos un formulario. Hacemos doble clic sobre el botón de comando y escribimos lo siguiente:

Private Sub CommandButton1_Click()

UserForm1.Show

End Sub

Con esto mostraremos el formulario al hacer clic en el botón de comando.


PASO 3: En el formulario creamos dos cuadros combinados (ComboBox). Creamos también etiquetas (label) para describir qué datos nos mostrará el cuadro combinado. 



PASO 4: Hacemos doble click en el formulario y escribimos lo siguiente:

Private Sub UserForm_Initialize()

With Sheets("Hoja1")
For Each SchoolDay In .Range(.Cells(9, 2), .Cells(9, Columns.Count).End(xlToLeft))
If SchoolDay <> Empty Then 
ComboBox1.AddItem SchoolDay.Value
End If 
Next SchoolDay
End With

End Sub

Private Sub ComboBox1_click()

With Sheets("Hoja1")
For Each SchoolDay In .Range(.Cells(9, 2), .Cells(9, Columns.Count).End(xlToLeft))
If SchoolDay.Value = ComboBox1.Value Then
            SchoolDay.Select
For Each SchoolSubject In .Range(ActiveCell.Offset(1, 0), _
ActiveCell.Offset(Cells(.Rows.Count, ActiveCell.Column).End(xlUp).Row, 0))
If SchoolSubject <> Empty Then
ComboBox2.AddItem SchoolSubject.Value
End If
Next SchoolSubject
End If
Next SchoolDay
End With
 
End Sub
 
Private Sub ComboBox1_Enter()
 
ComboBox2.Clear
 
End Sub
 
El primer procedimiento privado (Private Sub), nos dice que al iniciar el formulario, nos posicionamos en la "Hoja1" y luego en el rango de celdas entre "B9" (Cells(9, 2)) y la ultima columna que encuentre con datos en esa misma fila. Por cada celda entre ese rango, si la celda no se encuentra vacía, se añadirá el valor de la celda al ComboBox1.  Con esto llenamos nuestro primer cuadro combinado con los días de la semana.   
 
Con el segundo procedimiento privado nos posicionandonos en la "Hoja1" y  tomamos el rango de celdas donde se encuentran los días de nuestra semana, al igual que en el paso anterior. Si el día que elejimos en el ComboBox1 coincide con uno de los días de la semana, seleccionará esa celda. Luego rellenara el ComboBox2 con los datos que existan en esa columna (las asignaturas de ese día), partiendo de la fila que se encuentra inmediatamente debajo y hasta la ultima fila que contenga datos en esa columna. Con esto logramos rellenar el segundo cuadro combinado de forma dinamica.  
 
Finalmente, limpiamos el ComboBox2 cada vez que entremos al ComboBox1.
 

PASO 5: Ejecutar



COMENTARIO: Este codigo me costó una contractura en el hombro y aún así no me siento conforme con la belleza en el resultado. Estaba destinado a publicarse el 26 de diciembre, pero lo deje un mes criando hongos por que no se me ocurría nada y finalmente terminé con esto, que es lo más dinamico y flexible que pude hacer. Espero que te saque del apuro ✨😊

No hay comentarios.:

Publicar un comentario