Recorrer tabla

Y ante todo darte las gracias por el trabajo que haces de forma desinteresada. Mi problema es el siguiente: Tengo una tabla de comerciales, otra de contratos y otra de comisiones. Según los comerciales van haciendo contratos, mediante varias macros, mi BD le asigna la comisión. Hasta ahí todo va bien. El problema lo tengo cuando un comercial hace más de 30 contratos ya que las comisiones suben a otra escala en la tabla "comisiones". En el registro activo me lo calcula perfectamente, pero me gustaría que actualizara todos los registros anteriores de ese comercial a la nueva escala de comisiones. Tengo colocado en el formulario un campo llamado contador, el cual me dice el numero exacto de contratos que lleva el comercial que ha realizado ese contrato. Lo que quiero es que cuando llegue a 31 recorra toda la tabla de la BD y en cada registro que el campo contador tenga el valor 31 me ejecute la macro que asigna la comisión, o sea, actualizar a la nueva escala de comisiones los contratos que lleva ese comercial. ¿Sabes cómo lo podría hacer? Me urge muchísimo y estoy super atascado en este punto.

2 respuestas

Respuesta
1
Yo lo haría a través de una consulta de actualización de datos.
Crea una consulta normal, añadiendo la tabla dode quieres hacer la actualización de datos. No añadas ningún campo, por el momento, solo la tabla.
Dale al botón derecho del rtón, y selecciona el tipo de consulta "actualización".
A partir de ese momento, pon dos campos, uno el que quieres actualizar y otro el que deseas comprobar (en el caso de que no exista el campo de ese contador, sería buena idea añadir un campo para ese menester).
El campo que deseas actualizar, verás que hay un dato que dice "Actualizar a" (ahí pones el valor que quieras modificar) y otro dato que pone "Criterio". (Ese sería el de los 30 contratos).
Una vez la ejecutes, actualizará todos los datos de la tabla según el criterio de los datos.
Muchas gracias por contestar tan rápido. Veras, esa idea ya la barajé en su momento, lo que ocurre es que no puedo poner un dato determinado en la consulta de actualización, ya que las tablas de comisiones también pueden cambiar. Por eso el calculo de la comisión se hace mediante macros que acuden a la tabla de las comisiones, hacen una consulta del dato en esa tabla y luego colocan la comisión en el otro formulario. Es por ese que necesito que recorra la tabla y en cada registro que encuentre el contador en "31" me ejecute la macro. Posiblemente haya que hacerlo con código Visual Basic. A ver que me puedes decir, y otra vez gracias.
No se si la macro realiza en global el cambio de todos los registros o el de uno en concreto, pero bueno, supongamos que NO lo hace todo a la vez, es decir, la macro actualiza el dato actual del Comercial que este en ese momento leyéndose. (Si no es el caso me lo dices)
Debes utilizar un formulario nuevo apuntando los datos a la misma tabla, y un botón de comando para ese menester.
El código dentro del "Command" sería así:
-----------------------------------------------------
Dim Reg As DAO. Recordset
Set Reg = Me. Recordset
 DoCmd. GoToRecord , , acFirst
    While Not Reg. EOF
        Nombredelamacro
        Reg. MoveNext
    Wend
-----------------------------------------------------
Perdona, me olvide de poner la condición, je je
Dim Reg As DAO. Recordset
Set Reg = Me. Recordset
 DoCmd. GoToRecord , , acFirst
    While Not Reg. EOF
    if reg!nombredelcampocontador = 31 then
        nombredelamacro
Reg. MoveNext
else
        Reg. MoveNext
end if
    Wend
Efectivamente la macro actualiza el registro actual; Con el código que me has facilitado recorre todos los registros de la tabla, pero no me ejecuta la macro, además queda "un poco feo" todos los registros (que son bastantes) pasando por el formulario. ¿Hay otra manera de hacerlo de forma "más oculta"?
Pues más fácil.
Solo debes de hacer un botón de comando en el mismo formulario.
If me.nombredecampocontrol = 31 then
   Dim NombreMacro As String
   NombreMacro = "ACTUALIZAR"
   DoCmd.RunMacro NombreMacro
end if
Supongo que 31 se debería reiniciar a 0, no? en ese caso pones dentro del IF, cuando ejecutes la macro, me.nombredecampocontrol = 0.
Perdoname por no haberme explicado correctamente. Lo que te decía es que cuando ejecutaba el código que me diste, no ejecutaba la macro en cada uno de los registros que tiene la tabla, que es lo que realmente necesito.
¿mmm... pero la macro funciona sola?
Por que si funciona sola con el código anterior debería irte...
¿Me podrías mandar a mi correo la tabla y la macro? ... es para poder hacerte las pruebas.
Que bien! Me está funcionando perfectamente con el código que me diste cuando me dijiste que se te olvido la condición, porque lo puse mal. Lo único que ocurre es que pasan todos los registros por la vista del formulario. Hay alguna forma de hacerlo de forma más "discreta", osea, que no se vea.
Si, puedes poner el formulario a visible=false y cuando acabe la macro ponerlo a visible=true.
Prueba desde la misma macro.
En cuanto he puesto el formulario a "visible=false" ya no ha ejecutado el código.
¿Me podrías mandar a mi correo la tabla y la macro?
Respuesta
1
Pondría el código en un evento por ejemplo al activar el registro o al insertar, en fin eso según tengas planteado el formulario. El código sería:
Dim db as database
Dim rs as Recordset
Set db=Currentdb
If Form!Contador.Value=31 then
Set rs=db.OpenRecordset("Select * From <Nombre de la tabla>")
Do while not rs.eof
If rs.Contador=31 then
DoCmd.RunMacro "Nombre de la macro que quieras ejecutar"
end if
rs.MoveNext
Loop
End If
Me cuentas.
Buenos días, gracias por contestar. Te cuento: He colocado el evento en un botón de comando para ver si funcionaba y me da un "Error de compilación: No se encontró el método o el dato miembro" y en la linea:
If rs.Contador=31 then
Me sombrea
. Contador
Perdona lo escribí de memoria y...
Rs! Contador
Ahora no me da ningún fallo, pero solo me ejecuta la macro en el registro activo no en la totalidad de la tabla que cumple la condición.
Lo que hacemos en el código es recorrer el recordset basado en la totalidad de la tabla
Select * from NombredelaTabla
Y si encuentra un registro en el que el campo contador sea igual a 31 ejecuta la macro, al margen del registro activo, este no entra en el código salvo en el 1er If.
Si has puesto un botón pon el código sin este If:
Dim db as database
Dim rs as Recordset
Set db=Currentdb
Set rs=db.OpenRecordset("Select * From <Nombre de la tabla>")
Do while not rs.eof
If rs!Contador=31 then
DoCmd.RunMacro "Nombre de la macro que quieras ejecutar"
end if
rs.MoveNext
Loop
Me cuentas.
Ya creo que se lo que esta pasando... He puesto un nombre inexistente de macro para comprobar que la esta ejecutando y efectivamente me dice que no encuentra esa macro, por lo que ya se que si la está ejecutando. Lo que ocurre es que no se actualizan los datos al no estar en el registro activo y abrir que añadir algo en el código para que actualizara los datos a medida que va recorriendo la tabla.
Pero la actualización de los registros la tiene que hacer la propia macro. No se... ¿qué hace exactamente la macro? Porque quizás lo podamos sustituir por código.
La macro lo que hace es abrir un formulario de forma oculta basado en una consulta que se hace a la tabla "comisiones" y el dato que arroja lo coloca en un campo que hay en el formulario de la tabla "contratos" que se llama "comisión".
Pero entonces... ¿la macro no actualiza los registros de la tabla?
Bueno... La macro actúa sobre el registro activo, o sea, calcula la comisión del registro de la tabla que tengo en pantalla en el formulario. Según los valores que hay en otros campos del formulario asigna al campor comisión (que hasta entonces está vacío) un valor determinado que esta fijado en la tabla comisiones. Cuando construí la macro fui asignando valores a los campos del formulario. ¿Debería haberlo hecho sobre los campos de la tabla?
Si he entendido bien lo que quieres es que si un comercial llega a 31 contratos su comisión varia pero ¿varia en el contrato 31 y posteriores o en todos los anteriores? Si es en todos, creo que sí, tendrías que actualizar los registros en la tabla por medio de una sentencia sql ejecutada por el método DoCmd. RunSql
DoCmd.RunSql "Update <nombretabla> set <campotabla>=<nuevovalor>......
Efectivamente es en todos los contratos, el problema para utilizar el Update es que el nuevo valor no es un valor fijo, sino que varia dependiendo de varios factores, por lo que el nuevo dato tendría que venir de una consulta a la tabla comisiones. De hecho la macro funciona a base de consultas que tienen en cuenta todos esos factores. ¿Se puede hacer? ¿Se puede meter una consulta dentro de otra? ¿Puede el nuevo valor venir derivado de otra consulta?
Perdona, pero me acabo de dar cuenta de que tu código no recorre todos los registros, ya que si lo hiciera debería terminar en el ultimo, y sin embargo no se mueve del registro que esta en pantalla, por favor revísalo, por eso solo me actualiza el registro actual. Te suplico me perdones por toda la "tabarra" que te esoy dando. Muchas Gracias
Creo que el código si recorre toda la tabla, aunque en el formulario no se mueva del registro activo. Para comprobarlo solo tienes que poner un MsgBox que te dé el campo que quieras y así compruebas si te recorre toda la tabla. Te pongo como ejemplo el campo Contador:
Dim db as database
Dim rs as Recordset
Set db=Currentdb
Set rs=db.OpenRecordset("Select * From <Nombre de la tabla>")
Do while not rs.eof
MsgBox(rs!Contador)
If rs!Contador=31 then
DoCmd.RunMacro "Nombre de la macro que quieras ejecutar"
end if
rs.MoveNext
Loop
Me cuentas.
Tienes toda la razón, el código recorre toda la tabla. Me parece que el problema puede estar en que cuando "contador" llega a 31 y le digo que ejecute el código, en los registros anteriores el campo contador no esta en 31 y por eso no los actualiza por lo que tendría que actualizar antes el campo contador (creo). De todas formas he conseguido algo parecido a lo que quiero con este código:
Dim Reg As Recordset
Set Reg = Me.Recordset
If Form!Contador.Value = 31 Then
DoCmd.GoToRecord , , acFirst
While Not Reg.EOF
If Reg!Contador = 31 Then
DoCmd.RunMacro "Comisiones"
Reg.MoveNext
Else
Reg.MoveNext
End If
Wend
End If
Con esto recorre toda la tabla y ejecuta la macro en cada uno de los registros. El problema es que queda horrible todos los registros pasando por la pantalla uno tras otro. ¿Podrías sugerirme algún cambio para que no se vieran?
Lo que pasa es que no entiendo el porque hacerlo en el formulario y no sobre la propia tabla. Si en vez de ejecutar la macro ejecutas una consulta de actualización creo que sería mejor.
Esta claro que tienes razón, lo que pasa es que no se como implementar esa consulta ya que tiene que valorar varios datos para arrojar un resultado o otro. El calculo de la comisión viene dado por el "rango" en que esta encuadrado cada cormercial, el "producto" que ha contratado etc... así que la consulta no puede estar basada en un valor fijo sino en varias posibilidades. Yo con las macros introduzco varias condiciones ("IF") para que vaya enlazando con otras macros. Ten encuenta que la macro que yo coloco como inicio va llamando a otras dependiendo de los valores que están en cada registro y en varios campos.
Otra cosa que he intentado es convertir todas las macros a código e introducirlas en el código. Cambie todos los campos que estaban definidos como "Form![Formulario]![nombre de Campo] por rs![Nombre de Campo]. Anido todas las sentencias IF pero cuando le toca asignar el valor al campo comisión (rs!Comision= ...) me da el siguiente fallo "Update o CancelUpdate sin AddNew o Edit"
Me parece bien que lo pases a código. En cuanto al error, antes de actualizar un registro hay que: añadir uno nuevo o editarlo:
Rs. Edit o rs. AddNew

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas