Error en número de factura correlativa al cambiar de año Access VBA

En mi base de datos tengo un formulario para crear una nueva factura, lo normal. La última factura del 2022 ha sido la F22483. He creado la factura F23001 cambiando manualmente la que me proponía (la F22484).

Al crear una nueva más (en teoría la F23002) ha creado la F23485. Posteriormente he pensado que podía ser por la fecha de creación (estamos todavía en el año 2022) y eso podía influir. He cambiado la fecha del sistema al 1 de enero de 2023 pero me sigue proponiendo la misma.

El valor del campo NumeroFactura se genera tras el evento Afterupdate del campo anterior, Fecha mediante este vba:

NumeroFactura = "F" & Format(Right([Fecha], 2), "00") & Format(Nz(DCount("*", "Facturas", "left(NumeroFactura,1)=""F""") + 1), "000")

Alguien podría decirme cómo tener en cuenta la fecha del año y empezar de cero o tomar como referencia lo indicado manualmente en la primera factura del 23 (F23001)?

Respuesta
3

Eduardo., e complemento con este código que permite ingresar más de 999 facturas en el año, es decir, 9999. Se puede editar la función para 999999. Las funciones de dominio limitan las posibilidades y no sirven cuando se deben hacer consultas a otros servidores de datos.

TABLA

Ejemplo 1 - Año 2021

Observe que la última es F21999 pero la función retorna F211000

Ejemplo 2 - Año 2022

De acuerdo con la tabla la siguiente factura es F22004

Ejemplo - Año 2023

Como no hay registros en la tabla retorna F23001.

Función para obtener la siguiente factura

Public Function sgtefact(dfecha As Date) As String
'Función para conseguir la siguiente factura
'Formato inicial: F22001, en donde
 '                 F= Constante
 '                22=Primero 2 digitos del año
 '               001= Consecutivo
 'Si el consecutivo llega a 999 pasa al número 1000
 'Por ejemplo si la última factura=F21999 la siguiente será F211000
 '
 'NOTA: Lo ideal seria un formato como: F210001 alcanzaría para 9999 facturas
  Dim strSQl As String
  Dim intanio As Integer
  Dim rs As Recordset
  Dim aux1 As String
  Dim aux2 As String
  intanio = Right(dfecha, 2)
  strSQl = "SELECT Max(tblFacturas.factura) AS ultima" & vbCrLf
  strSQl = strSQl & "        FROM tblFacturas" & vbCrLf
  strSQl = strSQl & "      HAVING Mid([factura],2,2)=" & Right(dfecha, 2) & " ORDER BY Max(tblFacturas.factura);"
  Set rs = CurrentDb.OpenRecordset(strSQl)
  aux1 = Nz(rs("ultima"), "")
  If aux1 = "" Then
    sgtefact = "F" & intanio & "001"
    Exit Function
  End If
  aux2 = Mid(aux1, 2, Len(aux1) - 1)
  If Len(aux1) = 6 And Val(Right(aux2, 3)) = 999 Then
   '  llego a 999"
    sgtefact = "F" & Mid(aux1, 2, 2) & Val(Right(aux2, 3)) + 1
   ElseIf Len(aux1) > 6 Then
     sgtefact = "F" & Mid(aux1, 2, 2) & Val(Right(aux2, 4)) + 1
  Else
     sgtefact = "F" & Mid(aux1, 2, 2) & Format(Val(Right(aux2, 3)) + 1, "000")
  End If
 rs.Close
 Set rs = Nothing
End Function

Si quiere el ejemplo lo puede solicitar a [email protected]. Feliz año 2023

Le complemento el código del evento Después de actualizar del campo Fecha, para llamar la función.

Private Sub ctlFecha_AfterUpdate()
  Me.factura = sgtefact(Me.ctlFecha)
End Sub

Así de sencillo.

2 respuestas más de otros expertos

Respuesta
1

El error esta en 'contar' las facturas emitidas, es un gran error en cualquier circunstancia pues si 'falta' alguna intermedia el conteo y la correlatividad no coincidirán.

La siguiente se obtiene añadiendo una unidad a la más a la más alta del conjunto y se toman solo las cifras de la serie consecutiva para el calculo.

NumeroFactura = "F" & Right(Year(Date), 2) & DMax("Val(MId(Factura, 4))", "Facturas") + 1

Gracias Enrique, he modificado la expresión por esta, ya que me estaba dando error. He añadido "Numero" 

NumeroFactura = "F" & Right(Year(Date), 2) & DMax("Val(MId(NumeroFactura, 4))", "Facturas") + 1

pero me sigue proponiendo la F22484, cuando la última del listado es la F23001, alguna idea de por qué?

Gracias de nuevo.

Te propone la siguiente a la mas alta en base a estas condiciones:
La siguiente se obtiene añadiendo una unidad a la más a la más alta del conjunto y se toman solo las cifras de la serie consecutiva para el calculo.

Si se desea comenzar en cero con cada cambio de año (era mi opción inicial), se tendrá que filtrar por año y queda la duda si se rellena con ceros, se tiene que tener en cuenta que es un dato alfanumérico-consecutivo y 'el orden' será alfanumérico.

Con ceros y sin ceros de relleno (máximo 999 facturas con tres cifras)

NumeroFactura = "F" & Right(Year(Date), 2) & Nz(DMax("Val(mid(NumeroFactura,4))", "Facturas", "Left(NumeroFactura,3) = 'F" & Right(Year(Date), 2) & "'"), 0) + 1
NumeroFactura = "F" & Right(Year(Date), 2) & Format(Nz(DMax("Val(mid(NumeroFactura,4))", "Facturas", "Left(NumeroFactura,3) = 'F" & Right(Year(Date), 2) & "'"), 0) + 1, "000")

Un detalle, no se necesita inicializar la serie lo hace de forma automática con cada año.

¡Gracias! Funciona a la perfección.

Feliz año!

Aunque supongo que ya lo sabes, lo dejo aquí por si alguno tiene interés.

Si deseas tener más de 999 facturas/año (en el actual no has llegado a las 500) solo has de añadir tantos ceros como cifras necesites en la función Format final, te deseo que en este año que se inicia necesites añadir tres ceros más y llegar al millón de facturas.
Sin añadir ceros de relleno, el numero de facturas ... se podrán facturar clavos (un clavo: una factura) para construir un puente de madera entre continentes y sobraría espacio.

Respuesta
1

Puedes hacerlo de muchas formas. En el ejemplo siguiente uso el año de la fecha de la venta. Lo puse así, por si, por ejemplo, en Noviembre quiero hacer una factura para un mes de 2023.

El control NumFactura está bloqueado y en Fecha Venta escribo la fecha para la que quiero la factura

El cursor aún está en en el cuadro de texto. En el momento que pulso Enter

En este caso, pero ya te digo que se puede hacer de más formas, en el evento Después de actualizar del cuadro de texto le tengo puesto

Private Sub FechaVenta_AfterUpdate()
Dim a As Integer
a = Val(Nz(DMax("right([numfactura],3)", "ventas", "year([fechaventa])=year(date())"))) + 1
NumFactura = "F" & Right(Year(Date), 2) & "" & Format(a, "000")
End Sub

Por cierto, que tengas un Feliz Año Nuevo

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas