Intercambio de datos entre tablas

A ver si me pueden echar una mano con algo que parece sencillo pero con mi escasa experiencia se me ha complicado y no se bien cómo resolverlo.

Un amigo me pidió si no podía hacerle una base de datos sencilla para llevar el control de vehículos que ingresan y egresan de un depósito. Como de costumbre, debí suponer que cuando alguien dice “algo sencillo” es porque en algún momento te la va a complicar a más no poder.

La base consta de 2 tablas relacionadas. Una principal donde se guardan datos del vehículo, y otra asociada donde se almacenan los datos del propietario o conductor.

En la tabla principal existe un campo llamado [NroAsignado], es numérico, y corresponde al número que se le asigna al espacio físico que ocupa ese vehículo mientras está en el depósito. En el campo [Estado] se registra si ese vehículo está en depósito o si ya fue retirado. Por tanto a la salida de éste campo puse un código para que si se cambia el estado a ENTREGADO, el campo siguiente que es [NroAsignado] sea borrado y quede con valor nulo:

        If (Me.Estado Like "ENTREGADO") Then

            Me.NroAsignado.Value = ""

        End If

Hasta ahí todo bien, pero ahora vengo a descubrir que lo que se necesita es que en lugar de “borrar” el contenido del campo [NroAsignado] el mismo sea quitado y transferido –por ejemplo– a otra tabla de Números_Disponibles, de modo tal que cuando ingrese otro vehículo y sea depositado en ese espacio físico desocupado, al entrar en el campo [NroAsignado] se pueda abrir esa tabla, ver los números disponibles, y haciendo click quitar uno de esos números y registrarlo en el campo [NroAsignado]

Y allí terminó mi ciencia…, porque puedo crear la tabla DISPONIBLES, pero no se qué sentencias emplear para almacenar en ella los números que se quitan del campo [NroAsignado] de la tabla Principal de Vehículos, y tampoco cómo puedo hacer para abrirla y al cliquear sobre determinado número, que el mismo sea quitado de esa tabla y vuelto a registrar en el campo [NroAsignado] de la tabla principal.

Si alguien se le ocurre alguna idea se lo agradeceré enormemente.

Respuesta
2

Si creas una tabla con los números de plazas y un campo de tipo sí/no (Disponible) es relativamente sencillo hacer lo que buscas:

1º/ Esa tabla "Plazas" al relacionas con la tabla principal, por el campo NroAsignado.

2º/ Ese campo lo conviertes en un cuadro de búsqueda, de forma que te muestre siempre los números que tengan marcada la casilla (Disponible=True)

3º/ Por código, al seleccionar un valor de ese cuadro combinado, por medio de una SQL desmarcas la casilla, por ejemplo:

CurrentDb.Execute "UPDATE Plazas SET Disponible=False WHERE Plaza=" & Me.NroAsignado

4º/ Al entregar el coche, m con el mismo procedimiento, marcas la plaza como disponible:

        If (Me.Estado Like "ENTREGADO") Then

            Me.NroAsignado.Value = ""

           CurrentDb.Execute "UPDATE Plazas SET Disponible=TrueWHERE Plaza=" & Me.NroAsignado

        End If

Así quedó la tabla PLAZAS. Puse el campo Ubicación como clave principal. Según entendí, éste campo debo relacionarlo con el campo [NroAsignado] de la tabla principal, ahora bien ¿algún tipo de relación en especial o uno a uno? Otra pregunta: [NroAsignado] lo tengo indexado aceptando duplicados ¿debo indexarlo sin duplicados? 

Respondiendo a tus preguntas:

1º/ Has entendido bien tanto el concepto de tabla como la relación entre las tablas. Esta relación no tiene que ser especial.

2º/ Yo no cambiaría el tipo de índice a NroAsignado, porque si lo pones sin duplicados y tienes coches disponibles (NroAsigando estará "en blanco") probablemente te dará error.

Amplio con un comentario de la respuesta que le das a Jacinto: lo del cuadro combinado es correcto, pero como te decía, si en el origen de datos de ese cuadro combinado le pones como criterio que la casilla esté marcada (plaza disponible), en el cuadro combinado solo verás las plazas disponibles en cada momento, con lo que te evitas tener que comprobar si una plaza está o no libre, y además evitarás errores de asignar la misma plaza a varios vehículos.

Gente, la verdad que muy agradecido por los aportes, todos muy precisos.

Vengo haciendo pruebas despacito para no errarle. Luego de transformar a [NroAsignado] en un cuadro combinado y mandarlo a leer el contenido de la tabla PLAZAS, de acuerdo a lo sugerido por Sveinbjorn, le puse en "después de actualizar" el siguiente evento:  

CurrentDb.Execute "UPDATE Plazas SET Disponible=False WHERE Ubicacion=" & Me.NroAsignado

Probé y en la tabla PLAZAS queda destildado perfectamente el campo Disponible.

Ahora debo ir al siguiente paso, y es que cuando clickeo en el campo combinado [NroAsignado] me muestre sólo los datos en que el campo DISPONIBLE esté tildado como True, ya que como vengo hasta ahora, me sigue mostrando todo el contenido. ¿Dónde y cómo debería ubicar esa orden?

Si sacas las propiedades de cuadro combinado (en el formulario) o en la vista diseño de la tabla vas a la pestaña "busqueda" del campo, verás que tienes una propiedad que se llama origen de la fila, y tiene un valor similar a este:

SELECT Ubicacion FROM Plazas;

Si le añades como criterio que te muestre solo las disponibles, ya está:

SELECT Ubicacion FROM Plazas WHERE Disponible=-1;

Para acabar, te falta el código para cuando entregas el coche, que lo tienes en la primera respuesta.

Listo! En el origen del control del campo [NroAsignado] donde le mando a leer la tabla PLAZAS, llamé a una consulta que me filtre y muestre únicamente los registros que en el campo DISPONIBLE tengan la opción True, quedó así y funciona bien:

SELECT Plazas.Ubicacion, Plazas.Disponible FROM Plazas WHERE (((Plazas.Disponible)=True))

Ahora voy a probar con las entregas a ver si funciona todo correctamente. 

Eres un maestro de la simpleza Sveinbjorn! 

El código del punto 4° de tu primer respuesta tuve que "darlo vuelta", es decir, quedó así:

Private Sub NroAsignado_Enter()
     If (Me.Estado Like "ENTREGADO") Then
     CurrentDb.Execute "UPDATE Plazas SET Disponible=True WHERE Ubicacion=" & Me.NroAsignado
     Me.NroAsignado.Value = 0
    End If

End Sub

O sea, si primero asignaba valor 0 al campo [NroAsignado] no me funcionaba. Seguí la lógica y dije: antes de quitarle su valor original y asignarle 0 debo abrir la tabla plazas para que haga la comparación entre los valores de los campos [Ubicacion] y [NroAsignado]

La cuestión es que todo funciona perfecto, sólo un pequeño detalle me queda por pulir: Si voy de un registro a otro sin cerrar el formulario, el contenido de la tabla PLAZAS no se actualiza. Sólo se actualiza cuando cierro el formulario y lo vuelvo a abrir.

Las órdenes las ubiqué de éste modo: campo [NroAsignado] después de actualizar: 

Private Sub NroAsignado_AfterUpdate()

CurrentDb.Execute "UPDATE Plazas SET Disponible=False WHERE Ubicacion=" & Me.NroAsignado

End Sub

Campo [NroAsignado] Al entrar:

Private Sub NroAsignado_Enter()
If (Me.Estado Like "ENTREGADO") Then
CurrentDb.Execute "UPDATE Plazas SET Disponible=True WHERE Ubicacion=" & Me.NroAsignado
Me.NroAsignado.Value = 0
End If

End Sub

¿Debería agregar alguna sentencia para que guarde los cambios y actualice sin necesidad de cerrar el formulario?  

Imagino que te refieres al contenido del cuadro combinado, que no se te actualiza con los valores nuevos de la tabla (la tabla se actualiza al ejecutar la SQL).

Pues la solución es bien sencilla, añade un Me. NroAsignado. Requery después de ejecutar las SQL (lineas del CurrentDb.Execute...)

Nota: NroAsignado supongo que es el cuadro combinado

¡Gracias! 

Si, efectivamente [NroAsignado] es el cuadro combinado. Luego del CurrentDb.Execute puse la línea con Me.NroAsignado.Requery y actualiza a la perfección la lista sin necesidad de cerrar y volver a abrir el formulario.

Mi última pregunta es una soncera: el campo DISPONIBLE de la tabla PLAZAS es numérico y lo tengo asignado con 0 decimales. El cuadro combinado del campo [NroAsignado] de la tabla principal también lo tengo asignado con 0 decimales. Pero cuando abro la lista del cuadro combinado los números se muestran indefectiblemente con 2 decimales. Y si clickeo en un número para grabarlo en [NroAsignado] se graba sin decimales. No es en la única base de datos que me sucede esto, tengo otra en la que también un cuadro combinado me muestra los números con decimales pese a que tengo configurado el cuadro para que muestre números enteros.

¿Por qué puede ser? En ambos casos el campo es numérico y Entero Largo.

Más allá de éste detallito, realmente quedó sencillo y perfecto el funcionamiento. Nuevamente gracias Sveinbjorn y Jacinto por los aportes! son dos verdaderos capos!

1 respuesta más de otro experto

Respuesta
1

Víctor: En mi opinión y antes de seguir con la BD, seria deseable que tengas un Inventario de Ubicaciones, que en tu caso son los NroAsignado, pero que sería una Tabla que se llamara por Ejemplo TblUbicaciones.

Esa Tabla tendría en principio dos Campos, salvo que tu necesites alguno más.

Los Campos>> NumUbica (que sería se número que representa a una zona física), y Ocupado de tipo Si/No.

El proceso, sería muy parecido al de ahora.

Entra un Vehiculo >> NumMatricula.... NumUbica y Ocupado = True

Sale Vehiculo >> NumMatricula...... NumUbica = False.

Los NumUbica Disponibles (Estado = False) los derias sacar en un Combo.

Cuando lo tengas así comentamos. Necesitaré saber los Nombres de Tablas y Campos Implicados.

Mis saludos >> Jacinto

Aquí va una imagen de las tablas y relaciones Jacinto

Víctor: Al parecer Sveinbjorn y yo nos hemos solapado, con la respuesta.

Básicamente decimos lo mismo, pero él es más conciso, por lo que poco puedo añadir, salvo que si después de analizar y trabajar un poco las respuestas, sigues necesitando ayuda, aquí estamos. Mis saludos >> Jacinto

¡Gracias Jacinto!

No se si es correcto lo que hice: transformé el campo [NroAsignado] de la tabla principal de vehículos en  un cuadro combinado que lee el contenido de la tabla PLAZAS. Mañana continuaré con la tarea. 

Víctor: He releído todo el historial de la pregunta y en mi opinión tendrás un proceso ágil y seguro.

Solo una observación de como lo haría yo que no quiere decir que sea la mejor ni la única solución.

Cuando haces >> Me.NroAsignado.Value = Null, yo pondría >> Me.NroAsignado.Value = Un valor numérico que no esté en las "Plazas", puede ser cero o 99999, que para captura de datos posteriores, me parece mejor.

No obstante, y como te comento al principio eso es una apreciación personal. Saludos >> Jacinto

Víctor: Disculpa el lapsus.

Donde digo >> Me.NroAsignado.Value = Null, quería decir Me.NroAsignado.Value = "", que es lo que tu pones. Y te lo comento además porque mandas "Una cadena vacía", a un campo numérico.

Mis saludos >> Jacinto

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas