Access. Mostrar datos en consultas rotatoriamente
Mi pregunta va sobre Access, a ver si sabes tú cómo se hace o si me
puedes sugerir a qué otro experto preguntar.
¿Se pude hacer (generando alguna expresión determinada) que los datos devueltos
por una consulta Access vayan rotando cada vez que se ejecuta/abre la misma? Si
ahora aparece, por este orden 12345, quiero que en la siguiente vez que abra la
consulta o la ejecute (por ejemplo en Internet), se presenten/listen como 23451 y
así ucesivamente (34512, 45123 51234 y de nuevo 12345, 23451, etc sin fin).
Lo de que la info se vea en Internet lo tengo claro, el problema es que se muestra
tal cual "sale" de la consulta y yo quiero entonces que la consulta sea la que ordene
los datos de forma rotatoria. ¿Sirven para ello las funciones incorporadas de
cronómetro o número aleatorio que crea Access?
¿Access es capaz de hacerlo? ¿Cómo se hace?
puedes sugerir a qué otro experto preguntar.
¿Se pude hacer (generando alguna expresión determinada) que los datos devueltos
por una consulta Access vayan rotando cada vez que se ejecuta/abre la misma? Si
ahora aparece, por este orden 12345, quiero que en la siguiente vez que abra la
consulta o la ejecute (por ejemplo en Internet), se presenten/listen como 23451 y
así ucesivamente (34512, 45123 51234 y de nuevo 12345, 23451, etc sin fin).
Lo de que la info se vea en Internet lo tengo claro, el problema es que se muestra
tal cual "sale" de la consulta y yo quiero entonces que la consulta sea la que ordene
los datos de forma rotatoria. ¿Sirven para ello las funciones incorporadas de
cronómetro o número aleatorio que crea Access?
¿Access es capaz de hacerlo? ¿Cómo se hace?
1 Respuesta
Respuesta de davidth
1
1
La solución rápida que se me ocurre en estos momentos, es la de sacar una copia de la tabla que contiene los datos originales hacia una tabla NO INDEXADA y mostrar esa tabla en vez de tu tabla original. En esa copia NO INDEXADA, eliminas el registro que se encuentra al principio de la tabla y lo vuelves a agregar, lo que hará que aparezca al final de la misma.
Por ejemplo, si en la tabla no indexada (copia) tienes 5 registros en este orden 12345, entonces, después de que el usuario haya visto los resultados y cierre el formulario (o la página html) puedes poner un código parecido a esto:
Dim rs As DAO.Recordset
Dim campo1 As String, campo2 As String '..poner todos los campos requeridos
Set rs = Me.RecordsetClone
Rs. MoveFirst
campo1 = rs("campo1") '...hacer lo mismo para el campo2, campoN
'se agrega antes de eliminarlo
rs.AddNew
rs("campo1") = campo1 '...hacer lo mismo para el campo2, campoN
rs.Update
'se elimina el primer registro
rs.MoveFirst
rs.Delete
Rs. Close
Ahora, la próxima vez que el usuario vuelva a desplegar el mismo formulario (o página html), verá los registros rotados (23451).
Este código es para Access, pero lo puedes adaptar fácilmente para ADO (páginas ASP). EL TRUCO ES: copiar los datos a una tabla NO INDEXADA. Y sí funciona, porque ya lo probé :)
Por ejemplo, si en la tabla no indexada (copia) tienes 5 registros en este orden 12345, entonces, después de que el usuario haya visto los resultados y cierre el formulario (o la página html) puedes poner un código parecido a esto:
Dim rs As DAO.Recordset
Dim campo1 As String, campo2 As String '..poner todos los campos requeridos
Set rs = Me.RecordsetClone
Rs. MoveFirst
campo1 = rs("campo1") '...hacer lo mismo para el campo2, campoN
'se agrega antes de eliminarlo
rs.AddNew
rs("campo1") = campo1 '...hacer lo mismo para el campo2, campoN
rs.Update
'se elimina el primer registro
rs.MoveFirst
rs.Delete
Rs. Close
Ahora, la próxima vez que el usuario vuelva a desplegar el mismo formulario (o página html), verá los registros rotados (23451).
Este código es para Access, pero lo puedes adaptar fácilmente para ADO (páginas ASP). EL TRUCO ES: copiar los datos a una tabla NO INDEXADA. Y sí funciona, porque ya lo probé :)
Estimado David:
Te quedo agradecidísimo pero ni siquiera sé qué es una tabla no indexada ni sé tampoco como rellenar los datos que me propones (ni donde ponerlos). Yo trabajo en access en el modo diseño de consultas. Ahora bien, en la consulta en la que quiero hacer que roten los resultados (sin dejar de verse ninguno en ningún momento), te puedo dar el código de la vista SQL que genera Access en la consulta y que es el siguiente:
SELECT FACTURACION.Cliente, FACTURACION.Banner, FACTURACION![Fecha ALTA]+365 AS Baja, FACTURACION.Url, FACTURACION.Primera, FACTURACION.Castillos, FACTURACION.Piromusicales, FACTURACION.Piroacuaticos, FACTURACION.Mascletaes, FACTURACION.Toros, FACTURACION.Infantil, FACTURACION.Tiendas, FACTURACION.Clase3, FACTURACION.Especiales, FACTURACION.Magia, FACTURACION.Dimonis, FACTURACION.Teatro, FACTURACION.Luminarias, FACTURACION.Importadores, FACTURACION.Exportadores, FACTURACION.Materias, FACTURACION.Tecnologia, FACTURACION.Busqueda, FACTURACION.Agenda, FACTURACION.Contacto, FACTURACION.Personas
FROM FACTURACION
WHERE ((([FACTURACION]![Fecha ALTA]+365)>=Now()));
Esto lee los datos de la tabla Facturación y muestra los registros de quienes no han caducado (fecha de alta +1 año). El problema es que estos datos se presentan siempre de la fisma forma: en el mismo orden y yo quiero que tal cual está la cosa ¿qué hay que añadir y dónde y cómo? Para que cada vez que se ejecute la consulta rote el orden de presentación de los clientes, bv; Jose, Ana, Luis / Ana, Luis, Jose / Luis, Jose, Ana / Jose, Ana, Luis / etc.
Si me puedes decir qué hay que poner pero en el modo diseño de la consulta te lo agradeceré. Si es en el modo SQL pues también.
Un saludo cordialísimo. Y gracias de todas formas.
Te quedo agradecidísimo pero ni siquiera sé qué es una tabla no indexada ni sé tampoco como rellenar los datos que me propones (ni donde ponerlos). Yo trabajo en access en el modo diseño de consultas. Ahora bien, en la consulta en la que quiero hacer que roten los resultados (sin dejar de verse ninguno en ningún momento), te puedo dar el código de la vista SQL que genera Access en la consulta y que es el siguiente:
SELECT FACTURACION.Cliente, FACTURACION.Banner, FACTURACION![Fecha ALTA]+365 AS Baja, FACTURACION.Url, FACTURACION.Primera, FACTURACION.Castillos, FACTURACION.Piromusicales, FACTURACION.Piroacuaticos, FACTURACION.Mascletaes, FACTURACION.Toros, FACTURACION.Infantil, FACTURACION.Tiendas, FACTURACION.Clase3, FACTURACION.Especiales, FACTURACION.Magia, FACTURACION.Dimonis, FACTURACION.Teatro, FACTURACION.Luminarias, FACTURACION.Importadores, FACTURACION.Exportadores, FACTURACION.Materias, FACTURACION.Tecnologia, FACTURACION.Busqueda, FACTURACION.Agenda, FACTURACION.Contacto, FACTURACION.Personas
FROM FACTURACION
WHERE ((([FACTURACION]![Fecha ALTA]+365)>=Now()));
Esto lee los datos de la tabla Facturación y muestra los registros de quienes no han caducado (fecha de alta +1 año). El problema es que estos datos se presentan siempre de la fisma forma: en el mismo orden y yo quiero que tal cual está la cosa ¿qué hay que añadir y dónde y cómo? Para que cada vez que se ejecute la consulta rote el orden de presentación de los clientes, bv; Jose, Ana, Luis / Ana, Luis, Jose / Luis, Jose, Ana / Jose, Ana, Luis / etc.
Si me puedes decir qué hay que poner pero en el modo diseño de la consulta te lo agradeceré. Si es en el modo SQL pues también.
Un saludo cordialísimo. Y gracias de todas formas.
Con tabla indexada me refería a una tabla sin claves ni índices (cuando la estás diseñando), es decir, una simple tabla sin ningún tipo de ordenación.
Con lo nuevo que me planteas lo siento, pero después de estar casi dos horas tratando de resolver tu problema, no he podido llegar a una solución aceptable. Lo único que te puedo decir es lo siguiente:
Tu problema es muy complejo porque para hacer esa rotación que necesitas, es necesario conocer el número de registros EXACTOS que aparecen en tu consulta. Como los datos en una consulta son cambiantes (en este caso por la condición [FACTURACION]! [Fecha ALTA]+365)>=Now()) es difícil predecir eso.
La única solución que se me ocurre es agregar un campo adicional en tu tabla de "Facturación" que se llame "Orden". Obviamente, mediante ese campo ordenaríamos los registros de tu consulta (order by Orden), por lo tanto necesitamos llenarlo de números que deben cambiar así: 123435, 23451, 34512, etc. y eso arreglaría el problema, pero ¿cómo llenar ese campo?
Lo único que nos puede dar ese comportamiento de números es el operador módulo (MOD):
Por ejemplo, si quieres que tus 5 números se mantengan rotando, debes de usar algo como:
n = n mod 5 + 1
suponiendo que n comienza en 0 (también puede empezar en 5):
n = 0 mod 5 + 1 -> 1
n = 1 mod 5 + 1 -> 2
n = 2 mod 5 + 1 -> 3
n = 3 mod 5 + 1 -> 4
n = 4 mod 5 + 1 -> 5
n = 5 mod 5 + 1 -> 1 <-se repite
n = 1 mod 5 + 1 -> 2
...
Si seguimos repitiendo el proceso de n = n mod 5 + 1, nos mantendremos rotando "circularmente" del 1 al 5, algo similar a lo que necesitas. El problema para meter estos números en el campo "Orden" es que necesitarías sustituir el 5 por el número de registros exactos de tu consulta, y también necesitarías apoyarte de funciones definidas por ti en un módulo, ya que la consulta por si sola no tiene suficientes herramientas para realizar este tipo de ordenamiento.
Ojalá que esta respuesta te dé algunos tips para resolverlo, y si logras encontrar una solución más eficiente.
Con lo nuevo que me planteas lo siento, pero después de estar casi dos horas tratando de resolver tu problema, no he podido llegar a una solución aceptable. Lo único que te puedo decir es lo siguiente:
Tu problema es muy complejo porque para hacer esa rotación que necesitas, es necesario conocer el número de registros EXACTOS que aparecen en tu consulta. Como los datos en una consulta son cambiantes (en este caso por la condición [FACTURACION]! [Fecha ALTA]+365)>=Now()) es difícil predecir eso.
La única solución que se me ocurre es agregar un campo adicional en tu tabla de "Facturación" que se llame "Orden". Obviamente, mediante ese campo ordenaríamos los registros de tu consulta (order by Orden), por lo tanto necesitamos llenarlo de números que deben cambiar así: 123435, 23451, 34512, etc. y eso arreglaría el problema, pero ¿cómo llenar ese campo?
Lo único que nos puede dar ese comportamiento de números es el operador módulo (MOD):
Por ejemplo, si quieres que tus 5 números se mantengan rotando, debes de usar algo como:
n = n mod 5 + 1
suponiendo que n comienza en 0 (también puede empezar en 5):
n = 0 mod 5 + 1 -> 1
n = 1 mod 5 + 1 -> 2
n = 2 mod 5 + 1 -> 3
n = 3 mod 5 + 1 -> 4
n = 4 mod 5 + 1 -> 5
n = 5 mod 5 + 1 -> 1 <-se repite
n = 1 mod 5 + 1 -> 2
...
Si seguimos repitiendo el proceso de n = n mod 5 + 1, nos mantendremos rotando "circularmente" del 1 al 5, algo similar a lo que necesitas. El problema para meter estos números en el campo "Orden" es que necesitarías sustituir el 5 por el número de registros exactos de tu consulta, y también necesitarías apoyarte de funciones definidas por ti en un módulo, ya que la consulta por si sola no tiene suficientes herramientas para realizar este tipo de ordenamiento.
Ojalá que esta respuesta te dé algunos tips para resolverlo, y si logras encontrar una solución más eficiente.
Hola David, sólo te digo una cosa más y te dejo tranquilo.
- Mediante otra consulta diferente:
SELECT Count(Banners!Cliente) AS Cuenta
FROM Banners;
Logro saber cuántos registros hay exactamente en cada momento (según los que no estén caducados), a "tiempo real".
Sabiendo este número, creo que dentro del diseño de la consulta puedes decirle que use esa cantidad (de otra consulta paralela) como número ¿no? Para hacer otras "operaciones" como la de "rotar circularmente" que es lo que yo quiero que se produzca con los N datos que cumplen lo de no estar caducados (según la fecha).
¿Ves qué se pudiera hacer algo más ahora?
MUCHÍSIMAS GRACIAS POR TU TIEMPO; y si logro algo más por otro experto te lo diré.
Un abrazo !
- Mediante otra consulta diferente:
SELECT Count(Banners!Cliente) AS Cuenta
FROM Banners;
Logro saber cuántos registros hay exactamente en cada momento (según los que no estén caducados), a "tiempo real".
Sabiendo este número, creo que dentro del diseño de la consulta puedes decirle que use esa cantidad (de otra consulta paralela) como número ¿no? Para hacer otras "operaciones" como la de "rotar circularmente" que es lo que yo quiero que se produzca con los N datos que cumplen lo de no estar caducados (según la fecha).
¿Ves qué se pudiera hacer algo más ahora?
MUCHÍSIMAS GRACIAS POR TU TIEMPO; y si logro algo más por otro experto te lo diré.
Un abrazo !
Es un gusto poder ayudarte (si está a mi alcance, claro).
Mira, eso ya lo había intentado también (te digo que me pasé casi 2 horas tratando de lograrlo y no pude, jaja :-)
Hice una función (en un módulo) en la que incluí esa consulta select que me estás indicando, y la cual llamaba desde la consulta de las facturas vigentes. La llamé GetLimite. Hice también otra que hacía la operación con el MOD, y la llamé GetNumero. Entonces, desde GetNumero llamaba a GetLimite más o menos así:
function GetNumero(algo) as Integer
Conmutador = Conmutador MOD GetLimite + 1
GetNumero = Conmutador
end function
El argumento "algo" lo puse porque si no se incluye, "por alguna fuerza desconocida de la naturaleza" :-) la función me devolvía siempre el mismo valor. Entonces para evitar eso, la llamaba desde mi campo "orden" en la consulta de facturas vigentes de la siguiente forma:
Orden: GetNumero([Cliente])
Y eso me devolvía los valores diferentes ¡Y girando!
Pero no basta con que giren los números, hay que girarlos bien, para eso guardo el límite en el que empezaron (o sea 1) para incrementarlo después (a 2, y así...), y para hacerlo, llamaba a una función "MoverLimite" justo después de cerrar la consulta, para que la siguiente vez se iniciara la secuencia en el número siguiente. De hecho, puedes usar MOD o un simple contador c = c + 1 para hacer el proceso, la ventaja del MOD es que no tienes que andar cuidando límites con IF y cosas así, sino que la operación por si sola rota perfectamente.
PERO, ¿por qué me rendí? Por una situación que no me gustó nada de Access:
La rotación de los números ocurre bien si la consulta se ejecuta UNA SOLA VEZ, lo cual nos muestra 12345. PERO, la segunda vez que mostraba la consulta, me salían valores así 34512, o a veces se repetía 12345. ¿Cuál fue mi conclusión?: Aunque nosotros vemos a Access mostrar los registros 1 sola vez, en realidad, Access llama varias veces (de forma invisible) a la consulta (para ciertos cálculos supongo) y en realidad las funciones no se ejecutaron sólo una vez por cada registro, sino varias veces, antes de presentar los datos, lo que en consecuencia, muestra los números en una SECUENCIA INCORRECTA.
Pienso que la solución no está en la consulta, sino hacerlo mediante programación de Visual Basic usando DAO, porque ahí sí puedes hacer todos los trucos que quieras, el diseño de consultas limita mucho.
Así que, ni hablar amigo, con este problema no pude jaja, pero no dudo que alguien mejor que yo te pueda ayudar a solucionarlo. Si así fuera, te encargo me compartas la solución
Mira, eso ya lo había intentado también (te digo que me pasé casi 2 horas tratando de lograrlo y no pude, jaja :-)
Hice una función (en un módulo) en la que incluí esa consulta select que me estás indicando, y la cual llamaba desde la consulta de las facturas vigentes. La llamé GetLimite. Hice también otra que hacía la operación con el MOD, y la llamé GetNumero. Entonces, desde GetNumero llamaba a GetLimite más o menos así:
function GetNumero(algo) as Integer
Conmutador = Conmutador MOD GetLimite + 1
GetNumero = Conmutador
end function
El argumento "algo" lo puse porque si no se incluye, "por alguna fuerza desconocida de la naturaleza" :-) la función me devolvía siempre el mismo valor. Entonces para evitar eso, la llamaba desde mi campo "orden" en la consulta de facturas vigentes de la siguiente forma:
Orden: GetNumero([Cliente])
Y eso me devolvía los valores diferentes ¡Y girando!
Pero no basta con que giren los números, hay que girarlos bien, para eso guardo el límite en el que empezaron (o sea 1) para incrementarlo después (a 2, y así...), y para hacerlo, llamaba a una función "MoverLimite" justo después de cerrar la consulta, para que la siguiente vez se iniciara la secuencia en el número siguiente. De hecho, puedes usar MOD o un simple contador c = c + 1 para hacer el proceso, la ventaja del MOD es que no tienes que andar cuidando límites con IF y cosas así, sino que la operación por si sola rota perfectamente.
PERO, ¿por qué me rendí? Por una situación que no me gustó nada de Access:
La rotación de los números ocurre bien si la consulta se ejecuta UNA SOLA VEZ, lo cual nos muestra 12345. PERO, la segunda vez que mostraba la consulta, me salían valores así 34512, o a veces se repetía 12345. ¿Cuál fue mi conclusión?: Aunque nosotros vemos a Access mostrar los registros 1 sola vez, en realidad, Access llama varias veces (de forma invisible) a la consulta (para ciertos cálculos supongo) y en realidad las funciones no se ejecutaron sólo una vez por cada registro, sino varias veces, antes de presentar los datos, lo que en consecuencia, muestra los números en una SECUENCIA INCORRECTA.
Pienso que la solución no está en la consulta, sino hacerlo mediante programación de Visual Basic usando DAO, porque ahí sí puedes hacer todos los trucos que quieras, el diseño de consultas limita mucho.
Así que, ni hablar amigo, con este problema no pude jaja, pero no dudo que alguien mejor que yo te pueda ayudar a solucionarlo. Si así fuera, te encargo me compartas la solución
Hola Davith, de nuevo. Me permito tener el descaro de insistirte y te envío la respuesta de otro experto (julioarango) para ver qué piensas tú, si crees que lo que me contesta me servirá o no y si, leyendo esta respuesta a ver si a ti se te ocurre algo más:
COPIO RESPUESTA DE julioarango:
Lo que quieres, sí se puede, pero con código, no con una expresión. Y por supuesto, tiene su respectivo costo en tiempo de ejecución.
Debes guardar una variable (llamada MARCA, por ejemplo) en disco y que se actualice cada que abras la consulta.
La mencionada consulta debes dividirla en dos.
Así:
rs1 = SELECT * from [tabla] where IdRegistro >= [MARCA]
rs2 = SELECT * from [tabla] where IdRegistro < [MARCA]
El primer recordset guarda los registros iguales o superiores a la marca; el segundo recordset guarda los registros inferiores a la marca; debes mostrar primero el rs1 (en un bucle) y luego el rs2 (en un bucle). Así se obtiene lo que deseas.
Esto que sigue se debe hacer después de abrir el recordset y antes de mostrarlo al usuario. Para actualizar MARCA cada que abras la consulta debes calcular el MAX(IdRegistro) y el MIN(IdRegistro) en las variables MinReg, MaxReg.
with MiRecordset
.movefirst
NuevaMarca = !IdRegistro
If NuevaMarca = MaxReg then
NuevaMarca = MinReg
Else
.MoveNext
If not .Eof then
NuevaMarca = !IdRegistro
End If
End If
MARCA = NuevaMarca 'Guardar en disco
End With
Debes tener en cuenta que ésto se puede volver lento, porque se requiere de tres consultas en vez de una.
¿Crees qué esto sirve o es demasiado rebuscado? ¿Te da esto alguna idea nueva?
Otro abrazo desde España
COPIO RESPUESTA DE julioarango:
Lo que quieres, sí se puede, pero con código, no con una expresión. Y por supuesto, tiene su respectivo costo en tiempo de ejecución.
Debes guardar una variable (llamada MARCA, por ejemplo) en disco y que se actualice cada que abras la consulta.
La mencionada consulta debes dividirla en dos.
Así:
rs1 = SELECT * from [tabla] where IdRegistro >= [MARCA]
rs2 = SELECT * from [tabla] where IdRegistro < [MARCA]
El primer recordset guarda los registros iguales o superiores a la marca; el segundo recordset guarda los registros inferiores a la marca; debes mostrar primero el rs1 (en un bucle) y luego el rs2 (en un bucle). Así se obtiene lo que deseas.
Esto que sigue se debe hacer después de abrir el recordset y antes de mostrarlo al usuario. Para actualizar MARCA cada que abras la consulta debes calcular el MAX(IdRegistro) y el MIN(IdRegistro) en las variables MinReg, MaxReg.
with MiRecordset
.movefirst
NuevaMarca = !IdRegistro
If NuevaMarca = MaxReg then
NuevaMarca = MinReg
Else
.MoveNext
If not .Eof then
NuevaMarca = !IdRegistro
End If
End If
MARCA = NuevaMarca 'Guardar en disco
End With
Debes tener en cuenta que ésto se puede volver lento, porque se requiere de tres consultas en vez de una.
¿Crees qué esto sirve o es demasiado rebuscado? ¿Te da esto alguna idea nueva?
Otro abrazo desde España
Ya resolví tu problema, pero usando Visual basic, créeme, no hay otra forma de hacer esto desde el diseñador de consultas.
Estos serían los pasos para resolver el problema:
1. Crea una variable pública en uno de tus módulos, ella va a controlar el inicio de la numeración:
Public Inicio As Integer
2. Vas a tener que agregar un campo más como te había dicho a tu tabla de Facturación, llamado "Orden".
3. Luego, en el form donde muestras tu consulta de las facturas vigentes, programas el evento "AL abrir (OnLoad)" con este código (sustituye "Consulta" con el nombre de tu consulta, y el campo "Nombre" con un campo que se pueda contar, ejemplo "Cliente"):
Private Sub Form_Open(Cancel As Integer)
Dim db As Database, rs As DAO.Recordset
Dim Total As Integer, Conmutador As Integer
Set db = CurrentDb
'se lee el total de los registros en la consulta
Set rs = CurrentDb.OpenRecordset("select count(Cliente) as Total from [Consulta]")
Total = rs("Total")
rs.Close
'se ajusta el inicio de la numeración
Inicio = Inicio + 1
If Inicio > Total Then Inicio = 1
'se abre la consulta para borrar los números anteriores
Set rs = CurrentDb.OpenRecordset("Consulta")
rs.MoveFirst
Do While Not rs.EOF
rs.Edit
rs("Orden") = 0
rs.Update
rs.MoveNext
Loop
rs.Close
'se vuelve a recorrer la consulta, ahora para poner los números en orden
Set rs = CurrentDb.OpenRecordset("Consulta")
Conmutador = Inicio
rs.MoveFirst
Do While Not rs.EOF
rs.Edit
rs("Orden") = Conmutador
rs.Update
Conmutador = Conmutador Mod Total + 1
rs.MoveNext
Loop
rs.Close
'se le indica al formulario que muestre la consulta ya ordenada
Me.RecordSource = "select * from Consulta order by Orden"
End Sub
Puntos importantes:
1.- Tu consulta en el diseñador de consultas NO debe estar ordenada por el campo "Orden" (se ordena en la última instrucción del código anterior). De hecho si puedes, elimina cualquier ordenación de esa consulta.
2.- Los registros que muestras en tu formulario son en realidad una subconsulta de tu consulta (lo de "Me.Recordsource...").
Si quieres que la numeración comience donde se quedó la última vez que se abrió la BD, entonces guarda el valor de Inicio al salir de Access. No debes preocuparte por el valor inicial de la variable "Inicio", se ajusta automáticamente con la sentencia IF.
EL INCONVENIENTE: La numeración en vez de ir 12345, 23451, etc. va así: 12345, 51234, 45123, 34512, etc., pero creo que es aceptable ¿no? Tal vez se cambie el orden si en el último select ordenas así "order by Orden DESC", pero esto último no lo probé.
Tal como está este código ya lo probé ¡Y si funciona!, así que si también te sirve a ti, entonces creo que me merecí una calificación perfecta ¿no crees? :-)
Ahora sí: TAN, TAN, fue todo lo que pude hacer, ya se me quemó el cerebro jaja :-)
Estos serían los pasos para resolver el problema:
1. Crea una variable pública en uno de tus módulos, ella va a controlar el inicio de la numeración:
Public Inicio As Integer
2. Vas a tener que agregar un campo más como te había dicho a tu tabla de Facturación, llamado "Orden".
3. Luego, en el form donde muestras tu consulta de las facturas vigentes, programas el evento "AL abrir (OnLoad)" con este código (sustituye "Consulta" con el nombre de tu consulta, y el campo "Nombre" con un campo que se pueda contar, ejemplo "Cliente"):
Private Sub Form_Open(Cancel As Integer)
Dim db As Database, rs As DAO.Recordset
Dim Total As Integer, Conmutador As Integer
Set db = CurrentDb
'se lee el total de los registros en la consulta
Set rs = CurrentDb.OpenRecordset("select count(Cliente) as Total from [Consulta]")
Total = rs("Total")
rs.Close
'se ajusta el inicio de la numeración
Inicio = Inicio + 1
If Inicio > Total Then Inicio = 1
'se abre la consulta para borrar los números anteriores
Set rs = CurrentDb.OpenRecordset("Consulta")
rs.MoveFirst
Do While Not rs.EOF
rs.Edit
rs("Orden") = 0
rs.Update
rs.MoveNext
Loop
rs.Close
'se vuelve a recorrer la consulta, ahora para poner los números en orden
Set rs = CurrentDb.OpenRecordset("Consulta")
Conmutador = Inicio
rs.MoveFirst
Do While Not rs.EOF
rs.Edit
rs("Orden") = Conmutador
rs.Update
Conmutador = Conmutador Mod Total + 1
rs.MoveNext
Loop
rs.Close
'se le indica al formulario que muestre la consulta ya ordenada
Me.RecordSource = "select * from Consulta order by Orden"
End Sub
Puntos importantes:
1.- Tu consulta en el diseñador de consultas NO debe estar ordenada por el campo "Orden" (se ordena en la última instrucción del código anterior). De hecho si puedes, elimina cualquier ordenación de esa consulta.
2.- Los registros que muestras en tu formulario son en realidad una subconsulta de tu consulta (lo de "Me.Recordsource...").
Si quieres que la numeración comience donde se quedó la última vez que se abrió la BD, entonces guarda el valor de Inicio al salir de Access. No debes preocuparte por el valor inicial de la variable "Inicio", se ajusta automáticamente con la sentencia IF.
EL INCONVENIENTE: La numeración en vez de ir 12345, 23451, etc. va así: 12345, 51234, 45123, 34512, etc., pero creo que es aceptable ¿no? Tal vez se cambie el orden si en el último select ordenas así "order by Orden DESC", pero esto último no lo probé.
Tal como está este código ya lo probé ¡Y si funciona!, así que si también te sirve a ti, entonces creo que me merecí una calificación perfecta ¿no crees? :-)
Ahora sí: TAN, TAN, fue todo lo que pude hacer, ya se me quemó el cerebro jaja :-)
- Compartir respuesta
- Anónimo
ahora mismo