Access

Cómo seleccionar un valor de cuadro combinado de Microsoft Access usando VBA

Puede ser muy útil poder establecer/seleccionar mediante programación el valor de un cuadro combinado, pero ¿cómo se puede hacer exactamente?

Hoy, me gustaría explicar esto en 2 escenarios distintos: (I) un cuadro combinado básico de una sola columna y (II) una configuración de cuadro combinado de varias columnas normalizada más estándar.

Caso sencillo

En este escenario, tendremos un cuadro combinado vinculado a un campo de texto en una tabla donde lo configuraremos para una persona específica. Este es un escenario muy común que tienen muchos desarrolladores novatos, pero en el que los datos no están normalizados adecuadamente. De todos modos, sigo pensando que vale la pena hacer una demostración.

Configuración de la mesa

Supongamos que estamos construyendo un cuadro combinado alrededor de tablas de contactos:

CREATE TABLE Contacts_Simplified (
    ContactName VARCHAR(50),
);

Luego podemos llenar la tabla con algunos datos haciendo:

INSERT INTO Contacts_Simplified (ContactName) VALUES ('John Smith');
INSERT INTO Contacts_Simplified (ContactName) VALUES ('Emma Johnson');
INSERT INTO Contacts_Simplified (ContactName) VALUES ('Michael Williams');
INSERT INTO Contacts_Simplified (ContactName) VALUES ('Sophia Brown');
INSERT INTO Contacts_Simplified (ContactName) VALUES ('William Jones');
INSERT INTO Contacts_Simplified (ContactName) VALUES ('Olivia Davis');

Configuración de formulario y VBA

Ahora, simplemente creamos un formulario, insertamos un cuadro combinado que en este contexto he llamado ‘cbo_Search_Name’ y lo configuramos para usar la tabla como su origen de fila. Entonces configuraría sus propiedades como:

Row Source: SELECT Contacts_Simplified.ContactName FROM Contacts_Simplified ORDER BY Contacts_Simplified.ContactName;
Column Width: 

Ahora, digamos que queremos establecer el valor del cuadro combinado en «Sophia», todo lo que tendríamos que hacer es:

Me.cbo_Search_Name = "Sophia Brown"

Eso es todo. Simplemente asigne el valor al control del cuadro combinado.

Caso avanzado

Ahora veamos lo mismo, pero cuando los datos están correctamente normalizados. Así que vamos a crear una tabla de Contactos adecuada con una clave principal adecuada y dividiremos los datos en atributos como Nombre y Apellido. Luego, nos vincularemos correctamente a la clave principal en lugar del nombre real del individuo para establecer el valor del cuadro combinado.

Configuración de la mesa

Supongamos que estamos construyendo un cuadro combinado alrededor de tablas de contactos:

CREATE TABLE Contacts_Advanced (
    ContactID AUTOINCREMENT PRIMARY KEY,
    FirstName TEXT(50),
    LastName TEXT(50)
);

Luego podemos llenar la tabla con algunos datos haciendo:

INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('John Smith');
INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('Emma Johnson');
INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('Michael Williams');
INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('Sophia Brown');
INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('William Jones');
INSERT INTO Contacts_Advanced (FirstName, LastName) VALUES ('Olivia Davis');

Configuración de formulario y VBA

Ahora, simplemente creamos un formulario, insertamos un cuadro combinado que en este contexto he llamado ‘cbo_Search_Name’ y lo configuramos para usar la tabla como su origen de fila. Entonces configuraría sus propiedades como:

Row Source: SELECT Contacts_Advanced.ContactId, Contacts_Advanced.FirstName, Contacts_Advanced.LastName FROM Contacts_Advanced ORDER BY Contacts_Advanced.FirstName, Contacts_Advanced.LastName; 
Column Count: 3
Column Width: 0";0.5";0.5"

Ahora, digamos que queremos establecer el valor del cuadro combinado en «John», tendríamos que hacer:

    Dim iCounter              As Long
    Const sSearchValue1       As String = "John"
    
    With Me.cbo_Search_Name
        For iCounter = 0 To .ListCount - 1
            If .Column(1, iCounter) = sSearchValue1 Then
                .Value = .ItemData(iCounter)
                Exit For
            End If
        Next iCounter
    End With

donde recorremos las entradas del cuadro combinado mirando el valor de la segunda columna ( .Column(1, iCounter) – no olvides que es un índice de columna basado en 0, por lo que 1 significa la segunda columna!) y cuando encontramos el valor que estamos buscando, configuramos el cuadro combinado al valor enlazado de esa fila usando ItemData(iCounter).

pero lo anterior no es infalible ya que solo verifica la columna Nombre. ¿Qué pasa si tenemos varios contactos con el nombre ‘John’??? Por lo tanto, para nuestro ejemplo, necesitaríamos no solo validar el nombre, sino también el apellido de cada fila del cuadro combinado. Así, terminaríamos con algo como:

    Dim iCounter              As Long
    Const sSearchValue1       As String = "John"
    Const sSearchValue2       As String = "Smith"
    
    With Me.cbo_Search_Name
        For iCounter = 0 To .ListCount - 1
            If .Column(1, iCounter) = sSearchValue1 _
               And .Column(2, iCounter) = sSearchValue2 Then
                '.Value = .ItemData(iCounter)
                .Value = .Column(0, iCounter)
                Exit For
            End If
        Next iCounter
    End With

Como puede ver, simplemente agregamos un AND con la siguiente cláusula y podríamos agregar más según sea necesario.

También notarás que en este ejemplo de código, ilustro que también podríamos usar

    .Value = .Column(0, iCounter)

para establecer el valor del cuadro combinado, pero en realidad .ItemData(iCounter) normalmente es preferible ya que ItemData siempre proporcionará el valor de la columna vinculada, mientras que .Column está vinculado estáticamente a cualquier columna que defina. En la mayoría de los casos, no importará, pero a veces puede causar dolores de cabeza si no prestas atención.

Entonces ahí lo tienes; cómo establecer el valor de un cuadro combinado en un escenario simple y/o avanzado.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba