VBA Access: Sumar 1 a 'y' tras contar 10 en 'x'

PRIMERO:
Tengo tres campos que deben aumentar su valor en 1 por cada vez que se genere un registro.
Con fines prácticos, los campos serán X, Y, Z. Y los valores deben ir del 0 al 9.
Todos inician en '0' (cero) pero deberá sumar '1' al valor anterior en 'Z'. Cuando 'Z' llegue a '9', deberá volver a '0' y sumar '1' al último valor de 'Y'. Lo mismo sucederá cuando 'Y' llegue a '9':  sumará '1' a 'X'. Pero, contrario al resto, 'X' no tendrá límite máximo por lo que podrá llegar a un número de 4 cifras si fuera necesario.

SEGUNDO:
Otro detalle que podría ser necesario (aunque dependerá de cuán comlicado se me ponga, es que a 'X' y 'Z' podré ponerle un valor manualmente y el siguiente registro deberá sumar 1 a este valor, a la vez que si el valor es '0', deberá sumarse '1' a 'X' o 'Y' según corresponda.
Por el momento lo que más me interesa es PRIMERO. Si se puede hacer SEGUNDO a la par, mejor.

2 respuestas

Respuesta
2

Te he preparado un mini-ejemplo, que puedes descargar aquí: http://www.filebig.net/files/JM5vAV77Nu 

El código va comentado, para que sepas lo que se va haciendo. Ten en cuenta que para que el sistema funcione, has de tener obligatoriamente un campo que ordene secuencialmente los registros (en el ejemplo el ID autonumérico)

Saludos!


He adaptado el código a mi Base de Datos. El código quedó así:

If Not Me.NewRecord Then Exit Sub 'Si no es un registro nuevo, no haces nada
If IsNull(DMax("FASE", "VERSION")) Then 'Si aún no hay registros, inicias en 0
    Me.MAYOR = 0
    Me.MENOR = 0
    Me.MICRO = 0
Else 'Si ya hay registros buscas los valores de MICRO, MENOR, MAYOR del último ID
    ultMi = DLookup("MICRO", "VERSION", "MICRO=" & DMax("MICRO", "VERSION"))
    ultMe = DLookup("MENOR", "VERSION", "MENOR=" & DMax("MENOR", "VERSION"))
    ultMa = DLookup("MAYOR", "VERSION", "MAYOR=" & DMax("MAYOR", "VERSION"))
    'Para MICRO:
    If ultMi < 9 Then ' Si es menor que 9, sumas 1
        Me.MICRO = ultMi + 1
    Else ' Si es 9, vuelves a 0 y añades 1 a ultMe
        Me.MICRO = 0
        ultMi = ultMe + 1
    End If
    'Para MENOR:
    If ultMe = 10 Then ' Si es  10, vuelves a 0 y sumas 1 a ultMa
        Me.MENOR = 0
        ultMa = ultMa + 1
    Else ' Si no, dejas como está
        Me.MENOR = ultMe
    End If
    'Para MAYOR:
    Me.MAYOR = ultMa
End If

Los valores quedan bien, PERO, viniendo de un valor:
MAYOR 1.
MENOR 9.
MICRO 2.
Da valor (y siempre vuelve a) 0 a MICRO y debería ser 3. ¿Qué hice mal?
Lo he revisado y no encuentro el error.

Tienes mal esta línea:

 ultMi = ultMe + 1

que debería ser:

 ultMi = ultMi + 1

¿no?

He probado, pero vuelve a 0 MICRO, mero no aumenta a MENOR.
La corrección que me has pasado me hizo ver el verdadero error (y que le di vuelva al código pero no llegué al causal hasta tu corrección y en realidad es:

ultMe = ultMe + 1

Así que comparto el código final, corregido, funcional para quien le sirva de ayuda:

Private Sub Form_Current()
Dim ultMa As Integer, ultMe As Byte, ultMi As Byte
If Not Me.NewRecord Then Exit Sub 'Si no es un registro nuevo, no haces nada
If IsNull(DMax("FASE", "VERSION")) Then 'Si aún no hay registros, inicias en 0
    Me.MAYOR = 0
    Me.MENOR = 0
    Me.MICRO = 0
Else 'Si ya hay registros buscas los valores de MICRO, MENOR, MAYOR del último ID
    ultMi = DLookup("MICRO", "VERSION", "MICRO=" & DMax("MICRO", "VERSION"))
    ultMe = DLookup("MENOR", "VERSION", "MENOR=" & DMax("MENOR", "VERSION"))
    ultMa = DLookup("MAYOR", "VERSION", "MAYOR=" & DMax("MAYOR", "VERSION"))
    'Para MICRO:
    If ultMi < 9 Then ' Si es menor que 9, sumas 1
        Me.MICRO = ultMi + 1
    Else ' Si es 9, vuelves a 0 y añades 1 a ultMe
        Me.MICRO = 0
        ultMe = ultMe + 1
    End If
    'Para MENOR:
    If ultMe = 10 Then ' Si es  10, vuelves a 0 y sumas 1 a ultMa
        Me.MENOR = 0
        ultMa = ultMa + 1
    Else ' Si no, dejas como está
        Me.MENOR = ultMe
    End If
    'Para MAYOR:
    Me.MAYOR = ultMa
End If
End Sub

¡Y TE DOY INFINITAS GRACIAS! Siempre eficiente y completo. EL mundo necesita más Sveinbjorns.

FE DE ERRATAS:
He vuelto a probar y ahora se reinicia todo a 0 y suma 1 a MAYOR solamente. Y Access deja de funcionar. Hay un detalle que quiero saber:

DLookup("MICRO", "VERSION", "MICRO=" & DMax("MICRO", "VERSION"))

¿Busca el último valor máximo? Porque si busca sólo el máximo, siempre será 9, pero el último no siempre es 9.
NOTA: Aclaro que recuperé de un BackUp y vuelvo a cargar el código que yo pegué por lo tanto lo que hice con el código de Jacinto no lo incluyo y lo mismo se cierra Access. Aclaro también que es cuando se ejecuta la Macro AutoExec iniciando todas las consultas entre las que está la que obtiene el último registro generado en la tabla que incluye esto que añado. ¿Está bien el código resultante?

Otro detalle, que eso me doy cuenta que no aclaré porque ahora caigo en la cuenta de la necesidad:

  • para que MAYOR sume 1, tienen que haber pasado 10 veces del 0 al 9 en MICRO.
  • Al llegar a la 101 vez, sume 1 a MENOR.
  • 0 al 9 en MENOR para sumar 1 a MAYOR.

En definitiva, generar números del 1 al 'x00' en tres campos por separado (siendo 'x' un número que irá aumentando de 100 en 100.
¿Sería conveniente incluir el código en cada campo indicando lo que dependa del valor anterior?
Es decir:

  • En MICRO sumar 1 al valor anterior. Al llegar a 9 + 1 vuelva a 0 y sume 1 a MENOR.
  • En MENOR esperar a que llegue a 9 y al ser 9+1 vuelva a 0 y sume 1 a MAYOR.
  • Y MAYOR quede así

Si es factible, ¿cómo sería el código más práctico? Si hay otra posibilidad, ¿cómo es el código?

Por partes,

Veo que o no has entendido o no has hecho caso a mi comentario

Ten en cuenta que para que el sistema funcione, has de tener obligatoriamente un campo que ordene secuencialmente los registros (en el ejemplo el ID autonumérico)

Por el código que pones, entiendo que ese campo debe ser "FASE".

Pregunta:

DLookup("MICRO", "VERSION", "MICRO=" & DMax("MICRO", "VERSION"))

¿Busca el último valor máximo? Porque si busca sólo el máximo, siempre será 9, pero el último no siempre es 9.

Respuesta:

Sí y no, DLookUp busca el valor de "MICRO" que corresponde al máximo de "MICRO", lo cual es un sinsentido hacerlo así, pues sólo con el DMax obtienes el mismo valor.

Si lo pones en relación con el comentario anterior, entiendo que el código tendría que ser:

DLookup("MICRO", "VERSION", "MICRO=" & DMax("FASE", "VERSION"))

En cuanto a tu última pregunta, el código mío ya lo hace (si entendí bien lo que quieres), fíjate bien. Y Si corriges el tuyo, entiendo que también.

La tabla no tiene ni debe tener un campo autonumérico porque me complica mucho cuando cargo datos pues siempre queda uno desfasado cuando cancelo la acción si no necesito. El campo de ordenación es el campo FECHA. Y siendo así no me genera bien los registros.

Aclaro: Los valores se generan de uno en uno acorde a la fecha, a menos que por algún motivo se vuelva a desordenar y yo no lo sepa. En las propiedades de tabla establecí FECHA por lo que siempre deberá ordenarse acorde a eso. Y el formato es fecha hora por lo que si hay dos registros en una misma fecha, siguen siendo secuenciales. Y no ha funcionado. He vuelto a probar ahora y Access vuelve a fallar.
Añadí el campo ID, lo ordené por tal y sigue dando 200 (MAYOR, MENOR, MICRO) y debería ser 193.

Y digo yo, ¿qué problema tienes en tener un campo autonumérico aunque tengas saltos en los números? Si para lo único que te sirve es para ordenar los registros secuencialmente y poder aplicar el código tal cual te lo proporcioné yo.

Dicho esto, si tienes un campo fecha/hora, el funcionamiento debería ser el mismo, pero obviamente has de adaptar la sintaxis del DLookUp a un valor de tipo fecha, es decir, has de añadirle las almohadillas, por ejemplo, si el campo es FECHA:

DLookup("MICRO", "VERSION", "FECHA=#" & DMax("FECHA", "VERSION") & "#")
Respuesta
1

Sasha: Así sin darle muchas vueltas y para el primer caso, debes programar dos eventos.

Uno.- En el Form_Current

Dos.- En el AfterUpdate de Z

Private Sub Form_Current()
If Me.Z = 9 Then
Me.Y = Me.Y+1
Me.Z = 0
End If
End Sub
'Y para el AfterUpdate de Z, el Mismo código

Creo haber interpretado bien tu idea y si no es así me comentas. Mis saludos >> Jacinto

¡Gracias!
No lo usé exactamente así, pero el código me sirve para eventuales correcciones manuales de los valores para reiniciar o aumentar los demás de acuerdo al valor que ingresé. El código me da vergüenza copartirlo porque quedó un embrollo de código que mejor olvidar. Pero me sirvió para algo más. Muchas gracias a los dos.

Perdón, Jacinto: Creo que lo que hice no funcionó como esperaba y tuve que quitarlo.
Ahora, como escribí a Svein, no fui claro en la necesidad final:

  • Para que MAYOR sume 1, tienen que haber pasado 10 veces del 0 al 9 en MICRO.
  • Al llegar a la 101 vez, sume 1 a MENOR.
  • 0 al 9 en MENOR para sumar 1 a MAYOR.

En definitiva, generar números del 1 al 'x00' en tres campos por separado (siendo 'x' un número que irá aumentando de 100 en 100.
¿Sería conveniente incluir el código en cada campo indicando lo que dependa del valor anterior?
Es decir:

  • En MICRO sumar 1 al valor anterior. Al llegar a 9 + 1 vuelva a 0 y sume 1 a MENOR.
  • En MENOR esperar a que llegue a 9 y al ser 9+1 vuelva a 0 y sume 1 a MAYOR.
  • Y MAYOR quede así

Si es factible, ¿cómo sería el código más práctico? Si hay otra posibilidad, ¿cómo es el código? Juro que di tantas vueltas al tema que no logro pensar en nada.

Sasha: La verdad es que con ésta segunda explicación tampoco consigo ver con claridad tu necesidad.

Me he bajado el Ejemplo de Sveinbjorn y si tomo la última parte de tu explicación>>

Es decir:

  • En MICRO sumar 1 al valor anterior. Al llegar a 9 + 1 vuelva a 0 y sume 1 a MENOR.
  • En MENOR esperar a que llegue a 9 y al ser 9+1 vuelva a 0 y sume 1 a MAYOR.
  • Y MAYOR quede así

He ido pasando registros y veo que hace exactamente eso, si tengo en cuenta que:

Micro = Z

Menor = Y

Mayor = X

No te preocupes por insistir si es que en mi caso confundo la idea.

Estoy seguro que Sveinbjorn, partiendo de lo ya hecho puede contestarte.

Mis saludos >> Jacinto

La pregunta no admite más respuestas

Más respuestas relacionadas