¿Cómo crear con Access y VB una base de datos que te de los turnos rotatorios de unos trabajadores?

Tengo una base de datos en la que tiene tres tablas: TRABAJADORES, TURNOS Y TURNOS_TRABAJADOR, con esta última creé un formulario que tiene los campos CÓDIGO_TRABAJADOR, TURNO Y FECHA_INICIO y un control llamado FECHA_INICIO_TURNOS. Lo que pretendo es que poniendo la fecha_inicio_turnos automáticamente me cubra todos los campos del formulario o de la tabla (son 7 trabajadores con 7 turnos). Me estoy rompiendo la cabeza y escribí este código (mi primer código, perdonar las tonterías que seguro que puse), pero imagino que no es necesaria tanta historia, además yo escribo el código con lo que pretendo pero ¿cómo lo tendría que llamar desde el formulario para que se ejecutase?. Tampoco sé si es necesario que lo declare público ni sé si al final del código vuelva a empezar el ciclo de turnos sumando las fechas o tengo que repetirlos hasta completar los 365 días si quisiera sacar un calendario anual por ejemplo.

Public Sub turnostodos()
Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Trabajador = 1
Trabajador = 2
Trabajador = 3
Trabajador = 4
Trabajador = 5
Trabajador = 6
Trabajador = 7
Turno = 1
Turno = 2
Turno = 3
Turno = 4
Turno = 5
Turno = 6
Turno = 7
If Trabajador = 1 And Turno = 1 Then Fecha_inicio = Fecha_inicio
If Trabajador = 2 And Turno = 2 Then Fecha_inicio = Fecha_inicio
If Trabajador = 3 And Turno = 3 Then Fecha_inicio = Fecha_inicio
If Trabajador = 4 And Turno = 4 Then Fecha_inicio = Fecha_inicio
If Trabajador = 5 And Turno = 5 Then Fecha_inicio = Fecha_inicio
If Trabajador = 6 And Turno = 6 Then Fecha_inicio = Fecha_inicio
If Trabajador = 7 And Turno = 7 Then Fecha_inicio = Fecha_inicio

If Trabajador = 1 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 2 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 3 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 4 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 5 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 6 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 7
If Trabajador = 7 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 7

If Trabajador = 1 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 2 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 3 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 4 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 5 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 6 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 14
If Trabajador = 7 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 14

If Trabajador = 1 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 2 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 3 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 4 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 5 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 6 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 21
If Trabajador = 7 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 21

If Trabajador = 1 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 2 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 3 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 4 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 5 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 6 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 28
If Trabajador = 7 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 28

If Trabajador = 1 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 2 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 3 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 4 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 5 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 6 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 35
If Trabajador = 7 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 35

If Trabajador = 1 And Turno = 7 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 2 And Turno = 1 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 3 And Turno = 2 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 4 And Turno = 3 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 5 And Turno = 4 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 6 And Turno = 5 Then Fecha_inicio = Fecha_inicio + 42
If Trabajador = 7 And Turno = 6 Then Fecha_inicio = Fecha_inicio + 42

End Sub

3
Respuesta
2

Andrés, no te voy a dar la solución, pues Jacinto ya te indicó dónde verla y sería repetirme... Sin embargo sí te voy a responder a alguna de tus dudas "existenciales" que planteas y señalarte algún error de tu código:

Yo escribo el código con lo que pretendo pero ¿cómo lo tendría que llamar desde el formulario para que se ejecutase?.

Para llamarlo desde cualquier parte simplemente basta con poner el nombre del procedimiento, a saber:

Turnostodos

o

Call turnostodos

Tampoco sé si es necesario que lo declare público

Esto depende de dónde lo escribas y dónde lo quieras usar. Me explico: si el procedimiento lo escribes en el módulo asociado al formulario y sólo lo vas a usar desde el propio formulario, lo deberías declarar como Private. Si lo vas a llamar desde otro formulario o desde cualquier otro módulo, entonces lo has de declarar como Public. Si el procedimiento lo escribes en un módulo independiente, para poder llamarlo desde un formulario, debe ser Public.

Por otro lado, errores de tu código, para que te sirva para evitarlos en futuras ocasiones.

Cuando haces:

Trabajador = 1
Trabajador = 2
...
Trabajador = 7

El valor que queda en la variable Trabajador es 7, no se quedan los 7 valores que le asignas consecutivamente. Por tanto, de todos los Ifs que pones, el único que se va a cumplir SIEMPRE es éste:

If Trabajador = 7 And Turno = 7 Then Fecha_inicio = Fecha_inicio

porque en el código el último valor que le asignas a trabajador y turno es 7. El resto daría igual que los borraras, porque nunca se van a dar las condiciones para que se ejecute el código que sigue al Then.

Y por último, esa línea tampoco tendría mucho sentido, porque al Fecha_inicio le asignas el mismo valor que ya tiene, y que además es un valor nulo, porque a esa variable ni le das tú un valor en el código, ni haces que lo coja de ningún control del formulario (y si es lo que pretendes, que coja el valor de un cuadro de texto llamado Fecha_inicio, deberías indicar con "Me." que se refiere a un control del formulario, y además, deberías usar un nombre distinto para la variable, para que Access sepa a qué te refieres al decir Fecha_inicio: la variable o el control del formulario)

Gracias cómo siempre por contestar Sveinbjorn El Rojo,

Lo del llamar al procedimiento ya sé que es con el call y el nombre del procedimiento. No me expresé bien, yo lo que quería era saber la ejecución en estos casos. Pongamos por ejemplo el código que puse ( ya sé que está mal, puesto que de programación de momento ni papa). Yo lo que quiero llegar es a lo siguiente: Creo un botón mismamente en un formulario vacío, le pongo que al hacer Click: call turnostodos (hasta aquí no tengo problema). Pero yo lo que quiero, es que me inserte en una tabla  dependiendo de la fecha de los turnos algo similar a lo que puse arriba, el código sé que se lee de arriba abajo, por lo que me dijiste sólo se ejecutaría la última línea, pero ¿no se puede ir intercalando sentencias para que vaya añadiendo registros a una tabla por ejemplo? (por cierto me acabo de dar cuenta de que el código que estaba escribiendo no era realmente lo que quería. Quería algo similar a esto pero que funcionase claro. Imagino que el inser into funciona con SQL pero aquí no, yo buscaba lo equivalente, si es que lo hay):

Private Sub cmdadjudicación_de_turnos_Click()
Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Trabajador = 1
Trabajador = 2
Trabajador = 3
Trabajador = 4
Trabajador = 5
Trabajador = 6
Trabajador = 7
Turno = 1
Turno = 2
Turno = 3
Turno = 4
Turno = 5
Turno = 6
Turno = 7
Fecha_inicio = #8/13/2018#
If Fecha_inicio = fecha() Then Trabajador = 1 And Turno = 1
INSERT INTO tblempleadosturnos (fecha_inicio, trabajador, turno)
    VALUES (Fecha_inicio, trabajador, turno)


If Fecha_inicio = fecha() Then Trabajador = 2 And Turno = 2
INSERT INTO tblempleadosturnos (fecha_inicio, trabajador, turno)
    VALUES (Fecha_inicio, trabajador, turno)
.......................................................


End Sub

Perdón por las barbaridades que pueda escribir, dentro de mi ignorancia!

Me contesto a mi mismo ¿… hay forma de ejecutar las sentencias SQL desde código? Sí, simplemente es con DoCmd.RunSQL instrucción después de la sentencia SQL. Pero sigo con mis DUDAS EXISTENCIALES ;) ahora lo que quiero es en la sentencia SQL me coja los valores de mi código, no que se los tenga que ir poniendo (sino, para nada me sirve). ¿hay forma de llamar a los datos de las variables que declaré, desde VALUES? Si pongo datos directamente VALUES (1,1,#13/08/2018#) funciona sin problema, pero si pongo como pretendo nada de nada:

……….
If Fecha_inicio = fecha Then Trabajador = 1 And Turno = 1
instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (trabajador, turno, fecha)"
DoCmd.RunSQL instruccion

Pues así :

instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (" & trabajador & "," &  turno & ",#" & fecha & "#)"

Si tienes problemas con la fecha, usa cdate(Fecha) o Format(Fecha,"mm/dd/yyyy")

¿Dónde está el horror? Según está sólo me pone el número de turno 7 y la fecha de hoy en la primera fila que inserta, y de nuevo turno 7 y la fecha dentro de una semana. Anulo las variables de turnos  (turno=1, turno=2 …) para ver si me aparecería trabajador 7 y tampoco nada. :(

¿Al poner "If Fecha_inicio = Date Then Trabajador = 1 And Turno = 1" no me tendría que poner al ser hoy que el trabajador es 1 y el turno 2?

Private Sub cmdsino_Click()

Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Dim instruccion As String

Trabajador = 1
Trabajador = 2
Trabajador = 3
Trabajador = 4
Trabajador = 5
Trabajador = 6
Trabajador = 7
Turno = 1
Turno = 2
Turno = 3
Turno = 4
Turno = 5
Turno = 6
Turno = 7
Fecha_inicio = Date

If Fecha_inicio = Date Then Trabajador = 1 And Turno = 1
instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion
Fecha_inicio = Date + 7
If Fecha_inicio = Date + 7 Then Trabajador = 2 And Turno = 2
instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion

End Sub

Pues no, porque después del Then no puedes encadenar con And, tienes que hacerlo en distintas líneas y cerrar con end if:

If Fecha_inicio = Date Then

Trabajador = 1

Turno = 1

End if

Sigo rompiéndome la cabeza y disculpa que sea tan burro … pero creo que cuanto más aprendo menos sé ;), ¿que tendría que hacer para que funcione el código?. De esta manera sólo me coge el primer valor: Trabajador 1, Turno 1 y la fecha que le meta por el inputbox

Private Sub cmdsino_Click()

Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Dim instruccion As String

Trabajador = 1
Turno = 1
Fecha_inicio = InputBox("introduce fecha de inicio")

DoCmd.SetWarnings False

If Fecha_inicio = Fecha_inicio Then
Trabajador = 1
Turno = 1
instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion

Fecha_inicio = Fecha_inicio + 7

ElseIf Fecha_inicio = Fecha_inicio + 7 Then
Trabajador = 2
Turno = 2
instruccion = "INSERT INTO prueba (trabajador, turno, fecha)VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion
End If

DoCmd.SetWarnings True

End sub

Te respondo mañana por la noche con calma, que estoy de viaje y por el móvil es un poco "rollo"...

De todas formas, te convendría mirarte con calma algún manual de VBA para entender mejor las instrucciones y cómo funcionan, sobre todo si tienes intención de ir programando cosillas en tus bds. Por ejemplo los de la web de Neckkito, o el que hice para http://nksvaccessolutions.com/academy/ 

Te pego tu código, y te explico tus "errores" en negrita:

Private Sub cmdsino_Click()

Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Dim instruccion As String

Trabajador = 1 
Turno = 1 

Fecha_inicio = InputBox("introduce fecha de inicio")

DoCmd.SetWarnings False

If Fecha_inicio = Fecha_inicio Then 'este If no tiene sentido, porque Fecha_inicio siempre será igual a Fecha_inicio
Trabajador = 1 'esto sobra, porque trabajador ya era = 1
Turno = 1 'esto sobra, porque turno ya era = 1
instruccion = "INSERT INTO prueba (trabajador, turno, fecha) VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion

Fecha_inicio = Fecha_inicio + 7

ElseIf Fecha_inicio = Fecha_inicio + 7 Then 'Este ElseIf no tiene sentido, porque si se ejecuta el bloque If anterior (que lo hará siempre), este ya no se va a ejecutar, aunque en la linea anterior cambies el valor de Fecha_inicio
Trabajador = 2
Turno = 2
instruccion = "INSERT INTO prueba (trabajador, turno, fecha) VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion
End If

DoCmd.SetWarnings True

End Sub

La forma de que te inserte los dos registros que buscas en la tabla, tal y como quieres sería:

Private Sub cmdsino_Click()
Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Dim instruccion As String
Trabajador = 1 
Turno = 1 
Fecha_inicio = InputBox("introduce fecha de inicio")
DoCmd.SetWarnings False
instruccion = "INSERT INTO prueba (trabajador, turno, fecha) VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion
'Hasta aquí te insertó el trabajador 1, turno 1 y la fecha introducida
'Ahora pasas al trabajador y turno de la semana siguiente
Fecha_inicio = Fecha_inicio + 7
Trabajador = 2
Turno = 2
instruccion = "INSERT INTO prueba (trabajador, turno, fecha) VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
DoCmd.RunSQL instruccion
DoCmd.SetWarnings True
End Sub

Muchas gracias Sveinbjorn El Rojo, es increíble cómo hacéis que lo que parece super complicado sea tan fácil a veces. Yo ya ves que estoy en pañales, pero quiero mejorar poco a poco, por cierto ... vaya página que os currasteis, imagino que tu y Neckkito, una pena que se tenga que cerrar, puesto que es material de excelente calidad (cuantas veces perdemos el tiempo mirando manuales muy malos o con profesores pésimos. Fui a clases de Access hace años y el profe lo único que quería es que escribiéramos mucho para explicar muy poco o nada ... para tenernos entretenidos horas y horas metiendo datos y no aprendiendo lo importante del programa vamos).

Volviendo al código yo con el tema del IF quería transmitir que si la fecha era hoy me pusiese los turnos y trabajadores: 1 1, 2 2, 3 3 ..., si la fecha era uno más 7 días: 1 2, 2 3, 3 4, ... pero ya veo que iba muy mal con mis ideas. Por cierto, ¿como puedo hacer para que ese código que ya tengo se me repita pero con diferentes fechas?, me sirve el que te puse: Ese devuelve Trabajador 1 Turno 1 fecha, trabajador 2 Turno 2 fecha+7. Si quiero repetir ese bucle o como se llame 10  veces ¿? creo que se puede pero no me entero mucho con algo de i=número de veces y el if o algo así ... pero no me entero, escucho fuegos pero no sé donde ;)

Y por cierto ... si que me da problema el tema de las fechas: la primera vez me suma meses y después ya suma correctamente ... los días. Puse así pero tampoco me funciona:

Fecha_inicio = DateAdd("d", 7, Fecha_inicio)

también probé con esto al principio pero nada de nada:

Fecha_inicio = Format(#1/1/2018#, "dd/mm/yyyy")

No te voy a hacer todo el desarrollo del código, porque no tengo tiempo (ni ganas) y no es una cosa de escribir 4 líneas y ya...

Para mi la mejor solución es la que explica Chea y que te pasó Jacinto en su respuesta, pero puedes hacer ciclos con For Next.

Para hacerlo 10 veces, como preguntas, y hasta aquí mi ayuda con este tema (XDD):

Private Sub cmdsino_Click()
Dim Trabajador As Byte
Dim Turno As Byte
Dim Fecha_inicio As Date
Dim instruccion As String
Dim i As Integer
Fecha_inicio = InputBox("introduce fecha de inicio")
Trabajador = 0
Turno = 0
DoCmd.SetWarnings False
For i = 1 To 10
    Trabajador = Trabajador + 1
    Turno = Turno + 1
    instruccion = "INSERT INTO prueba (trabajador, turno, fecha) VALUES (" & Trabajador & "," & Turno & ",#" & Fecha_inicio & "#)"
    DoCmd.RunSQL instruccion
    Fecha_inicio = Fecha_inicio + 7
Next i
DoCmd.SetWarnings True
End Sub

El resto de combinaciones ya es cosa tuya sacarlas siguiendo el esquema.

En cuanto a las fechas, VBA trabaja con fechas en formato americano, es decir con el mes primero. La solución la tienes en mi respuesta previa cuando te lo comenté, pero veo que no la has leído bien...

2 respuestas más de otros expertos

Respuesta
1

Andrés: En la Web de Nksv... se hizo una pregunta de ese estilo, y creo que su desarrollo puede ayudarte.

http://nksvaccessolutions.com/Foro/viewtopic.php?t=410 

Un saludo >> Jacinto

Respuesta

No es fácil realizar turnos rotarios en Access se deben tener en cuenta varios aspectos como, día de descanso, fechas, hora de ingreso al turno y hora de salida etc. Por mi parte no he elaborado aplicaciones con asignación de turnos al azar, espero otro experto tenga la solución.

Si envía su correo le estaré suministrando un programa gratis para fijar horarios de clases, de pronto lo puede adaptar.

Mi correo es [email protected]

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas