Función en campo fecha para generar número de factura

Antes que nada agradecer como siempre la ayuda recibida, qué sería de nosotros, los que no sabemos, sin los que aportan su conocimiento de manera desinteresada, de verdad, gracias!

Tengo una tabla "PFS" donde recojo datos para hacer presupuestos y facturas. Los presupuestos tienen la nomenclatura P+AA+00X, es decir el primer presupuesto del año es P22001. Las facturas igual, solo con la letra F.

En el formulario donde elaboro el presupuesto el primer control es fecha y tiene un código vba después de actualizar que es este:

Dim a As Integer
a = Val(Nz(DMax("right([NumeroPFS],3)", "PFS", "year([fecha])=year(date())"))) + 1
NumeroPFS = "P" & Right(Year(Date), 2) & "" & Format(a, "000")

Donde NumeroPFS es el número de orden de presupuesto o de factura.

El problema me ha llegado cuando tras hacer el primer presupuesto (P22001) he ido a hacer la primera factura (en teoría la F2201) y me ha nombrado automáticamente F22002, es decir, no hace distinción entre la P y la F.

¿Qué variación tendría que hacerle al código para que hiciera esa distinción?

2 respuestas

Respuesta
1

Eduardo, sería conveniente saber como son las tablas, ya que lo puedes hacer de mil formas diferentes. Por ejemplo, y suponiendo que la tabla Facturas no se toca para nada, excepto para enviarlas( y rogar que te las paguen).

Si tengo la tabla Presupuestos

El campo NumPresupuesto es indexado sin duplicados. Y con ella construyo un formulario

Puedes ver que hay tres registros. Le he puesto que el campo Numpresupuesto esté bloqueado, de forma que cuando escribo la fecha me ponga ya el Numpresupuesto que le corresponda.

Y le he puesto el botón porque he supuesto que un buen día te llama un cliente y te dice que sí, que aprueba el presupuesto, por lo que "repasas" el presupuesto y por tanto lo pasas a Factura. Cuando pulso el botón me pasa los datos a la tabla Facturas. Pasan unos días y viene otro cliente y dice que sí. Comprueba que me he ido al registro 3( mira el numpresupuesto).

Pulso el botón y la tabla Facturas me la deja como

Observa que el numfactura es correlativo

En este caso en particular, en el evento Después de actualizar del cuadro de texto FechaPrep del formulario Presupuestos le he puesto

Private Sub FechaPrep_AfterUpdate()
Dim a As Integer
a = Val(Nz(DMax("right([numpresupuesto],3)", "presupuestos", "year([fechaprep])=year(forms!presupuestos!fechaprep)"))) + 1
NumPresupuesto = "P" & Right(Year([FechaPrep]), 2) & Format(a, "000")
End Sub

En el botón de Pasar a Factura

Private Sub Comando9_Click()
DoCmd.RunSQL "insert into facturas(fechafact,cliente,importe)values(fechaprep,cliente,importe)"
DoCmd.RunSQL "update facturas set numfactura=""F""&mid('" & Me.NumPresupuesto & "',2,2)&format(idfactura,""000"") where numfactura is null"
End Sub

Como te decía hay mil formas de hacerlo

De todas formas, si quieres el ejemplo, repito, si quieres, mándame un mensaje, sólo el mensaje a [email protected] y te lo mando.

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

Respuesta
1

Puede utilizar la siguiente función para tomar el número de Presupuesto o Factura

CASO I- Utiliza la misma tabla para numerar presupuestos y facturas

Function sgte(strletra As String) As String
' Parámetro:  strletra="P" Presupuesto
'                     ="F" Factura
' Opera sobre una misma tabla PFS
' Función para trabajar sobre la misma tabla
' ' Ejemplo de llamada:
'                     sgte("P") ---- retorna P22001
'                     sgte("F") ---- retorna F22001
  Dim strSQl As String
  Dim rs As Recordset
  strSQl = "SELECT Max(Mid([NumeroPFS],2,5)) AS sigue" & vbCrLf
  strSQl = strSQl & "        FROM PFS" & vbCrLf
  strSQl = strSQl & "       WHERE  (Year([fecha]) =Year(Date()) " & vbCrLf
  strSQl = strSQl & "         AND  Left([NumeroPFS],1) ='" & strletra & "')" & ";"
 Set rs = CurrentDb.OpenRecordset(strSQl)
  If IsNull(rs.Fields("sigue")) Then
   sgte = strletra & Right(Year(Date), 2) & "001"
 Else
   sgte = strletra & rs.Fields("sigue") + 1
 End If
 rs.Close
 Set rs = Nothing
End Function

Si es en el formulario presupuesto, en el evento Después de actualizar la fecha llama la función como sgte("P"), ahora si utiliza una misma tabla para presuuesto y factura (aunque no sería lo ideal) puede que tenga un campo para diferenciar con una letra, por ejemplo, "P", presuesto "F" factura, en este caso llamaría la función es en el evento Después de actualizar de este campo, por ejemplo

Call sgte(Me.letra)

CASEO II - Utiliza una tabla para presupuesto y otra para facturas, es lo ideal.

Function fac_pre(strTabla As String, strletra As String) As String
' Parámetro:
'          strTabla ... Nombre de la tabla
'          strletra   ="P" Presupuesto
'                     ="F" Factura
' Opera sobre tabla pasada como parámetro
' Ejemplo de llamada:
'                     fac_pre("PFS","P")  ---- retorna P22001 -- Tabla presupuesto
'                     fac_pre("PFAC","F")  ---- retorna F22001 --- Tabla Facturas
  Dim strSQl As String
  Dim rs As Recordset
  strSQl = "SELECT Max(Mid([NumeroPFS],2,5)) AS sigue" & vbCrLf
  strSQl = strSQl & "        FROM " & strTabla & vbCrLf
  strSQl = strSQl & "       WHERE  (Year([fecha]) =Year(Date()) " & vbCrLf
  strSQl = strSQl & "         AND  Left([NumeroPFS],1) ='" & strletra & "')" & ";"
 Set rs = CurrentDb.OpenRecordset(strSQl)
  If IsNull(rs.Fields("sigue")) Then
   fac_pre = strletra & Right(Year(Date), 2) & "001"
 Else
   fac_pre = strletra & rs.Fields("sigue") + 1
 End If
 rs.Close
 Set rs = Nothing
End Function

Con esta función puede determinar el siguiente número de presupuesto o de factura, pasando como  parámetro el nombre de la tabla y la letra. Ya pude mirar que uso le da si quiere registrar la factura partiendo de la tabla presupuesto etc.

Muchas gracias Eduardo.

Efectivamente hay un campo "TipoPFS" que tiene los valores "Presupuesto" o "Factura" y que en el formulario "Nuevo Presupuesto" está, no visible, con el valor predeterminado en Presupuesto.

Este código debe ir en el evento "después de actualizar" del campo fecha, verdad? Actualmente el código vba es este:

Private Sub Fecha_AfterUpdate()
Dim a As Integer
a = Val(Nz(DMax("right([NumeroPFS],3)", "PFS", "year([fecha])=year(date())"))) + 1
NumeroPFS = "P" & Right(Year(Date), 2) & "" & Format(a, "000")
End Sub

Al sustituir el código que me especificas aquí me da un error de compilación en la primera línea "se esperaba End Sub".

Private Sub Fecha_AfterUpdate()
Function sgte(strletra As String) As String
' Parámetro:  strletra="P" Presupuesto
'                     ="F" Factura
' Opera sobre una misma tabla PFS
' Función para trabajar sobre la misma tabla
' ' Ejemplo de llamada:
'                     sgte("P") ---- retorna P22001
'                     sgte("F") ---- retorna F22001
  Dim strSQl As String
  Dim rs As Recordset
  strSQl = "SELECT Max(Mid([NumeroPFS],2,5)) AS sigue" & vbCrLf
  strSQl = strSQl & "        FROM PFS" & vbCrLf
  strSQl = strSQl & "       WHERE  (Year([fecha]) =Year(Date()) " & vbCrLf
  strSQl = strSQl & "         AND  Left([NumeroPFS],1) ='" & strletra & "')" & ";"
 Set rs = CurrentDb.OpenRecordset(strSQl)
  If IsNull(rs.Fields("sigue")) Then
   sgte = strletra & Right(Year(Date), 2) & "001"
 Else
   sgte = strletra & rs.Fields("sigue") + 1
 End If
 rs.Close
 Set rs = Nothing
End Function
End Sub

Dados mis bajos conocimientos de vba es muy probable que me esté equivocando en algo...

Gracias de nuevo!

Está llamando mal la función, la debe guardar en un módulo de VBA y la llamarla así:

Private Sub Fecha_AfterUpdate()
 If Me.TipoPFS = "Presupuesto" Then
  NumeroPFS = sgte("P")
 Else
  NumeroPFS = sgte("F")
 End If
End Sub

Por último, si ve que no puede envíeme su base de datos a [email protected], favor en el asunto anotar su consulta

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas