Una consulta que necesita de una entrada completa, para repasar un poco sobre los Eventos en VBA.
Mi lector Julián (al cual también agradezco las palabras que me dedica en su correo) tiene el siguiente problema: tiene 3 rangos definidos en una hoja, y cada rango posee 10 celdas y una columna. El usuario debe seleccionar uno de esos rangos, pero solamente "ese" rango, sin ninguna celda adicional. Aparte, si hacen click dentro de alguno de esos tres rangos, la macro debe conocer sobre cual de ellos clickearon. Estimo que Julián está armando algún juego o algo por el estilo.
tres rangos, de 10 filas y una columna cada uno. veremos la forma de identificarlos desde VBA
[+/-] Ver el resto / Ocultar
Al principio del post nombré a los Eventos. Estos son acciones que se disparan dentro de Excel y que nosotros podemos "capturar", aprovechándolos para allí insertar nuestro código.
En este caso utilizaremos el evento SelectionChange, del objeto Worksheet, es decir, cada vez que la selección cambie en la hoja activa. Nos dirigimos al Explorador de Proyectos y hacemos doble click sobre el nodo de la Hoja1, para abrir su ventana de código:
Seleccionamos el evento mencionado:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
End SubVemos que tiene un argumento: "Target", del tipo Range, que no es otra cosa que el rango sobre el cual cambió la selección. Este evento se disparará cada vez que el cursor cambie de celda, o sea cada vez que cambie la selección, que puede ser múltiple (muchas celdas) o única.
Pasemos a resolver una de las dudas planteadas: si el usuario hace click dentro de "rojo", "azul" o "amarillo" debo saberlo y almacenar ese dato. Caso contrario, si hace click en cualquier otra parte de la hoja, no pasa nada. Antes de generar el código, seleccioné uno x uno los tres rangos y dentro del Cuadro de Nombres (a la izquierda de la barra de fórmulas) ingresé los nombres respectivos:
Y luego en la ventana de Hoja1:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Application.Intersect(Range("rojo"), Target) Is Nothing Then
MsgBox "dentro de rojo"
ElseIf Not Application.Intersect(Range("azul"), Target) Is Nothing Then
MsgBox "dentro de azul"
ElseIf Not Application.Intersect(Range("amarillo"), Target) Is Nothing Then
MsgBox "dentro de amarillo"
End If
End Sub
El Sub es sencillo: Target trae a mis manos que rango seleccionó el usuario. Luego con Intersect me fijo si Target está o nó dentro un determinado rango, mejor dicho, si se "cruza" o "intersecta". Yo muestro un Msgbox, pero podríamos almacenar en alguna variable el resultado. Las imágenes respectivas:
noten como la selección está dentro de los distintos colores en cada caso.
Para solucionar los dos planteamientos, el código nos quedaría:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'si el tamaño del rango seleccionado es menor a 10 filas e igual
'a una columna, aplico la primer parte del código:
If Target.Rows.Count < 10 And Target.Columns.Count = 1 Then
If Not Application.Intersect(Range("rojo"), Target) Is Nothing Then
MsgBox "dentro de rojo"
ElseIf Not Application.Intersect(Range("azul"), Target) Is Nothing Then
MsgBox "dentro de azul"
ElseIf Not Application.Intersect(Range("amarillo"), Target) Is Nothing Then
MsgBox "dentro de amarillo"
End If
'si el tamaño del rango seleccionado es de 10 filas y 1 columna:
ElseIf Target.Rows.Count = 10 And Target.Columns.Count = 1 Then
'en primera instancia almaceno la cantidad de nombres presentes en el
'libro:
j = ThisWorkbook.Names.Count
'luego con un for recorro todos los nombres, y los comparo contra
'el nombre de la seleccion actual
For x = 1 To j
If ThisWorkbook.Names(x).RefersTo = Selection.Name Then
MsgBox ThisWorkbook.Names(x).Name
End If
Next x
End If
End Sub
Si tenemos muchos nombres de rango en el libro podemos acotar la búsqueda haciendo referencia también al nombre de la hoja. Por ejemplo la linea
ThisWorkbook.Names(x).RefersTo
nos devuelve: =Hoja1!$D$1:$D$10
Por qué? Por que el nombre "azul" hace referencia (RefersTo) al rango Hoja1!$D$1:$D$10
Teniendo a mano el nombre de la hoja (en este ejemplo la Hoja1), podremos hacer la comparativa y buscar nombres en una sola, omitiendo las demás.
Espero Julián que te sea de utilidad y de nuevo gracias x tu mail.
revisando la ayuda de Excel sobre el tema planteado, encontré un buen ejemplo de como buscar Nombres de Rangos dentro de un libro. Para tener en cuenta:
ResponderEliminarSub UnaAyuditaDeMicrosoft()
Set nms = ActiveWorkbook.Names
Set wks = Worksheets(1)
For r = 1 To nms.Count
wks.Cells(r, 2).Value = nms(r).Name
wks.Cells(r, 3).Value = nms(r).RefersToRange.Address
Next
End Sub