Combobox y ListIndex

Resuelto
wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   -  
pijaku Mensajes publicados 13513 Fecha de registro   Estado Moderador Última intervención   -
Hola,

Tengo dos preguntas:
Estoy en proceso de inicializar un "user form" y tengo diferentes combobox y listbox.

1) En primer lugar, quiero implementar mi lista de combobox

Para realizar una lista sin "duplicados" he recuperado un código que circula por los foros :


ComboBox1 = Variable_A_Ajouté_N°1
If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Variable_A_Ajouté_N°1


En este trozo de código me gustaría entender qué significa la línea
ComboBox1 = Variable_A_Ajouté_N°1

y sobre todo :
If ComboBox1.ListIndex = -1

???

2) Luego, tengo un problema al ejecutar este trozo de código.
He incluido este pequeño trozo de código en un bucle para inicializar mi combobox, y periódicamente, éste llega a activar

Private Sub ComboBox1_Click()


¿Existe alguna forma de desactivar todo "clic" en mi ComboBox1 mientras mi primer script no haya terminado ??

Muchas gracias

Configuración: Windows 2003 / Chrome 43.0.2357.130

6 respuestas

  1. ThauTheme Mensajes publicados 1564 Estado Miembro 160
     
    Hola Wireless, hola al foro,

    el método más rápido para alimentar una ListBox/ComboBox sin duplicados es la utilización de un diccionario. Generalmente este abastecimiento se realiza mediante la inicialización del UserForm que la contiene.

    Mira el ejemplo comentado a continuación:

    Private O As Worksheet 'declara la variable O (Hoja) Private TC As Variant 'declara la variable TC (Matriz de Celdas) Private Sub UserForm_Initialize() 'en la inicialización del UserForm Dim I As Long 'declara la variable I (Incremento) Dim D As Object 'declara la variable D (Diccionario) Set O = Sheets("Feuil1") 'define la hoja O TC = O.Range("A1").CurrentRegion 'define la matriz de celdas TC Set D = CreateObject("Scripting.Dictionary") 'define el diccionario D For I = 2 To UBound(TC, 1) 'bucle sobre todas las filas I de la matriz de celdas TC (empezando desde la segunda) D(TC(I, 1)) = "" 'llena el diccionario D Next I 'próxima fila del bucle Me.ComboBox1.List = D.keys 'llena el ComboBox1 con la lista de elementos del diccionario D sin duplicados End Sub


    El uso de una variable "Matriz de Celdas" es mucho más rápido que recorrer realmente las celdas de una matriz. Esto también incrementa considerablemente la ejecución del código...

    http://www.cjoint.com/c/EGhrkgxVzeR

    --
    Hasta luego,
    ThauTheme
    1
    1. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      Hey hey hey !!!
      ThauTheme :-/ !!!
      ¡Tu código funciona muy bien! Y además, ya no hay problemas de activación de "Private Sub ComboBox1_Click()" intempestivamente :-D y eso también es genial !!

      Gracias :-)
      0
  2. ThauTheme Mensajes publicados 1564 Estado Miembro 160
     
    Hola,

    Me alegra por ti. Deberías marcar el hilo como "resuelto"...

    --
    Hasta luego,
    ThauTheme
    1
  3. ThauTheme Mensajes publicados 1564 Estado Miembro 160
     
    Hola,

    No hace falta filtrar. Mira el ejemplo abajo:

    http://www.cjoint.com/c/EGitkzkIIRR

    --
    Hasta luego,
    ThauTheme
    1
    1. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      Maravilloso!!!
      ¡Gracias ThauTheme!!
      ¡Funciona como un dios del fuego!!
      0
    2. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      Solo una última pregunta :-/
      ¿Cuál es la diferencia entre "_Click()" y "_Change()" ???
      Private Sub ComboBox1_Click() End Sub

      y
      Private Sub ComboBox1_Change() End Sub
      0
    3. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      Tengo una última pregunta real ThauTheme.

      Private TC As Variant 'declara la variable TC (Tabla de Celdas) For I = 2 To UBound(TC, 1) 'bucle sobre todas las filas I de la tabla de celdas TC (empezando por la segunda) If TC(I, 1) = Me.ComboBox1.Value And TC(I, 2) = Me.ComboBox2.Value Then D(TC(I, 3)) = "" 'llena el diccionario D Next I 'próxima fila del bucle 


      Tengo un gran problema con mis pruebas :
      Primera prueba :
      If TC(I, 1) = Me.ComboBox1.Value ... ' Ok todo funciona bien. Tengo bien 'Toto' = 'Toto' ...
      Segunda prueba :
      If TC(I, 2) = Me.ComboBox2.Value ... 'Esta vez tengo 1 =/= "1" ... y ahí estoy realmente molesto!
      He intentado definir mi variable TC As String para imponer un "1" = "1" pero entonces VBA ya no reconoce TC como una matriz !!

      ¿Tendrías alguna idea ???

      Merci.
      0
  4. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
     
    :-) Sé que... Sé que... Pero esperaba aún un poco para ver si me quedaba algún problema oculto por ahí... :-p

    Gracias de nuevo.
    Hasta luego

     For i = 1 to 1000 Call Msgbox(" MERCI ") Next i 
    0
    1. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      ¡Hola! Aquí tienes la traducción al español del texto que proporcionaste: Hey hey !! :-/

      Tengo otra pregunta...
      Voy a hacerla corta y clara...

      Me gustaría usar mis combobox con la función Autofilter de Excel...
      Así que

      Tengo una Combobox1 asociada al diccionario de la columna 1
      una Combobox2 asociada al diccionario de la columna 2
      una Combobox3 asociada al diccionario de la columna 3

      Así, después de hacer clic en mi Combobox1, hago un
      Sheets("Mi_hoja").Range("A1").CurrentRegion.AutoFilter Field:=1, Criteria1:=ComboBox1.Value


      Reinicio mis combobox1, 2 y 3, y me gustaría que mis combobox2 y 3 tengan en cuenta solo los elementos que han sido filtrados...

      ¿cómo hacerlo :-/ ??

      Gracias :-|
      0
  5. ThauTheme Mensajes publicados 1564 Estado Miembro 160
     
    Hola,

    Sí, tienes razón, es mi culpa; hay que convertir los valores a String :

    If CStr(TC(I, 1)) = Me.Combobox1.Value If Cstr(TC(I, 2)) = Me.ComboBox2.Value

    Pero deja la variable TC de tipo Variant !

    Para tu pregunta de arriba, mira la ayuda de VBA...

    --
    Hasta luego,
    ThauTheme
    0
    1. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      Thank you!
      it works really well. Have a good day and a good weekend.
      0
  6. pijaku Mensajes publicados 13513 Fecha de registro   Estado Moderador Última intervención   2 773
     
    Hola a ambos,

    Voy a intentar responder a las preguntas de wire less.

    1- ¿qué hace este código?
    ComboBox1 = Variable_A_Ajouté_N°1 If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Variable_A_Ajouté_N°1


    Una ComboBox es un “mezcla” entre el textbox y la listbox. Se trata de una lista en la que se puede escribir lo que se quiera.
    Por lo tanto, la línea :
    ComboBox1 = Variable_A_Ajouté_N°1
    (implícito:
    ComboBox1.Value = Variable_A_Ajouté_N°1
    ) no hace sino introducir, en la combobox, el contenido de la variable Variable_A_Ajouté_N°1.
    ¿Qué sucede al introducir “manualmente”, un valor en una ComboBox?
    Simplemente, si el valor introducido ya forma parte de la ComboBox.List, entonces se selecciona. Esto tiene como consecuencia cambiar la propiedad ListIndex al índice de ese valor.
    Si no forma parte, no pasa nada, lo has escrito, eso es todo.
    ¿Eso es todo? Pues en realidad no. Si el valor introducido no forma parte de la ComboBox.List, la propiedad ListIndex permanece en -1 (el primer índice de las ComboBox no vacías es 0).
    Así que, el código anterior:
    • escribe tu variable en la combobox
    • prueba el ListIndex de tu combobox.

    Si el ListIndex sigue en -1, eso significa que el valor introducido aún no forma parte de ComboBox.List, así que... puedes añadirlo con .AddItem...

    2- ¿Existe una forma de desactivar los eventos de un USerForm?
    Sí, mediante una variable pública de tipo boolean.
    Una pequeña prueba que reconocerás ;-)
    En modo paso a paso, verás la entrada y la salida de la Private Sub _Change()
    Public Evenements_Actifs As Boolean Private Sub ComboBox1_Change() If Me.Evenements_Actifs = False Then Exit Sub MsgBox "Change" End Sub Private Sub ComboBox1_Click() MsgBox "Clic" End Sub Private Sub UserForm_Initialize() Dim TABLEAU As Variant, I As Long TABLEAU = Sheets("Feuil1").Range("A2:A6") Call Tri(TABLEAU, LBound(TABLEAU), UBound(TABLEAU)) Me.Evenements_Actifs = False For I = 1 To UBound(TABLEAU, 1) ComboBox1.Value = TABLEAU(I, 1) 'evita duplicados If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem TABLEAU(I, 1) Next I Me.Evenements_Actifs = True End Sub Sub Tri(a, gauc, droi) ' Quick sort Dim ref, g, d, tmp 'Como se llena el array inicial por el objeto Range 'hay que añadir la dimensión ( , 1) para evitar error 9 ref = a((gauc + droi) \ 2, 1) g = gauc: d = droi Do Do While a(g, 1) < ref: g = g + 1: Loop Do While ref < a(d, 1): d = d - 1: Loop If g <= d Then tmp = a(g, 1): a(g, 1) = a(d, 1): a(d, 1) = tmp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call Tri(a, g, droi) If gauc < d Then Call Tri(a, gauc, d) End Sub


    3- ¿Cuál es la diferencia entre "_Click()" y "_Change()"?
    Click es el evento que se produce cuando haces clic en la ComboBox.
    Change es el evento que se produce cuando introduces en tu ComboBox.

    Al hacer clic, ocurre el evento Change, si el valor de la combobox cambia...
    Al hacer un cambio mediante una introducción manual en una combobox, Click no se dispara.

    > Este es el verdadero problema, la verdadera pregunta: ¿debo permitir la introducción de valores en mi ComboBox?
    Muy a menudo la respuesta es no, pero el desarrollador no ha pensado en este hecho: el usuario puede ser un imbécil.
    Si el usuario introduce cualquier cosa en la ComboBox, eso puede hacer que la herramienta falle.

    Para evitarlo, basta con impedir la introducción de valores no incluidos en ComboBox.List.
    ¿Cómo hacerlo?
    Simplemente piensa en ajustar la propiedad .Style de la ComboBox a: 2 (fmStyleDropDownList)

    Un ejemplo basado en el código anterior:
    Public Evenements_Actifs As Boolean Private Sub ComboBox1_Change() If Me.Evenements_Actifs = False Then Exit Sub MsgBox "Change" End Sub Private Sub ComboBox1_Click() MsgBox "Clic" End Sub Private Sub UserForm_Initialize() Dim TABLEAU As Variant, I As Long TABLEAU = Sheets("Feuil1").Range("A2:A6") Call Tri(TABLEAU, LBound(TABLEAU), UBound(TABLEAU)) Me.ComboBox1.Style = fmStyleDropDownCombo ' ====> Sinón problema : escritura imposible Me.Evenements_Actifs = False For I = 1 To UBound(TABLEAU, 1) ComboBox1.Value = TABLEAU(I, 1) ' ====> OJO aquí hay una escritura !!! 'evita duplicados If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem TABLEAU(I, 1) Next I Me.Evenements_Actifs = True Me.ComboBox1.Style = fmStyleDropDownList ' ====> Escritura de cualquier cosa imposible End Sub Sub Tri(a, gauc, droi) ' Quick sort Dim ref, g, d, tmp 'Como se llena el array inicial por el objeto Range 'hay que añadir la dimensión ( , 1) para evitar error 9 ref = a((gauc + droi) \ 2, 1) g = gauc: d = droi Do Do While a(g, 1) < ref: g = g + 1: Loop Do While ref < a(d, 1): d = d - 1: Loop If g <= d Then tmp = a(g, 1): a(g, 1) = a(d, 1): a(d, 1) = tmp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call Tri(a, g, droi) If gauc < d Then Call Tri(a, gauc, d) End Sub


    ps : je vais le répéter ici, mais c'est important, il n'est nul besoin de variables aussi gourmandes que l'objet dictionary pour remplir une ComboBox.

    À++
    🎼 Cordialement,
    Franck 🎶
    0
    1. wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención   5
       
      ¿Y es posible usar el mismo tipo de script para las listbox?
      ListBox1 = Variable_A_Ajouté_N°1 If ListBox1.ListIndex = -1 Then ListBox1.AddItem Variable_A_Ajouté_N°1

      :-/ ¿Tengo la impresión de que no ??
      0
      1. pijaku Mensajes publicados 13513 Fecha de registro   Estado Moderador Última intervención   2 773 > wire less Mensajes publicados 247 Fecha de registro   Estado Miembro Última intervención  
         
        No.
        ListBox1.Value = Variable_A_Añadido_N°1
        va a fallar.
        0