Imprimir página | Cerrar ventana

Como utilizar el bucle Do...Loop

Impreso de: Foro de Access y VBA
Categoría: Access y VBA
Nombre del foro: Access y VBA
Descripción del foro: Foro de programacion en Access (Con código y sin código)
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=86122
Fecha de impresión: 29/Marzo/2024 a las 00:40


Tema: Como utilizar el bucle Do...Loop
Publicado por: andressf
Asunto: Como utilizar el bucle Do...Loop
Fecha de publicación: 21/Septiembre/2021 a las 14:13
Buenas a todos, espero estén bien, desde ya agradezco su buena predispoición y el tiempo que se toman.
Estoy queriendo utilizar el bucle Do... Loop para que se repita la instrucción si se cumple la condición

Do While Forms!f_rev!F_Pedido_Revalida_Doc!ID_Nro_Rev_Doce > 1

DoCmd.RunSQL "Insert Into [T_Reval_Pedido_Docen](id_Rev_Ped_PRD, id_curso_rev_PRD,id_docent_PRD,id_insti_doc_PRD,nomyape_doc_PRD,tipo_dni_doc_PRD,dni_docent_PRD) Values (" & Forms!f_rev!F_Pedido_Revalida_Doc!ID_Nro_Rev_Doce & "," & Forms!f_rev!F_Pedido_Revalida_Doc!id_curso_rev & "," & Forms!f_rev!F_Pedido_Revalida_Doc!id_docent & "," & Forms!f_rev!F_Pedido_Revalida_Doc!id_insti_doc & ",'" & Forms!f_rev!F_Pedido_Revalida_Doc!nomyape_doc & "','" & Forms!f_rev!F_Pedido_Revalida_Doc!tipo_dni_doc & "'," & Forms!f_rev!F_Pedido_Revalida_Doc!dni_docent & ")"

Loop




Respuestas:
Publicado por: xavi
Fecha de publicación: 21/Septiembre/2021 a las 15:10
El "problema" de ese bucle es que, o bien no se ejecuta (porque el valor es menor o igual a 1) o se ejecuta eternamente (porque el valor supera 1)

En cualquier caso estaría bien que explicaras un poco más (conceptualmente) que es lo que deseas hacer porque yo no lo veo nada claro.

Un saludo


-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 21/Septiembre/2021 a las 15:49

Terrassa-BCN buenas, gracias por tu atención.

Tengo un formulario llamado F_curso el cual tiene un subformulario continúo vinculado con los datos de profesores.

Hay cursos que poseen 1 profesor y otros que tiene 2 o más.

El formulario F_curso tiene un botón que archivo todo en dos tablas que están relacionas.

Mientras el curso tenga un profesor no tengo inconvenientes me funciona todo bien, ahora el problema es que si el curso tiene 2 o más profesores ya que solo me copia el 1er profesor el 2do no me lo copia. Es ahí donde quiero colocar un bucle para que me copie si tiene 2 o más profesores.




Publicado por: xavi
Fecha de publicación: 21/Septiembre/2021 a las 17:37
Hola,

Para empezar mi nombre es Xavi, no Terrassa-BCN.

El problema es que cuando lanzas el código toma los datos del primer registro.

Yo lo enfocaría recorriendo el RecordsetClone del subformulario y lanzando la consulta de inserción en cada registro.
Ello implica:
- declarar una variable recordset
- abrir un recordset sobre el subformulario
- recorrerlo con un bucle Do Loop hasta que no termine (EOF)
- lanzar una consulta de inserción en cada registro pero tomando los datos del recordset y no del formulario como haces tu ahora

No es extremadamente complicado pero tampoco es de párvulos.

Un saludo



-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 22/Septiembre/2021 a las 13:41
Buenas Xavi, jaja perdón.

Podrás explicarme lo que me dices ya que no tengo muchos conocimientos. Gracias


Publicado por: lbauluz
Fecha de publicación: 22/Septiembre/2021 a las 14:46
Hola andressf


Si te fijas, haces un bucle, que resumido sería así:

do while X > 1

Inserta A en base de datos
loop

Bien, depende del valor de X, si X es menor que 1, no entrará jamás.
Si X es mayor que 1, entrará en el bucle y jamás saldrá, puesto que X no cambia.

Deberías, en mi opinión,  poner un control cambiando el valor de X dentro del bucle 

Por ejemplo 


do while X > 1
Inserta A en base de datos
X = 0
loop


Seguro que la realidad es "un poco más complicada", pero la idea final es esa.

Un saludo.

Luis


-------------
El Búho es un pajarraco


Publicado por: andressf
Fecha de publicación: 22/Septiembre/2021 a las 14:56
Dale buenisimo, lo voy a estudiar para aplicarlo y te comento.
Muchas gracias


Publicado por: andressf
Fecha de publicación: 23/Septiembre/2021 a las 13:36
Buenas Xavi, esuve probando pero no me funciona, a ver si puedo explicarme, el problema es que repite la secuncia pero sobre el mismo registro, no busca en un 2do registro,  nose si me explico.


Publicado por: xavi
Fecha de publicación: 23/Septiembre/2021 a las 13:55
Si, te explicas. Y la solución es que debes "moverte" al segundo registro. 

Si sigues pensando en clave formulario deberás moverte al segundo registro (mira DoCmd.MoveNext)  y cambiar la evaluación del bucle a "no hay más registros" (probablemente cuando salte un error)

Si pasas a pensar en clave de recordset, entonces vuelve a mi explicación y busca información sobre los conceptos que se mencionan.

Un saludo



-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 24/Septiembre/2021 a las 17:11
Buenas...

Podrás darme una ayuda con lo que me planteaste?

'- declarar una variable recordset

Dim db As Database                      ' Declaro la variable db para tipo base de datos.

'- abrir un recordset sobre el subformulario  (Forms!f_rev!F_Pedido_Revalida_Doc)
                                                             
Set rs = Forms!f_rev!F_Pedido_Revalida_Doc.Form.RecordsetClone

'- recorrerlo con un bucle Do Loop hasta que no termine (EOF)

Do Until Not rs.EOF
DoCmd.RunSQL "Insert Into [T_Reval_Pedido](Id_Rev_Ped_Doc_P_R, Fecha_P_R, Reval_Ano_P_R, LOCALIDAD_P_R, cod_postal_P_R) Values ('" & Id_Rev & "','" & fecha_pres & "','" & Me.ano_r & "','" & Me.LOCALIDAD_I & "','" & Me.cod_postal_I & "')"

loop

'- lanzar una consulta de inserción en cada registro pero tomando los datos del recordset y no del formulario como haces tu ahora




Publicado por: xavi
Fecha de publicación: 25/Septiembre/2021 a las 12:40
Declarar un recordset no es declarar una Database. Además es una buena práctica indicar el tipo. En este caso DAO

Dim rs As DAO.Recordset

(la db no es necesaria)

La apertura parece correcta.

El bucle debe evaluar una condición (no me acabé de expresar correctamente uy lo has traducido de forma literal) de forma que se repita mientras/hasta que no se cumpla. La ventaja de Do..Loop respecto a otras estructuras de bucle es que se puede controlar a la entrada, a la salida y con condiciones mientras y hasta. Si a eso le unimos el Not las posibilidades de condiciones son prácticamente todas.

En este caso se trata de que el bucle se ejecute hasta que termine el recordset:

Opción "mientras no finalice": Do While Not rs.EOF
Opción "hasta que finalice": Do Until rs.EOF

Para recorrer un recordset es necesario moverse por el ya que, de otra forma, siempre estará en el mismo registro y nunca saldrá del bucle:

Do condicion
  ' acciones
  rs.MoveNext
Loop

La SQL de acción debe tomar los valores del recordset en lugar del formulario. Debes entender que utilizamos el formulario como punto de partida y que recorremos los DATOS, no el formulario.

Debes sustituir Me. (consejo: mejor Me! que Me. para referirse a los controles de un formulario) por el recordset --> rs!ano_r

Finalmente, despues de recorrer el recordset (o sea: después de Loop) debes cerrarlo y "matarlo". 

rs.Close
Set rs = Nothing

Te recomiendo que busques y leas la información que puedas sobre todo lo que se ha apuntado en esta hilo. Los recordsets son sumamente útiles para hacer este tipo de acciones.

un saludo




-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 28/Septiembre/2021 a las 16:10

Buenas y nuevamente gracias....

 

** Debes sustituir Me. (consejo: mejor Me! que Me. para referirse a los controles de un formulario) por el recordset --> rs!ano_r Esto no termino de entender como cambiarlo, ya que los campos pertenecen a un suf formulario.

 

Me sigue sin recorrer los registros solo me copia el 1ero, a ver donde estoy fallando... desde ya muchas gracias por tu paciencia...

 

 

Dim rs As DAO.Recordset
Set rs = Forms!f_rev!F_Pedido_Revalida_Doc.Form.RecordsetClone

rs.MoveLast

sqlinsert = "INSERT INTO T_Reval_Pedido_Docen(id_Rev_Ped_PRD,id_curso_rev_PRD,id_docent_PRD,id_insti_doc_PRD,nomyape_doc_PRD,tipo_dni_doc_PRD,dni_docent_PRD) Values (" & Forms!f_rev!F_Pedido_Revalida_Doc!ID_Nro_Rev_Doce & ",'" & Forms!f_rev!F_Pedido_Revalida_Doc!id_curso_rev & "','" & Forms!f_rev!F_Pedido_Revalida_Doc!id_docent & "','" & Forms!f_rev!F_Pedido_Revalida_Doc!id_insti_doc & "','" & Forms!f_rev!F_Pedido_Revalida_Doc!nomyape_doc & "','" & Forms!f_rev!F_Pedido_Revalida_Doc!tipo_dni_doc & "')"

DoCmd.RunSQL (sqlinsert)

rs.MoveNext

Loop

rs.Close

Set rs = Nothing



Publicado por: xavi
Fecha de publicación: 28/Septiembre/2021 a las 18:06
1. Nunca entrarás en un bucle porque no lo inicias. La línea del Do no aparece por ningún sitio
2. Justo después de abrir el recordset te mueves al último ¿porqué?
3. Sigues sin cambiar el "chip": no se trata de sustituir el Me!loquesea por Forms!nombreform!loquesea; se trata de sustituir el Me!loquesea por rs!loquesea

Ejemplo del bucle con solo un campo:
Do Until rs.EOF
  sqlInsert = "INSERT INTO unaTabla (uncampotexto) VALUES('" & rs!uncampotexto & "')"
  DoCmd.RunSQL strInsert
  rs.Movenext
Loop




-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 29/Septiembre/2021 a las 14:34
Hola...
Tengo tantas pruebas que se me pasó lo de abrir el bucle Do lo mismo con mover al principio... se me está quemando el cerebro..jajaja

Estoy intentando cambiar el chip, me copia, pero sigue sin recorrer los registros, solo el prmero me copia.

Dim rs As DAO.Recordset
Set rs = Forms!f_rev!F_Pedido_Revalida_Doc.Form.RecordsetClone
MsgBox rs.RecordCount
rs.MoveLast
Do Until rs.EOF

sqlInsert = "INSERT INTO T_Reval_Pedido_Docen (id_Rev_Ped_PRD,localidad_doc_PRD) VALUES('" & rs!temp_ID_Nro_Rev_Doce & "','" & rs!localidad_doc & "')"
DoCmd.RunSQL sqlInsert
rs.MoveNext
Loop

rs.Close
Set rs = Nothing


Publicado por: xavi
Fecha de publicación: 29/Septiembre/2021 a las 15:27
Si haces un movelast te mueves al ultimo registro.... y de ese no se puede ir al siguiente.

Quita el rs.Movelast


-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 29/Septiembre/2021 a las 15:52
Se lo quité y anduvo una vez, ahora no me copia ninguno.

Dim rs As DAO.Recordset
Set rs = Forms!f_rev!F_Pedido_Revalida_Doc.Form.RecordsetClone
MsgBox rs.RecordCount

Do Until rs.EOF

sqlInsert = "INSERT INTO T_Reval_Pedido_Docen (id_Rev_Ped_PRD,localidad_doc_PRD) VALUES(" & rs!temp_ID_Nro_Rev_Doce & ",'" & rs!localidad_doc & "')"
DoCmd.RunSQL sqlInsert
rs.MoveNext
Loop

rs.Close
Set rs = Nothing



Publicado por: xavi
Fecha de publicación: 30/Septiembre/2021 a las 11:36
Imagino que te encuentras en esta secuencia de hechos:

- abres el formulario 
- ejecutas el código para un registro: funciona
- te mueves a otro registro
- ejecutas el código: no funciona
- sales del formulario
- vuelves a entrar
- ejecutas el código: funciona
- te mueves a otro registro
- ejecutas el código: no funciona

Si ese es el escenario es porque el Recordset se queda al final de los registros y, al volver  lanzar el código, la evaluación del rs.EOF es verdadero y no se ejecuta.

Prueba poniendo un rs.MoveFirst antes de cerrar el recordset (línea rs.Close)




-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: andressf
Fecha de publicación: 21/Octubre/2021 a las 14:36
Hola, estuve complicado por eso no respondí.

 lo puse rs.MoveFirst y a veces me funciona y muchas no
A veces tego 3 registros y me copia 2 otras simplemente no hace nada...
Me está superando...






Publicado por: andressf
Fecha de publicación: 21/Octubre/2021 a las 15:22
Creo haber encontrado el problema.

Pasa lo siguiente, a ver si me explico

Mientras en la tabla no haya datos me copia todos los registros, si en la tabla hay datos algunos me los copia y otros no.
En esa tabla se ingresan datos de profesores que dictan los cursos, hay profesores que dictan dos mas cursos, ahi es cuando no me los copia ya que tienen el campo id_Rev_Ped_PRD pero los datos del profesor son los mismos.

Como puedo solucionarlo?.
Gracias.








Publicado por: andressf
Fecha de publicación: 21/Octubre/2021 a las 17:57
Ufff ahora me tira...

Se ha producido el error 3021 en tiempo de ejecución
no hay ningun registro activo
Si cierro todo y abro de nuevo a veces desaparece

Si desaparece me tira este error!

Se ha producido el error 3134 en tiempo de ejecución
Error de sintaxis en la instrucción INSERT INTO

Dim rs As dao.Recordset
Set rs = Forms!f_rev!F_Pedido_Revalida_Doc.Form.RecordsetClone
MsgBox rs.RecordCount
                                   
Do Until rs.EOF

sqlInsert = "INSERT INTO T_Reval_Pedido_Docen(id_Rev_Ped_PRD, id_curso_rev_PRD, id_docent_PRD, id_insti_doc_PRD, nomyape_doc_PRD, tipo_dni_doc_PRD, dni_docent_PRD, fech_nac_doc_PRD, edad_doc_PRD, carac_tel_doc_PRD, tel_cel_doc_PRD, localidad_doc_PRD, cod_post_doce_PRD, calle_doc_PRD, num_calle_doc_PRD, email_1_doc_PRD) Values (" & rs!temp_ID_Nro_Rev_Doce & "," & rs!id_curso_rev & "," & rs!id_docent & "," & rs!temp_id_insti_doc & ",'" & rs!nomyape_doc & "','" & rs!tipo_dni_doc & "'," & rs!dni_docent & "," & rs!fech_nac_doc & "," & rs!edad_doc & "," & rs!carac_tel_doc & "," & rs!tel_cel_doc & ",'" _
& rs!localidad_doc & "','" & rs!cod_post_doce & "','" & rs!calle_doc & "'," & rs!num_calle_doc & ",'" & rs!email_1_doc & "')"

DoCmd.RunSQL sqlInsert
rs.MoveNext

Loop
rs.MoveFirst
rs.Close
Set rs = Nothing













Publicado por: xavi
Fecha de publicación: 22/Octubre/2021 a las 21:39
Pon un punto de interrupción antes del DoCmd.RunSQL, examinas el valor que contiene sqlInsert en la ventana de inmediato. La copias y la pegas en una nueva consulta. Ahí tienes más posibilidades de detectar cual es el error.

Un saludo


-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web



Imprimir página | Cerrar ventana