Individualizar Resta de Fechas Por Identificador

Tengo una bd. Obvio que en ms access y pues confío que me podrán dar una pequeña ayuda, pues mi dilema es que he logrado que me haga la resta entre fechas, por que lo que se requiere de la base de datos es que calcule mes transcurrido en base a mes calendario; ejemplo:

Numero Fecha_Pago Meses_Transcurridos

   B1                                 02/12/2022                              0

   B2                                 28/02/2022                              0

   B1                                 01/03/2023                              3

   B2                                 01/03/2023                              1

¿Por qué es así la estructura si no ha transcurrido un mes en cuenta de días desde Febrero a Marzo?, sencillamente es por que el mes se toma como mes calendario, ésto lo he logrado hacer, y repito ésto lo he logrado hacer, pero lo que no logro hacer es que me los calcule por Id de Número(B1-B2-etc), he logrado que me reste las fechas pero me lo hace corrido en la consulta, ejemplo:

Numero                          Fecha_Pago              Meses_Transcurridos

   B1                                 02/12/2022                              0

   B2                                 28/02/2022                              2

   B1                                 01/03/2023                              1

   B2                                 01/03/2023                              0

Actualmente así es como está acá arriba es como me aparece el calculo y no es eso lo que necesito si no como está en el inicio, reitero ésto es para dar una idea de lo que necesito y lo que me aparece, ésto está creado por dos tablas y una consulta:

1. Tabla que llamaremos Cobros_1 que es donde están los datos generales y que filtra a la hora de seleccionar Ubicación en el formulario de cobro que es similar al de una factura normal hecha en access.

2. Tabla que llamaremos Cobros_2 que tiene los campos que dan vida a la consulta que a su vez da vida al subformulario que es el que contiene los datos del cobro e historial de la ubicación que se esté trabajando:

Si nos damos cuenta A1 tiene unas fechas pero comienza con 8/10/2022 y continúa con 01/01/2023 y vemos que nos marca que solo se registra un que ha transcurrido un mes, pero es por que si nos damos cuenta A2 tiene asignada fecha de pago 10/12/2022 y nos marca que tiene dos meses de retraso, y por eso posteriormente en A1 en la fecha 01/01/2023 nos marca únicamente un mes transcurrido, a continuación para que se comprenda mejor coloco una imagen de la consulta que da "vida" al subformulario:

Si nos damos cuenta acá está mas claro lo que he venido exponiendo, lo que necesito es que las fechas de A1 se calculen únicamente con A1, y las A2 únicamente con A2, si hubiera A3 también con fechas de A3, etc.

Actualmente he logrado que se haga ésta resta con la siguiente expresión:

MesesRetraso: ((Nz(DifFecha("m";[Fecha_Pago];DÚltimo("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "#")))))*-1

3 respuestas

Respuesta
1

Añádele como una condición más, el campo [numero]:

MesesRetraso: ((Nz(DifFecha("m";[Fecha_Pago];DÚltimo("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "# AND Numero = '" & [numero] & "'")))))*-1

¿Por qué no intercambias las fechas? .. Te evitarías multiplicar por (-1) para invertir el resultado

Hace rato estoy queriendo responder pero la página no estaba funcionando bien, te comento que apliqué la corrección a la línea pero me da error, (algo debo de no haber hecho bien), agradezco sobremanera tu buena voluntad.

La expresión puede ser más corta (sobran paréntesis), pero si funcionaba debería continuar funcionando pero esta vez haciendo lo que necesitas.

Lo de cambiar el orden de las fechas (que actualmente te devuelve un negativo) es porque le haces calcular al revés, pones la fecha más alta como primer parámetro y como segundo una fecha más antigua (por eso es menor) y Access espera que el comienzo del periodo a calcular, sea inferior a su final.

Solo se le añade una condición más: que el dato a obtener pertenezca a los del mismo [numero] (sea el A1 o el FF = un texto y por eso se añaden unas comillas simples)

Original:

MesesRetraso: ((Nz(DifFecha("m";[Fecha_Pago];DÚltimo("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "#")))))*-1

Se le añade la segunda condición : que el [numero de lote] del registro en la tabla sea igual al [numero de lote] del registro l registro que esta calculando ==> [numero xx] (el dato en la tabla) = [A1] ( el dato de el primer .. el segundo, el tercero ... el actual).

[Numero_Lote] = "A1" o "A2"  (el del registro en calculo)


Yo condicionaría la función NZ de otra forma:

.- Que devuelva la misma fecha si no existe una fecha anterior que cumpla las condiciones.

[Numero_Lote] se supone que es el campo con los valores 'A1' o 'A2' etc..

Como [Fecha_Pago] es una fecha más reciente que la fecha del ultimo pago (que puede existir o no):

Esta función devuelve la fecha más alta inferior a la de referencia o un NULL

DMax("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "# AND [Numero_lote] = '" & [numero_lote] & "'")

He cambiado Ultima por Mayor, es mas fiel el resultado si las fechas se introdujeron sin orden.

Se le añade la función NZ para que devuelva la fecha de referencia si es un NULL (no se localiza la anterior por ser la primera u otra causa)

NZ(DMax("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "# AND [Numero_lote] = '" & [numero_lote] & "'"); [Fecha_Pago])

Eso nos garantiza que la función DifFecha  recibe dos parámetros de fecha y no da error al calcular. y si es la primera (no hay anterior) o no hay impagos devolverá la misma fecha que busca y por lo tanto cero meses.

Al final queda así:

MesesRetraso: DifFecha("m"; Nz(DMax("Fecha_Pago";"Cobros__2";"Fecha_Pago <#" & [Fecha_Pago] & "# AND [Numero_lote] = '" & [numero_lote] & "'") ; [Fecha_Pago]); [Fecha_Pago])

Te corresponde a ti (con los datos reales) verificar si los nombres de los campos son los correctos.

Bendiciones, vengo para agradecer sobremanera la ayuda que me diste por que lo logré hacer trabajar, yo estaba fallando con no poner unas comillas y ahora anda 100%, aunque en adelante estaré fastidiando como con dos procesos mas pero estaré trabajando en ello para solo venir a darle "el remate final".

Veo que obtienes resultados parciales (filtrando por [numero_lote])
Asumo que estabas en la creencia de que este filtro actuaria por defecto en la función de dominio. Y por eso no funcionaba (independiente de la falta de las comillas que seria un error diferente).

Respuesta
1

Honestamente, me he perdido. Si tengo la tabla Tabla1 y con ella hago un formulario, lo pongo continuo que se ve mejor. A medida que voy rellenando, me tiene en cuenta el número

Lo que no sé es si quieres que la diferencia en meses sea independiente de la fecha, es decir, que sólo tenga en cuenta el número del mes, no la diferencia en días traducida a meses.

En este caso en particular, en el evento Después de actualizar del control FechaPago le tengo puesto

Private Sub FechaPago_AfterUpdate()
DoCmd.RunCommand acCmdSaveRecord
If Nz(DLast("fechapago", "tabla1", "numero='" & Me.Numero & "' and difmeses is not null")) = 0 Then
DifMeses = 0
Else
DifMeses = DateDiff("m", Nz(DLast("fechapago", "tabla1", "numero='" & Me.Numero & "' and difmeses is not null")), FechaPago)
End If
End Sub

Muy amable gracias  por tomarte el tiempo, tu solución se ve mas elegante de lo que yo hice, aún me cuesta  con el código vba, acabo de aplicar la solución y no me produce nada, me queda totalmente igual el resultado (supongo que algo debo de estar haciendo mal), agradezco la paciencia y la ayuda muy amable.

Lo único que puedo hacer es que si quieres, repito, si quieres, mándame un mensaje ( sólo el mensaje) a [email protected] y te mando un ejemplo.

Si lo haces, en el asunto del mensaje pon tu alias Arm Mando, ya que si no sé quien me escribe ni los abro.

Respuesta
1

Espero haber entendido

Tengo esta tabla

Copie este script en a cuadricula de diseño de consulta

SELECT t1.Numero, t1.Fecha_Pago, IIf((SELECT Count(*) FROM tblPagos AS t2 WHERE t2.Numero = t1.Numero AND t2.Fecha_Pago <= t1.Fecha_Pago)=1,0,-1*DateDiff("m",t1.Fecha_Pago,(SELECT Max(t2.Fecha_Pago) FROM tblPagos AS t2 WHERE t2.Numero = t1.Numero AND t2.Fecha_Pago < t1.Fecha_Pago))) AS Meses_Transcurridos
FROM tblPagos AS t1
ORDER BY t1.Numero, t1.Fecha_Pago;

Ejecuto la consulta y obtengo

Ahora si solo quiere agrupar por numero este script le sirve

SELECT t1.Numero, t1.Fecha_Pago, -1*DateDiff("m",t1.Fecha_Pago,(SELECT MAX(Fecha_Pago) 
        FROM tblPagos AS t2 
        WHERE t2.Numero = t1.Numero 
        AND t2.Fecha_Pago < t1.Fecha_Pago)) AS Meses_Transcurridos
FROM tblPagos AS t1
WHERE (((t1.Fecha_Pago)=(SELECT MAX(Fecha_Pago) FROM tblPagos WHERE Numero = t1.Numero)));

Obtendrá algo como

Esto sería lo más práctico para controlar pagos.

Muy amable y gracias por tomarse el tiempo en responder, intentaré aplicar la solución aunque hago la salvedad que me tropiezo con el código vba, lo que quiero hacer es que las fechas de cada usuario se calculen con las fechas de cada respectivo usuario.

Si quiere envíeme a [email protected] su base datos con información ficticia y trato de colaborarle.

Hola y bendiciones, creo que le envié desde (la web del programador) pero no se si llegó o el servidor dio problema, pero lo enviaré, gracias de verdad por la buena disposición a ayudar.

Le envíe la base de datos editada a su correo.

Le dejo la imagen como quedaría el formulario

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas