¿Que opción de planteo es mejor en access para esto?

Tengo un tabla de pedidos y otra de detalle de pedidos relacionada.

En la tabla de pedidos hay un campo que es "Fecha de vencimiento de pago" y otro "Fecha de pago realizado"

La cuestion es que dentro del formulario de pedido tengo que generar un campo que calcule intereses. La formula para eso la tengo por medio de codigo. Pero la pregunta es la siguiente:

1. Me conviene crear un campo "intereses" en la tabla pedidos para que se vaya guardando la informacion de los intereses que se van generando dia a dia.

2. Me conviene en el formulario de pedido tener un campo que se llame "Intereses" pero que sea independiente y al cargar el formulario o actualizar se ejecute ese codigo y aparezcan los intereses (pero no se guarden en ningun lado, sea un calculo continuo)

3. Hacer una consulta sobre la tabla pedidos y agregar en la consulta una expresion en un campo nuevo que haga este calculo (El problema de esto es que no puedo usar el codigo visual basic en el generador de expresiones, ¿verdad?

La finalidad es que este numero de intereses voy a necesitar que se muestre en el formulario de pedido, y en varios informes. Mi duda surgio cuando estaba armando un informe, como hacer para que aparezca ya que lo tenia el dato en una tabla y al abrir el informe no se actualizaba. Pense en hacer el campo calculado solo para el informe, y luego me surgio si lo hago directo en la consulta, pero creo q deberia ser sin codigo visual basic.

1 respuesta

Respuesta
1

Te comento cómo lo haría yo, que no es ni la mejor ni la peor manera (todo según gustos). Yo optaría por la tercera opción que comentas, la de la consulta, así te evitas tener que guardar esa información variable en un campo de una tabla que posiblemente tengas que estar actualizando, y además esa consulta te sirve como base para los formularios e informes que necesites, sin tener que andar añadiendo campos calculados a cada uno de ellos.

Sí puedes usar una función escrita en código VBA en una consulta. Para ello, tienes que declararla como pública y como función (Public Function) y no como procedimiento (Public Sub). Además, tendrás que definirle los argumentos (los campos necesarios para el cálculo) y el tipo de datos que devuelve.

Por ejemplo: una función que calcule la media de tres números:

Public fncMedia(X1 as Integer, X2 as Integer, X3 as integer) as Double

fncMedia=(X1+X2+X3)/3

End Function

Es decir, una función que coge los 3 valores enteros que le pasas, y devuelve su media, que es de tipo doble.

Para usarla en la consulta, si los campos de la tabla se llaman Campo1, Campo2 y Campo3, sería:

Media: fncMedia([Campo1];[CAmpo2];[Campo3])

Si pones la fórmula que usas para tu cálculo, y los nombres de los campos, te puedo ayudar a convertirla a una función que puedas usar.

Gracias me va quedando claro! No creo que para lo que vaya a hacer que es muy simple me haga falta una función fija.
Más que nada tal vez lo decía por la función si.. pero si no queda otra la hago con el creador de expresiones del diseño de consulta. Este es el código:

If Not IsNull([Fecha de vencimiento de pago cliente]) And [Fecha de vencimiento de pago cliente] < Date Then

[Estado pago cliente] = "Pago vencido. Se generan intereses"
[dias mora pago cliente] = DateDiff("d", [Fecha de vencimiento de pago cliente], Date)
[Intereses mora clientes] = [Monto de pago cliente] * 0.1 / 365 * [dias mora pago cliente]
End If


If Not IsNull([Fecha de pago realizado cliente]) Then
[dias mora pago cliente] = DateDiff("d", [Fecha de vencimiento de pago cliente], [Fecha de pago realizado cliente])
[Intereses mora clientes] = [Monto de pago cliente] * 0.1 / 365 * [dias mora pago cliente]
[Estado pago cliente] = "Pagado"
End If
Y para los "Estados" que van variando recomiendas lo mismo? Porque segun varios "if" de las distintas fechas va cambiado el campo de texto estado: "Pendiente de pago", o "Vencido", o "Pagado". Hoy en tengo el codigo IF en el formulario donde se completan los datos pero luego tengo que tomar este campo "estado" en formularios y si paso un tiempo de un mes, y una orden se vencio, pero nadie entro en el formulario y entran directo en un informe sobre los "estados" de las ordenes, no van a verlo actualizado, porque el codigo de actualizacion figura al entrar al formulario de ordenes. 
¿Lo mejor para esto es siempre que estén en consultas estos campos? ¿Y hacer los condicionales por el diseño de consulta? Para que estén siempre actualizados digo...
Desde ya gracias por todo!

Realize esta expresion en un nuevo campo en la consulta llamado "dias de mora pago cliente", la cual funciona bien, pero no me agrada jeje, me gusta usar el codigo vba, me parece mas prolijo y mas versatil. Me parece como rebuscado tener que hacerlo así:
Dias mora pago cliente: SiInm(NoEs EsNulo([Fecha de vencimiento de pago cliente]) Y NoEs EsNulo([Fecha de pago realizado cliente]) Y [Fecha de vencimiento de pago cliente]<[Fecha de pago realizado cliente],DifFecha("d",[Fecha de vencimiento de pago cliente],[Fecha de pago realizado cliente]),SiInm(NoEs EsNulo([Fecha de vencimiento de pago cliente]) Y EsNulo([Fecha de pago realizado cliente]) Y [Fecha de vencimiento de pago cliente]<Fecha(),DifFecha("d",[Fecha de vencimiento de pago cliente],Fecha()),"0"))

En tu caso concreto, si lo quieres hacer todo por funciones VBA, necesitas no una, sino tres funciones distintas:

Una que te devuelva el estado

Otra que te devuelva los días de mora

Y otra que te calcule el importe del interés de demora.

Una forma de hacerlo sería troceando el código que pones, obteniendo una función para cada valor dentro de los Ifs.

Yo lo hice así, en un módulo independiente:

Public Function fncEstado(laFVto As Date, laFPago As Date) As String
'Si no hay fecha de vencimiento, se deja en blanco
If laFVto = -3.14 Then
    fncEstado = ""
    Exit Function
End If
'Analizamos la fecha de pago y la de vencimiento
Select Case laFPago
    Case -3.14 'No hay fecha de pago
        If laFVto < Date Then 'Si la fecha de vencimiento es menor que la actual
            fncEstado = "Pago vencido. Se generan intereses"
        End If
    Case Else 'Si hay fecha de pago
        If laFPago <= laFVto Then 'Si la fecha de pago es menor o igual que la de vencimiento
            fncEstado = "Pagado"
        Else
            fncEstado = "Pagado con retraso. Se generan intereses"
        End If
End Select
End Function
Public Function fncDiasMora(laFVto As Date, laFPago As Date) As Integer
'Si no hay fecha de vencimiento, se deja en blanco
If laFVto = -3.14 Then Exit Function
'Analizamos la fecha de pago y la de vencimiento
Select Case laFPago
    Case -3.14 'No hay fecha de pago
        If laFVto < Date Then 'Si la fecha de vencimiento es menor que la actual
            fncDiasMora = DateDiff("d", laFVto, Date)
        End If
    Case Else 'Si hay fecha de pago
        If laFPago > laFVto Then 'Si la fecha de pago es menor o igual que la de vencimiento
            fncDiasMora = DateDiff("d", laFVto, laFPago)
        End If
End Select
End Function
Public Function fncInteresMora(elMonto As Currency, losDiasMora As Integer) As Currency
If losDiasMora > 0 Then ' Si hay dias de mora se calculan los intereses
    fncInteresMora = elMonto * 0.1 / 365 * losDiasMora
End If
End Function

Como verás, a las dos primeras funciones les paso como argumentos la fecha de vencimiento y la de pago, y a la tercera, el monto y los días de mora.

En la consulta, las uso así:

Estado: fncEstado(Nz([FVto];-3,14);Nz([FPago];-3,14))

Dias Mora: fncDiasMora(Nz([FVto];-3,14);Nz([FPago];-3,14))

InteresMora: fncInteresMora([Monto];[Dias Mora])

Fíjate que uso la función Nz con las fechas por si no hay alguna, asignarles un valor improbable (-3.14, que se corresponde a la fecha 27/12/1899) y no de error la función.

Te adjunto un mini ejemplo para mayor claridad: BD

¡Gracias!  

Me funciono excelente!!

Una consulta sencilla:
Es igual en vez de poner: -3.14 (por si la fecha es nula), usar el comando:
If IsNull(Fecha) And I Then
fncEstado = "X"
¿Por que usas el valor -3.14 en vez de usar el valor IsNull ?

La uso por costumbre (la función Nz), porque con cuadros de texto que almacenan valores texto, si tienen algun valor y lo borras, lo que contiene el cuadro no es un Nulo, sino una cadena vacía ("") y la función IsNull ya no funciona.

Es lo mismo hacer esta comprobación: If Isnull(Campo) Or Campo=""

que esta otra: If Nz(Campo,"")=""

En cuanto al por qué del -3.14, es por darle un valor arbitrario, pues la fecha y hora que se corresponde a -3,14 es esta: 27/12/1899 3:21:36, que evidentemente es que algo falla.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas