ms-access - seleccion - cuadro de lista desplegable
Fuente de fila personalizada para el cuadro combinado en forma continua en Access (13)
He buscado alrededor, y parece que esto es una limitación en MS Access, así que me pregunto qué soluciones creativas han encontrado otros en este rompecabezas.
Si tiene un formulario continuo y desea que un campo sea un cuadro combinado de opciones que son específicas de esa fila, Access no puede entregar; el origen de fila de cuadro combinado solo se consulta una vez al principio del formulario y, por lo tanto, muestra las opciones incorrectas para el resto del formulario.
El siguiente paso que todos intentamos, por supuesto, es utilizar el evento onCurrent para volver a consultar el cuadro combinado, que de hecho limita las opciones a la fila dada. Sin embargo, en este punto, Access se vuelve loco y vuelve a consultar todos los cuadros combinados para cada fila, y el resultado suele ser desaparecer y volver a aparecer en otras filas, según hayan elegido una opción válida para el fuente de la fila del registro actual.
La única solución que he encontrado es solo enumerar todas las opciones disponibles, todo el tiempo. ¿Alguna respuesta creativa por ahí?
Editar También, debería tener en cuenta que el motivo para el cuadro combinado es tener una consulta como tabla de búsqueda, el valor real debe ocultarse y almacenarse, mientras se muestra la versión legible para el ser humano ... múltiples columnas en la fila del cuadro combinado fuente. Por lo tanto, cambiar el límite de la lista no ayuda, porque los identificadores que no están en la consulta de origen de la fila actual no tendrán una parte legible por humanos que coincida.
En este caso particular, las formas continuas tienen mucho sentido, así que no me digas que es la solución incorrecta. Estoy pidiendo respuestas creativas.
¿Qué pasa si desactivas la opción "Limitar a la lista" y realizas alguna validación antes de la actualización para confirmar que lo que el usuario haya escrito coincide con algo de la lista que los has presentado?
Descargo de responsabilidad: Odio el acceso con pasión.
No use formularios continuos. Son una arenga roja para lo que quieres lograr. Las formas continuas son la misma forma repetida una y otra vez con diferentes datos. Ya es un obstáculo para el modo de operación normal de Access ya que no puede tener el mismo formulario abierto varias veces. El comportamiento que está viendo está "como está diseñado" en Access. Cada uno de esos controles ComboBox es en realidad el mismo control. No puedes afectar a uno sin afectar a los demás.
Básicamente, lo que ha hecho aquí se ejecuta en el área donde Access ya no es adecuado para su proyecto (pero no puede deshacerse porque ya representa una gran cantidad de trabajo).
Lo que parece ser el curso de acción más probable aquí es fingir realmente bien. Ejecute una consulta en función de los datos y luego cree los elementos del formulario mediante programación en función de los resultados. Esta es una buena cantidad de trabajo, ya que usted mismo va a duplicar una buena parte de la funcionalidad de manejo de datos de Access.
Responder a Editar:
Pero tal como son, las formas continuas no pueden lograr lo que quieres. Es por eso que sugerí falsificar sus propias formas continuas, porque las formas continuas tienen limitaciones reales en lo que pueden hacer. No se quede tan atrapado en una implementación en particular que no pueda abandonarla cuando deje de funcionar.
No creo que los formularios de acceso continuo deban ser condenados en absoluto, pero definitivamente creo que deben evitarse para EDITAR DATOS. Funcionan muy bien para listas, y le brindan capacidades de formateo sustancialmente mayores que un simple listbox (y son mucho más fáciles de usar, también, aunque no permiten la selección múltiple, por supuesto).
Si desea utilizar un formulario continuo para la navegación a los registros para su edición, utilice un subformulario que muestre los datos detallados para su edición, y use el valor PK del subformulario para el campo de enlace. Esto se puede hacer con un formulario continuo donde coloca un subformulario de detalle en el encabezado o pie de página, vinculado en el PK de la tabla detrás de la forma continua.
O bien, si está utilizando un formulario continuo para mostrar datos secundarios en un formulario principal, puede vincular el subformulario de detalle con una referencia al PK en el subformulario continuo, algo así como:
[MySubForm].[Form]!MyID
Esa sería la propiedad principal del enlace, y MyID sería la propiedad secundaria del enlace.
También puede convertir el valor del cuadro combinado en un campo de texto no editable y luego abrir una ventana emergente / modal para editar ese valor. Sin embargo, si estuviera haciendo eso, podría inclinarme a editar todo el registro en una de esas ventanas.
También encontramos esto mucho en nuestras aplicaciones. Lo que hemos encontrado es una buena solución: simplemente muestre todas las filas en los cuadros combinados. Luego, tan pronto como el usuario ingrese el compobox en una fila específica, ajuste el rowsource (con el filtro para esa fila). Cuando el cuadro combinado pierde el foco, puede volver a establecer la fuente para mostrar todo.
También odio el acceso, pero debes jugar con las cartas que te reparten. Las formas continuas son algo maravilloso en Access, hasta que se encuentra con cualquier tipo de complejidad, como suele ser el caso, como en este caso.
Esto es lo que haría cuando enfrente esta situación (y he implementado soluciones similares antes):
Coloque un combobox UNBOUND en el formulario. A continuación, coloque un BOUND textBox para el campo que desea editar.
Asegúrese de que el cuadro combinado esté oculto detrás (NO invisible, simplemente oculto) detrás del cuadro de texto.
En el evento OnCurrent llene listBox con los datos necesarios. Adelante y "Limitar a la lista" también.
En el evento OnEnter u OnClick del cuadro de texto, da el foco del cuadro combinado. Esto traerá el combobox a la vanguardia. Cuando el foco abandona el cuadro combinado, se ocultará una vez más.
En el evento AfterUpdate del cuadro combinado, establezca el valor del cuadro de texto igual al valor del cuadro combinado.
Dependiendo de su situación, puede que haya otros detalles para resolver, pero eso debería lograr más o menos su objetivo sin agregar demasiada complejidad.
Tengo una forma más sencilla de ir que Gilligan. Parece mucho trabajo, pero realmente no lo es. Mi solución requiere tener mi forma continua como una hoja de datos de subformulario. En mi subformulario, tengo dos cuadros combinados de búsqueda, entre otros campos, llamados Equipo y Fabricante. Ambos simplemente tienen una clave de Entero largo en la fuente de datos. El fabricante debe ser filtrado por lo que se selecciona en el Equipo. La única vez que filtro Manufacturer.RowSource es en el evento Manufacturer_GotFocus.
Sub privado Manufacturer_GotFocus ()
If Nz(Me.Equipment, 0) > 0 Then
Me.Manufacturer.RowSource = GetMfrSQL() ''- gets filtered query based on Equipment
Else
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End If
End Sub
En Manufacturer_LostFocus reinicio Manufacturer.RowSource a todos los fabricantes también. Debe hacer esto porque cuando hace clic por primera vez en el subformulario, los eventos de GotFocus se activan para todos los controles, incluido el fabricante, incluso si no está actualizando ningún campo.
Sub privado Manufacturer_LostFocus ()
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End Sub
En el evento Enter del fabricante, debe verificar si se seleccionó el equipo, si no se ajustó el foco al equipo.
Private Sub Manufacturer_Enter ()
If Nz(Me.EquipmentID, 0) = 0 Then
''-- Must select Equipment first, before selecting Manufacturer
Me.Equipment.SetFocus
End If
End Sub
También necesita volver a consultar el cuadro combinado del fabricante en el evento Form_Current (es decir, Me.Manufacturer.Requery) y debe establecer la propiedad Cycle de este subformulario en "Current Record".
Parece bastante simple, pero aún no has terminado. También debe restablecer Manufacturer.RowSource a todos los fabricantes en el evento SubForm_Exit en el formulario principal en caso de que el usuario vaya al cuadro combinado del fabricante, pero no haga una selección y haga clic en algún lugar del formulario principal. Muestra de código (en forma parental):
Private Sub sFrmEquip_Exit (Cancelar como entero)
Me.sFrmEquip.Controls("Manufacturer").RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End Sub
Todavía hay una pieza de esto que no está limpia. Cuando hace clic en Fabricante y tiene varias filas en la cuadrícula de la hoja de datos, el campo Fabricante se pondrá en blanco en otras filas (los datos debajo de los cuadros combinados todavía están intactos) mientras está cambiando el Fabricante en la fila actual. Una vez que salga de este campo, el texto en los otros campos del fabricante volverá a aparecer.
Mejor...
Establezca el Origen de control de cuadro combinado en una columna en la consulta donde se almacenarán los valores de su cuadro combinado.
Para mí, creo que la mejor manera y la más fácil es crear una tabla temporal que tenga todos tus campos vinculados más un campo adicional que es un campo yeas / no.
luego usará esta tabla como la fuente de datos para el continuo para. Puede usar onLoad para completar la tabla temporal con los datos que desea.
Después de eso, creo que es fácil buscar las opciones, solo un pequeño bucle para leer el campo yeas / no de la tabla temporal.
Espero que esto sea de ayuda
Use el evento OnEnter
para rellenar el cuadro combinado, no use un rowsource
fijo.
Esto parece funcionar bien. CBOsfrmTouchpoint8 es un cuadro combinado acortado a solo el cuadro desplegable. CBOsfrmTouchpoint14 es un cuadro de texto que compone el resto del espacio. Nunca digas nunca:
Private Sub CBOsfrmTouchpoint8_Enter()
If Me.CBOsfrmTouchpoint8.Tag = "Yes" Then
CBOsfrmTouchpoint14.SetFocus
Me.CBOsfrmTouchpoint8.Tag = "No"
Exit Sub
End If
Me.CBOsfrmTouchpoint8.Tag = "No"
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
Me.CBOsfrmTouchpoint8.SetFocus
End Sub
Private Sub CBOsfrmTouchpoint8_GotFocus()
Me.CBOsfrmTouchpoint14.Width = 0
Me.CBOsfrmTouchpoint8.Width = 3420
Me.CBOsfrmTouchpoint8.Left = 8580
Me.CBOsfrmTouchpoint8.Dropdown
End Sub
Private Sub CBOsfrmTouchpoint8_LostFocus()
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
End Sub
Private Sub CBOsfrmTouchpoint8_Exit(Cancel As Integer)
Me.CBOsfrmTouchpoint14.Width = 3180
Me.CBOsfrmTouchpoint8.Width = 240
Me.CBOsfrmTouchpoint8.Left = 11760
Me.CBOsfrmTouchpoint8.Tag = "Yes"
End Sub
usa formas continuas ... definitivamente. De hecho, puede construir aplicaciones completas con una interfaz de usuario excelente e intuitiva construida en formularios continuos. ¡No escuches Toast!
Su solución de listar todas las opciones disponibles es la correcta. De hecho, no hay otra solución limpia. Pero te equivocas cuando dices que Acccess se vuelve loco. De forma continua, puede ver cada línea como una instancia de la sección de detalles, donde el cuadro combinado es una propiedad común a todas las instancias de la sección de detalles. Puede actualizar esta propiedad para todas las instancias, pero no puede configurarla para una instancia específica. ¡Es por esto que Access DEBE mostrar los mismos datos en el cuadro combinado para todos los registros!
Si necesita aceptar solo valores específicos de registro en este cuadro combinado, use el evento beforeUpdate para agregar un procedimiento de control. En caso de que no se pueda aceptar un nuevo valor, puede cancelar la actualización de datos, devolviendo el valor anterior en el campo.
No puede establecer la propiedad limitToList en ''No'' donde los datos vinculados (el que está almacenado en el control) están ocultos. Esto es lógico: ¿cómo puede la máquina aceptar la entrada de una nueva línea de datos cuando el campo vinculado (no visible) permanece vacío?
Acabo de hacer algo similar. Mi solución fue usar una fuente de fila fija vinculada a una consulta. Las cláusulas WHERE
la consulta hacen referencia al control del formulario, es decir, Client=Forms!frmMain!ClientTextBox
. Solo esto completará los cuadros combinados con los datos de la primera fila. El truco es establecer un evento '' On Enter
'' que simplemente hace una nueva consulta en el cuadro combinado, por ejemplo, ComboBox1.Requery
, esto volverá a consultar ese cuadro combinado solo y solo arrastrará los datos relacionados con esa fila de registro.
Espero que eso también te sirva!