ms access - Cómo llenar un ComboBox con un conjunto de registros usando VBA
ms-access adodb (6)
En MS Access, está bien, pero en VB, puede usar algo como esto usando adodc (Jet 4.0):
Private sub Form1_Load()
with Adodc1
.commandtype = adcmdtext
.recordsource = "Select * from courses"
.refresh
while not .recordset.eof
combo1.additem = .recordset.coursecode
.recordset.movenext
wend
end with
End Sub
Hay un poco de literatura disponible en el intercambio de expertos y en teck republic sobre el uso de la propiedad combobox.recordset para completar un cuadro combinado en un formulario de acceso.
Estos controles generalmente se completan con una cadena "SELECT *" en las propiedades de "rowsource" del control, haciendo referencia a una tabla o consulta disponible en el lado del cliente de la aplicación. Cuando necesito mostrar los datos del lado del servidor en un cuadro combinado, creo una tabla local temporal e importo los registros solicitados. Esto lleva mucho tiempo, especialmente con tablas grandes.
Ser capaz de utilizar un conjunto de registros para rellenar un control de cuadro combinado permitiría al usuario mostrar directamente los datos desde el lado del servidor.
Inspirado por los 2 ejemplos anteriores, escribí algunos códigos de la siguiente manera:
Dim rsPersonne as ADODB.recordset
Set rsPersonne = New ADODB.Recordset
Set rsPersonne.ActiveConnection = connexionActive
rsPersonne.CursorType = adOpenDynamic
rsPersonne.LockType = adLockPessimistic
rsPersonne.CursorLocation = adUseClient
rsPersonne.Open "SELECT id_Personne, nomPersonne FROM Tbl_Personne"
fc().Controls("id_Personne").Recordset = rsPersonne
Dónde:
- connexionActive: es mi conexión ADO permanente a mi servidor de base de datos
- fc (): es mi forma actual / activa
- controles ("id_Personne"): es el control de cuadro combinado para rellenar con la lista de personal de la empresa
- Versión de acceso en 2003
Desafortunadamente, ¡no funciona!
En el modo de depuración, puedo verificar que el conjunto de registros se haya creado correctamente, con las columnas y los datos solicitados, y que esté correctamente asociado al control del cuadro combinado. Desafortunadamente, cuando muestro el formulario, sigo obteniendo un combobox vacío, ¡sin registros en él! Cualquier ayuda es muy apreciada.
EDITAR:
Esta propiedad de conjunto de registros está disponible para el objeto de cuadro combinado específico, no para el objeto de control estándar, y me sorprendió descubrirlo hace unos días. Ya he intentado utilizar la función de devolución de llamada de combobox o rellenar una lista con el método "addItem" del cuadro combinado. Todos estos requieren mucho tiempo.
Encontré el truco ... la propiedad "rowSourceType" del control del combobox debe establecerse en "Tabla / Lista". La pantalla ahora está bien, pero ahora tengo otro problema con la memoria. Como utilizo estos conjuntos de registros ADO en mis formularios, el uso de la memoria de Access aumenta cada vez que navego por un formulario. La memoria no se libera al detener la exploración o al cerrar el formulario, lo que hace que MS Access sea inestable y se congele regularmente. Abriré una pregunta si no puedo resolver este problema
Un control de cuadro combinado no tiene una propiedad de conjunto de registros. Tiene una propiedad RowSource pero Access espera una cadena SQL allí.
Puede cambiar RowSourceType por el nombre de una función de "devolución de llamada" definida por el usuario. La ayuda de acceso le proporcionará más información, incluido el código de muestra, colocándose en RowSourceType y presionando F1. Utilizo este tipo de función cuando deseo proporcionar a los usuarios una lista de informes disponibles, letras de unidad u otros datos que no están disponibles a través de una consulta SQL.
No entiendo lo que quiere decir con su tercer párrafo con respecto al uso de datos directamente desde el servidor. O mejor dicho, no entiendo cuál es el problema con el uso de consultas estándar.
Como se dijo, debe obtener RowSourceType en "Table / List" (o "Table / Requête" si está en francés) para mostrar los resultados de la consulta en el cuadro combinado.
Sus problemas de memoria surgen al abrir el conjunto de registros (rsPersonne) sin cerrarlo. Debe cerrarlos al cerrar / descargar el formulario (pero, una vez más, tendría problemas de alcance ya que el conjunto de registros se declara en la función y no en el formulario).
También podría tratar de crear y guardar una consulta con el creador de consultas integrado de Access y tapar esa misma consulta en el RowSource de su cuadro combinado. De esta forma, la consulta se valida y compila dentro de Access.
un buen método para usar la propiedad Recordset, ¡gracias por esa pista!
Patrick, el método que mostraste en tu página tiene una gran desventaja (yo también lo intenté por mi cuenta): la lista de valores solo puede ser de 32 KB; si excedes este límite, la función arrojará un error. El método de devolución de llamada tiene la gran desventaja de que es muy lento y se llama una vez para cada entrada que lo hace inutilizable para una lista más larga. Usar el método recordset funciona muy bien. Lo necesitaba porque mi cadena de SQL tenía más de 32 KB (muchos valores de índice para WHERE ID IN (x, x, x, x, x ...)).
Aquí hay una función simple que usa esta idea para establecer un conjunto de registros en el cuadro combinado:
'' Fills a combobox with the result of a recordset.
''
'' Works with any length of recordset results (up to 10000 in ADP)
'' Useful if strSQL is longer than 32767 characters
''
'' Author: Christian Coppes
'' Date: 16.09.2009
''
Public Sub fnADOComboboxSetRS(cmb As ComboBox, strSQL As String)
Dim rs As ADODB.Recordset
Dim lngCount As Long
On Error GoTo fnADOComboboxSetRS_Error
Set rs = fnADOSelectCommon(strSQL, adLockReadOnly, adOpenForwardOnly)
If Not rs Is Nothing Then
If Not (rs.EOF And rs.BOF) Then
Set cmb.Recordset = rs
'' enforces the combobox to load completely
lngCount = cmb.ListCount
End If
End If
fnADOComboboxSetRS_Exit:
If Not rs Is Nothing Then
If rs.State = adStateOpen Then rs.Close
Set rs = Nothing
End If
Exit Sub
fnADOComboboxSetRS_Error:
Select Case Err
Case Else
fnErr "modODBC->fnADOComboboxSetRS", True
Resume fnADOComboboxSetRS_Exit
End Select
End Sub
(La función fnADOSelectCommon abre un conjunto de registros ADO y lo devuelve. La función fnErr muestra un cuadro de mensaje con el error, si hubo uno).
Como esta función cierra el conjunto de registros abierto, no debería haber ningún problema con la memoria. Lo probé y no vi ningún aumento de la memoria que no se publicó después de cerrar el formulario con los cuadros combinados.
En el evento de descarga del formulario, puede utilizar adicionalmente un "Establecer rs = Me.Comboboxname.Recordset" y luego cerrarlo. Esto no debería ser necesario con respecto a la memoria, pero puede ser mejor liberar las conexiones abiertas (si se usa con un servidor de base de datos de fondo).
Aclamaciones,
cristiano
Para establecer un control que acepte una fuente de filas para un conjunto de registros, haga lo siguiente:
Set recordset = currentDb.OpenRecordset("SELECT * FROM TABLE", dbOpenSnapshot)
Set control.recordset = recordset
Funciona con los conjuntos de registros DAO, no he probado los conjuntos de registros ADO porque no tengo ningún motivo real para usarlos.
Cuando se hace de esta manera, una nueva consulta simple no funcionará para actualizar los datos, debe repetir la instrucción set.