[Bucle en CheckBox de VBA Excel]

Resuelto
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro -  
 latuque -
¡Hola a todos!

Tengo un pequeño problema con las CheckBox (casillas de verificación). He creado un Userform en Excel con 52 CheckBox numeradas del 1 al 52, correspondientes a las semanas (CheckBox1 -> S01, ..., CheckBox52 -> S52), y he añadido un botón "Seleccionar todo" para poder seleccionarlas todas automáticamente. Mi problema es el siguiente: no consigo programar un bucle sobre las CheckBox para que funcione... He probado el siguiente código:

Dim i As Integer
For i = 0 To 52
CheckBox.i.Value = True
Next i

pero no funciona. Incluso he intentado usar corchetes, paréntesis o llaves, pero no hay manera... (CheckBox[i], CheckBox(i) ...). Me da un mensaje de error cada vez.
Así que me gustaría pedirles si saben cómo crear un bucle con las CheckBox, sabiendo que este botón "Seleccionar todo" es solo el primero (y el más simple) de mis problemas...
¡Muchas gracias!

Salim
Configuración: Windows XP Internet Explorer 6.0 Office 2003

22 respuestas

  • 1
  • 2
Usuario anónimo
 
Hola,

¡Sí, por supuesto! Excel (más bien VBA) no tiene una colección en términos estrictos. A diferencia de VB...

Todos los problemas que enfrentan vienen de ahí. ¡Por lo tanto, es imposible asignar un número en una colección de un tipo particular de objeto! La única colección que conoce (Excel) es UserForm1... Todos los objetos en un UserForm están en una sola colección (cualquiera que sea el tipo)... Así, las casillas de verificación o etiquetas y otros se indexan unos tras otros sin distinción.

La "trampa" para navegar dentro de un solo tipo de objeto es usar, por ejemplo, el comienzo del nombre genérico. Por ejemplo, para marcar todas las CheckBox (TRUE), basta con verificar si el inicio del nombre comienza con "CheckBox" y luego repasar cada objeto...

Concretamente, coloque algunas CheckBox en un UserForm1 y un botón.

Detrás del botón, coloque el siguiente código:

=

Private Sub CommandButton1_Click()

Dim ole1 As Control
For Each ole1 In UserForm1.Controls
If Left$(ole1.Name, 8) = "CheckBox" Then ole1.Value = True
Next

End Sub

=

y cuando haga clic en el botón, todas las casillas de verificación estarán marcadas... Por supuesto, el principio es aplicable a otros objetos...

AQUÍ uso el comienzo del Nombre (Name) del objeto, pero se podría usar otra propiedad. GroupName está hecho para eso...

--
¡Hasta luego!
Saludos, Us.
5
sncf Mensajes publicados 122 Estado Miembro 14
 
Efectivamente, no había pensado en esta solución, la verdad es que es bastante elegante.
Gracias por la información (lo tengo en cuenta, nunca se sabe).
0
Usuario anónimo > sncf Mensajes publicados 122 Estado Miembro
 
Sí, efectivamente...

He sido un poco radical al decir que solo había el userform... De hecho, también se pueden usar los FRAME que también poseen la colección CONTROLS... Así que se puede repasar solo dentro de ellos... Lo que es aún más elegante... Con: For Each ole1 In Frame1.Controls

En fin, creo que habrás entendido el principio...

--
Con cariño, Us.
0
xjl Mensajes publicados 232 Estado Miembro 183
 
Lo siento, te interrumpo, pero ¿alguien sabe por qué este código no funciona?:

For Each CheckBox In Sheets(1).CheckBoxes
CheckBox.Value = True
Next CheckBox

Tengo la impresión de que no encuentra los CheckBox en la colección y no entiendo por qué, pero si alguien logra hacer funcionar este código, resolverá el problema...
1
sncf Mensajes publicados 122 Estado Miembro 14
 
Hola

Coloca todas tus casillas de verificación en un marco (frame1)

luego intenta

for i = 0 to 51 (empezando la numeración en 0 para el primer control en el marco)
frame1(n)=true
siguiente i
0
latuque
 
Hola, pero cuando dices que debo poner las casillas de verificación en un marco, no encuentro el objeto marco, tengo un grupo de opciones, pero eso no me permite marcar más de una casilla a la vez y aparte de eso solo veo el rectángulo, pero no creo que eso sea.

Gracias por responderme lo más rápido posible.
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Gracias, SNCF, por tu rápida respuesta :)

He probado lo que me diste, pero lo único que hace es marcar la primera CheckBox (CheckBox1) únicamente cuando hago clic en el botón "Seleccionar todo"... Por lo tanto, hay un problema.
Cuando miré más de cerca, noté que el "i" de la incrementación no aparecía en la línea de comando, así que me parece normal que solo haya una CheckBox marcada... ¿Qué piensas?

Salim
0
sncf Mensajes publicados 122 Estado Miembro 14
 
Mis disculpas
aquí está el código correcto

Dim i As Integer
For i = 0 To 51
Me.Frame1(i) = True
Next i
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
No funciona todavía... Creo que viene del "Me" cuyo significado no entiendo.
Además, la respuesta a xjl también me interesa mucho.
Gracias de antemano ;)
0
sncf Mensajes publicados 122 Estado Miembro 14
 
remplace userform1 par formulario1 (el nombre de tu formulario)
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
¡Genial! Muchas gracias, SNCF ;) Parece que funciona.
Voy a probar eso de inmediato en mi proyecto y ver si puede solucionar mis problemas. Te doy la respuesta en cuanto se hagan las pruebas.
¡Gracias de nuevo! :)
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
¡Ay! Tengo un pequeño problema nuevamente... En mi Userform, no solo hay CheckBox, sino también Label (etiquetas) para indicar que tal semana está relacionada con tal casilla de verificación... Estas etiquetas están numeradas de la misma manera que las CheckBox. Así que cuando ejecuto tu programa, me cambia el nombre de las etiquetas (las etiquetas pasan de "S01", "S02"... a "True").
¡Vaya problemas! lol
Intenté sacar las etiquetas del Frame, pero el Frame sigue siempre en primer plano... Y también intenté usar Userform1.Frame1(i).Value = True, pero me da un mensaje de error...
0
sncf Mensajes publicados 122 Estado Miembro 14
 
No entiendo, ¿cómo se llama tu primera casilla de verificación y cómo se llama tu primera etiqueta y cuál es la etiqueta?
¿Las etiquetas también están en el frame1?
0
sncf Mensajes publicados 122 Estado Miembro 14
 
¿Cuál es la utilidad de poner una etiqueta para indicar S01 cuando en las propiedades de la casilla de verificación tienes un título que te permite hacerlo (además eso reduce a la mitad la cantidad de controles)?
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Bueno, es para aquel que va a usar el Userform, si no sabe qué CheckBox corresponde a qué semana (porque tendrá que marcar algunas o todas las casillas...), el Userform en sí no tiene razón de existir...
0
sncf Mensajes publicados 122 Estado Miembro 14 > salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
OK, pero la propiedad "Caption" del checkbox te permite justamente hacerlo (en realidad es una etiqueta integrada en la checkbox), de ahí mi pregunta
¿Por qué no utilizar esta propiedad de cada checkbox y eliminar todas estas etiquetas que se han vuelto innecesarias?
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro > sncf Mensajes publicados 122 Estado Miembro
 
He modificado la propiedad Caption, pero el nombre no aparece en el Userform. ¿Es normal?
0
sncf Mensajes publicados 122 Estado Miembro 14 > salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Para verlo más claro, ¿puedes enviarme tu formulario (exportado en el menú de archivo del editor de Visual Basic (CTRL+E) para generar un archivo frm)? Te envío un mensaje privado para indicarte mi dirección de correo electrónico.
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Para ser claro, cada semana i está asociada a una casilla de verificación numerada i (CheckBox25 para la semana 25, por ejemplo), y cada CheckBox i está acompañada por una etiqueta del mismo número i (Label25 para la CheckBox25, cuyo texto es "S25").
Por lo tanto, la semana 25 se indica con una casilla de verificación justo al lado de una etiqueta "S25". Por supuesto, las etiquetas también forman parte del marco...
Espero que esté claro :) Si no, no dudes en preguntarme.
0
sncf Mensajes publicados 122 Estado Miembro 14
 
Para aclararlo, ¿puedes enviarme tu formulario (exportar CTRL+E para generar un archivo frm)? Te enviaré un mensaje privado para indicarte mi dirección de correo electrónico.
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Está enviado ;)
El objetivo de este Userform es simplificar el uso de un programa VBA. El usuario podrá elegir las semanas que desee en el Userform, y este se encargará de ejecutar los programas para esas semanas. El botón Seleccionar todo no es más que un inicio, como dije en mi primer post.
0
sncf Mensajes publicados 122 Estado Miembro 14
 
solutions para resolver tu problema
Solución 1

Eliminación de la etiqueta Label1 (en realidad solo la he movido debajo de S02)
Redimensionamiento de la Checkbox1 (ella ocultaba todo lo que podías escribir en caption)
Caption = S01
Alignment = 0 –fmAlignmentLeft
TextAlign = fmTextAlignRight
Al redimensionar ligeramente en altura obtienes el resultado deseado y de paso eliminas la mitad de los controles (todas las Labels)

0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Justo estaba a punto de escribirte que la segunda solución no funcionaba... Habría sido más rápida... ¡Qué pena!
Me voy a poner con la primera, que seguro que funciona ;)
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
¡Mil gracias, chicos!
He optado por la solución de SNCF, que funciona muy bien, porque ya me había comprometido con esta vía, pero la solución de Us también me parece muy ingeniosa.
De todos modos, he logrado hacer lo que quería, ¡gracias a ustedes! ;)
Dos preguntitas muy pequeñas para el camino:
1. ¿Cómo hacer referencia al Userform desde las macros?
2. Al hacer clic en OK, el Userform me generará el programa que quiero, pero me gustaría que el Userform se cierre automáticamente justo después. ¿Cómo se hace?

Salim

EDIT: encontré la solución para la primera pregunta ;) fui a los módulos, escribí:

Sub UserForm()
UserForm1.Show
End Sub

y eso me creó una macro para mostrar mi Userform

EDIT bis: de igual manera, encontré la solución para la segunda pregunta (definitivamente, estoy en racha hoy, lol). Esta vez, hay que poner al final del Private Sub del botón Validar: Userform1.Hide... ¡Sencillo! ;)
Gracias nuevamente por su amabilidad, su competencia y su paciencia :)
Hasta pronto

Salim
0
Usuario anónimo
 
Salim, mira las respuestas publicadas a continuación...
--
Amicalement, Us.
0
salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro > Usuario anónimo
 
Ui ui, lo he visto bien :)
Prefiero con mucho Unload a Hide, aunque mantengo mi Show, me gusta mucho jaja
Gracias por estas precisiones muy instructivas :)

Salim
0
sncf Mensajes publicados 122 Estado Miembro 14 > salim2103 Mensajes publicados 49 Fecha de registro   Estado Miembro
 
Salim, estoy de acuerdo con ustedes.
Para cerrar el formulario, hay que estar seguros de que no necesitamos más los datos contenidos en él, de lo contrario es un lío.
--
Pascal
0
Usuario anónimo > Usuario anónimo
 
Sí, la mayoría de las veces usamos SHOW y UNLOAD, ¡pero en cuanto utilizas varios USERFORM, encontrarás más elegante solo ocultar los Userform, es más ventajoso (bueno, más sencillo para programar)... De hecho, así puedes seguir leyendo los datos ingresados sin tener que colocarlos en variables auxiliares... Así que, hasta luego
--
Amistosamente, Us.
0
Usuario anónimo
 
USERFORM1.SHOW = Carga y lanza el userform1

USERFORM1.LOAD = Carga el userform1 (pero no lo muestra)
USERFORM1.HIDE = Oculta el userform1 (permanecerá en memoria siempre que esté cargado)

UNLOAD USERFORM1 = Descarga el Userform1, ¡así que cierra el userform (ya no es visible)!

En general, se utiliza este último detrás de un botón donde se codifica:

Unload Me

Ahí tienes un poco de vocabulario... :-);

--
Amistosamente, Us.
0
sncf Mensajes publicados 122 Estado Miembro 14
 
para cerrar un formulario llamado userform1
unload userform1
--
Pascal
0
Philippe
 
Hola a todos,
Es mi primer post aquí
Tengo una pequeña pregunta tonta (espero que no haya encontrado respuesta en otro lugar)
He creado checkboxes en un userform y scripts que se ejecutan cuando se activan. Por ejemplo: se abre otro userform indicando que el usuario se ha equivocado al activar esta checkbox.
Quisiera que al cerrar este nuevo userform, la checkbox activada por error se desactive automáticamente.
¿Hay algún código para eso?
De antemano, gracias, me harían un GRAN favor.
0
vb
 
en el código de cierre o del botón de tu segundo userform,

 'para desmarcar el CheckBox UserForm1.CheckBox1.Value = False 'para desactivar (grisear) el CheckBox UserForm1.CheckBox1.Enabled = False 
0
Philippe
 
Hola a todos,

Muchas gracias, era muy sencillo pero ¡hay que pensarlo!

Otro pequeño "problema" en mi programación:
- cuando hago clic en el CommandButton destinado a borrar el Combobox en el que está implantado, un clic no es suficiente, necesito dos o tres clics para que funcione.

¿Es evitable? Yo creo que sí, pero dudo en completar mi macro (tengo miedo de sobrecargarla)

Gracias de antemano.
0
Usuario anónimo > Philippe
 
Hola,

¿Bajo qué evento has puesto tu código?

Si utilizas "CommandButton1_DblClick" se necesitan 2 clics para que el código se ejecute... (normal)
Normalmente (la mayoría de las veces) se usa un solo clic con el evento "CommandButton1_Click"

Quizás esa sea la origen de tu problema...

Ejemplo:

Private Sub CommandButton1_Click() MsgBox "un clic" End Sub Private Sub CommandButton1_DblClick(ByVal Cancel As MSForms.ReturnBoolean) MsgBox "¡un doble clic!" End Sub


--
¡Hasta luego!
Con amistad, Us.
0
Chriscam > Usuario anónimo
 
Hola Us,

Gracias por tu publicación. He comprobado (por si acaso) pero no pedí el DblClick para validar.

Mi problema se parece más a una especie de error que a una inserción (ni siquiera por inadvertencia) de comando. Originalmente, mi pequeño programa funcionaba a la perfección. Este problema apareció solo desde que añadí los códigos para desactivar las casillas de verificación.

Un detalle que puede ser importante, la llamada a ciertos userform (que contienen la ayuda de mi pequeño programa) se realiza en diferentes combobox. Me explico porque tengo dificultades para entenderme (vamos bien, jaja); doy los nombres por defecto deliberadamente, será más simple:

Userform1 contiene: 1 etiqueta (explicación); 3 Checkbox (que condicionan para 2 de ellas la apertura de un combobox de error (que, cuando se cierra, desmarca y desactiva la Checkbox que lo llamó) y para la última un funcionamiento normal (la casilla se activa cuando se selecciona); 2 CommandButton (uno para OK (que cierra Userform1 y abre Userform2) y el otro para AYUDA (que abre el Userform de ayuda);

Es en el nivel de los dos Combobox de error (ya que son diferentes) donde radica mi problema, debo hacer clic 2 o incluso 3 veces en el CommandButton (llamado OK - no tenía más imaginación) para volver al Userform original.

No sé si todo esto es comprensible, en caso de que siempre puedo detallar los aspectos oscuros de mi explicación.

De todos modos, muchas gracias por tu ayuda, lo aprecio y espero poder aportar la mía a su vez próximamente.

Phil

P.D.: ¿Dónde hay que ir para crear un tema?
0
  • 1
  • 2