Access: Formulario para facturar albaranes

Tengo diseñado un formulario independiente para facturar albaranes emitidos. Introduzco la fecha, automáticamente me da el nº de factura, incluyo el Id del cliente y me lista los albaranes pendientes de facturar de ese cliente. Los selecciono, y me calcula el total factura, IVA,,, Luego elijo el tipo de vencimiento y pulsando el botón "Facturar" rellena los datos correspondientes en las distintas tablas:

  • En la tabla Albaranes marca los albaranes como facturados y rellena los campos identificativos de la factura para luego poder enlazar las tablas
  • En la tabla Facturas crea la factura con sus campos correspondientes
  • En la tabla Vencimientos lo mismo

El problema me surge con los vencimientos. Tengo distintos tipos de vencimientos definidos como tipo, por ejemplo, Transferencia que sería un sólo vencimiento del 100% de la factura en la fecha factura, Transferencia0, 30 que serían dos vencimientos, uno a 0 días de la fecha factura del 50% y otro al de 30 días de la fecha factura del 50%, Transferencia0, 30,60 que serían tres vencimiento... Estos cálculos los pone en un subformulario continuo (porque puede haber más de un registro por factura) que calcula los importes de cada vencimiento en función de los vencimientos tipos establecidos en la tabla "Tipos de vencimiento".

El problema es que cuando me calcula el % de cada vencimiento, no siempre es divisible exactamente y al redondear a dos decimales, resulta que la suma de los vencimientos no cuadra con el total de factura por 1 céntimo. Por ejemplo, una factura de 115,25 € a dos vencimientos me calcula dos vencimientos de 57,63€, es decir la suma de los vencimientos es 115,26€.

Se os ocurre alguna idea.

2 respuestas

Respuesta
2

Yo lo que hago es ajustar siempre el céntimo del último plazo.

Por ejemplo, si el pago son 1000€ en tres plazos, las cuotas serían: 1º 333,33 €, 2º 333,33 € y 3º 333,34 €

La forma de ajustar es una simple suma y resta: cuotaN=Total-cuota1-cuota2...-cuota(N-1)

Saludos.


En efecto esa es la solución matemática correcta, mi problema es programarla en base a mis conocimientos. Mi planteamiento es el siguiente:

  • Los vencimientos los tengo definidos e la tabla "Vencimientos _Forma_Pago" , en la cual tengo definidos los siguientes campos: Id_Forma_Pago, Forma de pago, Plazo (meses de desfase respecto a fecha factura), Cuantia. Por ejemplo, la forma de pago "Transferencia a 0, 30 y 60 días" tendría los siguientes registros (3 por tener 3 plazos de pago)  TR0,30,60, Transferencia, 0, 33,33%, TR0,30,60, Transferencia, 1, 33,33%, TR0,30,60, Transferencia, 2, 33,33%
  • Al ser un formulario independiente, he creado una tabla "Temporal-Vencimientos_Factura_Emitidas", para luego poder acceder a los registros y hacer el ajuste final.
  • Para anexar los registros a la tabla temporal, intenté crear una consulta de datos anexados, pero no me funcionó, por lo hice una consulta de selección para hacer los cálculos intermedios y una consulta de datos anexados para finalmente traspasar los cálculos a la tabla temporal. La consulta de selección, en SQL es:

SELECT Vencimientos_Forma_Pago.Id_Forma_Pago, Vencimientos_Forma_Pago.[Forma de pago], Vencimientos_Forma_Pago.Plazo, [Forms]![Formulario Ventas-Ingresos]![Fecha_Factura] AS Fecha_Factura, Vencimientos_Forma_Pago.Cuantia, DateAdd("m",[plazo],[Fecha_Factura]) AS Fecha_Vencimiento, Round([Forms]![Formulario Ventas-Ingresos]![Total_Factura]*[Cuantia],2) AS Importe_Vencimiento
FROM Vencimientos_Forma_Pago
WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)=[Forms]![Formulario Ventas-Ingresos]![Forma de pago]));

  • A continuación, ejecuto desde código la siguiente instrucción:

CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ( [Forma de pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT ConsultaTemporal_Vencimientos_FacturaEmitida.[Forma de pago], ConsultaTemporal_Vencimientos_FacturaEmitida.Fecha_Vencimiento, ConsultaTemporal_Vencimientos_FacturaEmitida.Importe_Vencimiento FROM ConsultaTemporal_Vencimientos_FacturaEmitida;"

Pero me error (si lo hago manualmente desde consultas no me da error, pero al pasarlo a código me da error: "Se ha producido el error "3061" en tiempo de ejecución: Pocos párametros. Se esperaba 3"

Estoy perdido, no entiendo el Error.

He modificado el código, agrupando en una consulta de datos anexados, eliminando la consulta de selección intermedia:

Var_TipoCobro = Me![Forma de pago]
Var_N_Vencimientos = DCount("[Plazo]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Mi_FechaFactura = Me![Fecha_Factura]
MiAño = Me![Año_Factura]
MiSerieFactura = Me![SerieFactura]
N_Factura = Me![N_Factura]
MiFormaPago = DLookup("[Forma de Pago]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Var_TotalFactura = Me![Total_Factura]
CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ([Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT Vencimientos_Forma_Pago.[Forma de pago], DateAdd(m,[plazo],#" & Mi_FechaFactura & "#) AS Fecha_Vencimiento, Round(" & Var_TotalFactura & "*[Cuantia],2) AS Importe_Vencimiento FROM Vencimientos_Forma_Pago WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)='" & MiFormaPago & "'));"

El error que me da ahora es. "Se ha producido el error '3075' en tiempo de ejecución: Se utilizó un número incorrecto de argumentos con la función en la expresión de consulta 'Round(278,65*[Cuantia],2'.

Me da la sensación que el problema viene de la "," del decimal, que lo toma como una separación de argumentos. ¿Como puedo pasar el número a formato decimal con "."?

El problema del round es que tu multiplicación contiene decimales y "se hace un lío" con la coma decimal del número y la coma separadora de los argumentos. Puedes usar la función Str() para convertir ese producto en cadena de texto o usar Replace() para cambiar la coma por un punto:

Round(Str(" & Var_TotalFactura & "*[Cuantia]),2)

o

Round(Replace(" & Var_TotalFactura & "*[Cuantia],',','.'),2)

Para hacer el ajuste puedes hacerlo así (con los nombre que tu tengas):

Cuota3=Total-Nz(Cuota1,0)-Nz(Cuota2,0)

He seguido tu consejo, pero ahora me da error 3061 en tiempo de ejecución: Pocos parámetros. Se esperaba 1

Por tanto, algo más me falla

¿Qué has puesto, exactamente?

¿Es posible que el error esré en la función Dateadd?

¿En qué línea te marca el error?

En la línea de la consulta: CurrentDb.execute...

No veo nada raro, pero tampoco me dices los cambios que has hecho...

La mejor forma de saber si te construye bien la SQL es cambiar el CurrentDb. Execute por Debug. Print, y mirar en la ventana inmediato si hay algo que "chirríe". Tmabien puedes coger esa SQL de la ventana inmediato y llevarla al editor de consultas: te indicará si hay algún error con alguna expresión, sintaxis...

La verdad es que, la sql la he sacado del diseñador de consultas, he hecho la consulta a través del diseñador y probado que funciona. Luego, la he sacado de la vista sql, pegado en el código y cambiado los campos por nombres de variables

Insisto, ¿probaste la que te genera el código en el diseñador de consultas?

Si quieres pega aquí la SQL resultante para intentar verle algún fallo

Gracias por tu ayuda, te pego la sql:

INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ( [Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento )
SELECT Vencimientos_Forma_Pago.[Forma de pago], DateAdd("m",[plazo],[Forms]![Formulario Ventas-Ingresos]![Fecha_Factura]) AS Fecha_Vencimiento, Round([Forms]![Formulario Ventas-Ingresos]![Total_Factura]*[Cuantia],2) AS Importe_Vencimiento
FROM Vencimientos_Forma_Pago
WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)=[Forms]![Formulario Ventas-Ingresos]![Forma de pago]));

Está probada y funciona.

Te pego el código, he creado variables para sustituir los nombres de campos e la sql, he comprobado paso a paso que toma bien los valores de las variables:

Var_TipoCobro = Me![Forma de pago]
Var_N_Vencimientos = DCount("[Plazo]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Mi_FechaFactura = Me![Fecha_Factura]
MiAño = Me![Año_Factura]
MiSerieFactura = Me![SerieFactura]
N_Factura = Me![N_Factura]
MiFormaPago = DLookup("[Forma de Pago]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Var_TotalFactura = Me![Total_Factura]
'CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ([Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT Vencimientos_Forma_Pago.[Forma de pago], DateAdd(m,[plazo],#" & Mi_FechaFactura & "#) AS Fecha_Vencimiento, Round(" & CambiaDecimal(Var_TotalFactura) & "*[Cuantia],2) AS Importe_Vencimiento FROM Vencimientos_Forma_Pago WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)='" & MiFormaPago & "'));"
CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ([Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT Vencimientos_Forma_Pago.[Forma de pago], DateAdd(m,[plazo],#" & Mi_FechaFactura & "#) AS Fecha_Vencimiento, Round(Replace(" & Var_TotalFactura & "*[Cuantia],',','.'),2) AS Importe_Vencimiento FROM Vencimientos_Forma_Pago WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)='" & MiFormaPago & "'));"

Solo veo rara una cosa en la sintaxis, y es que si el campo por el que filtras (Id_forma_pago) es numérico, te sobran las comillas simples que le pones al encadenarle la variable MiFormaPago. Lo mismo en el dlookup con el que le das valor a esa variable.

Si piensas que el error está en el dateadd, prueba formateando la fecha "a la americana":

DateAdd(m,[plazo],#" & Format(Mi_FechaFactura,"mm/dd/yyyy") & "#)

También me parece raro que te de ese error de pocos parámetros ¿comprobaste que MiformaPago no sea nulo?

Insisto, estaría bien que comprobases que la SQL que te genera tu código VBA es correcta, imprimiéndola en la ventana inmediato con Debug. Print... Ahí verás qué es lo que te falta

Lo he solucionado a medias, el código que tengo actualmente es:

Var_TipoCobro = Me![Forma de pago]
Var_N_Vencimientos = DCount("[Plazo]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Mi_FechaFactura = Me![Fecha_Factura]
MiAño = Me![Año_Factura]
MiSerieFactura = Me![SerieFactura]
N_Factura = Me![N_Factura]
MiFormaPago = DLookup("[Forma de Pago]", "Vencimientos_Forma_Pago", "[Id_Forma_Pago]='" & Var_TipoCobro & "'")
Var_TotalFactura = CambiaDecimal(Me![Total_Factura])
CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ([Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT Vencimientos_Forma_Pago.[Forma de pago], Dateadd('m',[Plazo]," & Format(Mi_FechaFactura, "mm/dd/yyyy") & ") AS Fecha_Vencimiento, Round(" & Var_TotalFactura & "*[Cuantia],2) AS Importe_Vencimiento FROM Vencimientos_Forma_Pago WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)='" & Var_TipoCobro & "'));"

CambiaDecimal es un módulo que cambia de 34,56 a 34.56

Me crea los registros, pero me pone mal las fechas. Si la forma de pago es transferencia a 0, 30 y 60 días, y la fecha factura 28/10/2017, a los vencimientos les da las fechas 30/12/1899, 30/01/1900 y 28/02/1900.

Supongo que será algo del formato de la fecha, ¿es posible?

Si fuera del formato no te cambiaría el año. Todo indicar que no te coge la fecha en la variable mifechafactura...

¡Gracias! Lo he resuelto....

Al final, parece ser que en la función Dateadd, hay que tratar la variable fecha como texto, es decir entre comillas simples:

CurrentDb.Execute "INSERT INTO [Temporal-Vencimientos_Factura_Emitidas] ([Forma de Pago], Fecha_Vencimiento, Importe_Vencimiento ) SELECT Vencimientos_Forma_Pago.[Forma de pago], Dateadd('m',[Plazo],'" & Mi_FechaFactura & "') AS Fecha_Vencimiento, Round(" & Var_TotalFactura & "*[Cuantia],2) AS Importe_Vencimiento FROM Vencimientos_Forma_Pago WHERE (((Vencimientos_Forma_Pago.Id_Forma_Pago)='" & Var_TipoCobro & "'));"

Gracias por tu ayuda

Me alegra un montón que lo hayas resuelto, porque ya me estaba quedando sin ideas...

Además, me sorprende mucho que te funcione como texto (entre comillas) y no como fecha (entre almohadillas) con formato europeo o americano... Pero bueno, siempre se aprende algo... je je.

Respuesta
1

La repuestos que te dan es la correcta hago lo mismo en planes de amortización para ajustar la ultima cuota

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas