Comprobar que en una tabla no falta ningún registro.

Tengo una tabla que recoge los cobros realizados a Clientes y estos están numerados con orden correlativo de menor a mayor.

Lo que que necesito es revisar cada uno de los cobros y comprobar previamente que no falta ningún numero en la relación que se presenta en un listado.

2 respuestas

Respuesta
1

Lo puedes hacer de muchas formas, convendría saber como es tu tabla o el formulario. Por ejemplo, tengo un formulario continuo basado en la tabla Numeros donde faltan algunos IdNumero( en tu caso sería, por ejemplo, Orden)

 Si pulso el botón me dice los IdNumero que faltan

En mi caso, el código del evento Al hacer clic del botón es

Private Sub Comando5_Click()
Dim i As Integer, d As Byte, c As Byte
DoCmd.GoToRecord , , acFirst
For i = 1 To Me.Recordset.RecordCount
d = IdNumero - (Nz(DMax("idnumero", "numeros", "idnumero<" & Me.IdNumero & "")) + 1)
If d = 1 Then
Faltan = Nz([Faltan], "") & "," & (Nz(DMax("idnumero", "numeros", "idnumero<" & Me.IdNumero & "")) + 1)
ElseIf d > 1 Then
For c = 1 To d
Faltan = Nz([Faltan], "") & "," & (Nz(DMax("idnumero", "numeros", "idnumero<" & Me.IdNumero & "")) + c)
Next c
End If
DoCmd.GoToRecord , , acNext
Next
Faltan = Mid([Faltan], 2, Len([Faltan]) - 1)
End Sub

Pero como te decía sería conveniente saber lo que apunto en el primer párrafo.

La tabla contiene los siguientes campos:

IdTabla-> Autonumérico

NFactura: Alfanumerico -> con esta composicion: 22FC0256

Año+SerieFactura+NºOrden

Tipo:Alfanumerico

Descripcion: Alfanumerico

Importe:Numerico (Doble)

Lo que busco es saber si me falta algún numero de Factura: NFactura

Esta tabla a través de una Consulta recoge las facturas emitidas en función de las Series solicitadas que son diferentes.

Si necesitas más información dímelo y te la envío.

Gracias.

Supongo que la serie factura serán las dos letras del centro y que los cuatro dígitos de la derecha son el Número de Orden. Vamos a ver si me explico. Si tengo la tabla Facturas a la que le añado un campo numérico llamado ValorNumero

Y construyo un formulario donde le añado un cuadro combinado para seleccionar la serie y el cuadro de texto Faltan

Cuando lo abro nstrucciónme actualiza el campo ValorNumero de la tabla a

Para ello uso la instrucción, en el evento Al cargar del formulario( así cada vea que lo abra me actualiza la tabla)

Private Sub Form_Load()
DoCmd.RunSQL "update facturas set valornumero=val(right([nfactura],4))"
Me.Requery
End Sub

Con lo cual el formulario me queda como

El combinado se llama ElegirSerie y voy a elegir la setrie AA. En el momento que la selecciono

1º Me limita los registros del formulario a aquellos de la tabla Facturas que correspondan a esa serie

2º En el cuadro de texto Faltan me muestra aquellos que ídem.

Si cambio de serie

En el evento Después de actualizar del combinado ElegirSerie le tengo puesto

Private Sub ElegirSerie_AfterUpdate()
Me.RecordSource = "select * from facturas where mid([nfactura],3,2)='" & Me.ElegirSerie & "'"
Dim i As Integer, d As Byte, c As Byte
DoCmd.GoToRecord , , acFirst
For i = 1 To Me.Recordset.RecordCount
d = ValorNumero - (Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & " and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + 1)
If d = 1 Then
Faltan = Nz([Faltan], "") & "," & (Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & "and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + 1)
ElseIf d > 1 Then
For c = 1 To d
Faltan = Nz([Faltan], "") & "," & (Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & "and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + c)
Next c
End If
DoCmd.GoToRecord , , acNext
Next
Faltan = Mid([Faltan], 2, Len([Faltan]) - 1)
End Sub

Y, también, en sus propiedades-eventos-Al recibir el enfoque

Private Sub ElegirSerie_GotFocus()
Faltan = Null
End Sub

Para que me lo deje en blanco para comprobar una nueva serie

O si lo prefieres así

Pon el código como

Private Sub ElegirSerie_AfterUpdate()
Me.RecordSource = "select * from facturas where mid([nfactura],3,2)='" & Me.ElegirSerie & "'"
Dim i As Integer, d As Byte, c As Byte
DoCmd.GoToRecord , , acFirst
For i = 1 To Me.Recordset.RecordCount
d = ValorNumero - (Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & " and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + 1)
If d = 1 Then
Faltan = Nz([Faltan], "") & "," & Left([NFactura], 2) & "" & Mid([NFactura], 3, 2) & "" & Format((Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & "and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + 1), "0000")
ElseIf d > 1 Then
For c = 1 To d
Faltan = Nz([Faltan], "") & "," & Left([NFactura], 2) & "" & Mid([NFactura], 3, 2) & "" & Format((Nz(DMax("ValorNumero", "Facturas", "ValorNumero<" & Me.ValorNumero & "and mid([nfactura],3,2)='" & Me.ElegirSerie & "'")) + c), "0000")
Next c
End If
DoCmd.GoToRecord , , acNext
Next
Faltan = Mid([Faltan], 2, Len([Faltan]) - 1)
End Sub
Respuesta
1

Si no quiere complicarse con código VBA puede hacerlo mediante una consulta.

TABLA

Es decir, faltan los números 3,4,6,8,10,11

DISEÑO DE LA CONSULTA

EQUIVALENCIA CÓDIGO SQL

SELECT ([nrocobro]+1) AS FaltanDesdeElNro, DMin("nrocobro","tblcobros","nrocobro>" & [nrocobro]) AS FaltanHastaElNro
FROM tblcobros
WHERE (((DMin("nrocobro","tblcobros","nrocobro>" & [nrocobro]))<>([nrocobro]+1)));

RESULTADO DE LA CONSULTA

FaltaHastaElNro seria a este valor -1, es decir, 5 indica que faltan el 3 y 4.

La tabla contiene los siguientes campos:

IdTabla-> Autonumérico

NFactura: Alfanumerico -> con esta composicion: 22FC0256

Año+SerieFactura+NºOrden

Tipo:Alfanumerico

Descripcion: Alfanumerico

Importe:Numerico (Doble)

Lo que busco es saber si me falta algún numero de Factura: NFactura

Esta tabla a través de una Consulta recoge las facturas emitidas en función de las Series solicitadas que son diferentes.

Si necesitas más información dímelo y te la envío.

Escríbame a [email protected] y le envío un ejemplo de algo muy parecido que respondí en TodoExpertos hace un tiempo.

Ya es cuestión que lo adpate.

Te escribí ayer dándote la mi correo. Por si no te llego mi dirección es:

[email protected]

Te agradecira si pudieses enviarme el ejemplo que me dijiste para poderlo adaptar.

Revise su correo

Le preparé este ejemplo teniendo en cuenta el año ha consultar y la serie.

TABLA

FORMULARIO (Hago la prueba con 3 series, 2 que tienen movimiento y 1 que no tiene)

En este último como no existe en la tabla la serie inicia la numeración.

CÓDIGO DEL BOTÓN CONSULTAR

Private Sub btnConsultar_Click()
  Me.ctlFaltan.Visible = True
  Me.ctlFaltan = faltanfacturas(Me.cboSerie, Me.cboPeriodo)
End Sub

CÓDIGO DE LA FUNCIÓN FALTANFACTURAS

Public Function faltanfacturas(strSerie As String, mperiodo As Integer) As String
  On Error GoTo hay_error
'Función para determinar las facturas que faltan en una serie
'Parámetros:
'           strSerie, por ejemplo FC,GD,HT
'           mperiodo = 2022 (es decir el año)
'Ejemplo llamada:
'                   faltanfacturas("FC",2023)
'Elaborada por:
'               EDUARDO PÉREZ FERNÁNDEZ - 22/06/2022
    Dim rst As DAO.Recordset
    Dim num As Integer
    Dim flag As Boolean
    Dim dbID As Integer
    Dim strFaltan As String
    Dim strsql As String
    Dim periodo As Integer
    Dim ctafacturas As Integer
   periodo = Right(mperiodo, 2)
  strsql = "SELECT tbfacturaserie.factura" & vbCrLf
  strsql = strsql & "           , tbfacturaserie.fecha" & vbCrLf
  strsql = strsql & "        FROM tbfacturaserie" & vbCrLf
  strsql = strsql & "       WHERE Mid([factura],3,2)='" & UCase(strSerie) & "'" & vbCrLf
  strsql = strsql & "         AND Right(Year([fecha]),2)=" & periodo & vbCrLf
  strsql = strsql & "    ORDER BY tbfacturaserie.factura;"
    Set rst = CurrentDb.OpenRecordset(strsql)
    If rst.RecordCount > 0 Then
     ctafacturas = Right(Nz(DLast("factura", "tbfacturaserie", "Mid([factura],3,2)='" & strSerie & "'")), 2)
    Else
      faltanfacturas = periodo & strSerie & "0001"
      Exit Function
    End If
     For num = 1 To ctafacturas
        flag = False
        Do While Not rst.EOF
            dbID = Val(Right(rst!factura, 4))
            If dbID = num Then
                flag = True
            End If
            rst.MoveNext
        Loop
        If flag = False Then
            strFaltan = strFaltan & periodo & UCase(strSerie) & Format(num, "0000") & ","
        End If
         rst.MoveFirst
     Next
    faltanfacturas = mid(strFaltan, 1, Len(strFaltan) - 1)
    rst.Close
    Set rst = Nothing
hay_error_exit:
   Exit Function
hay_error:
    MsgBox "Ocurrió el error " & Err.Number & " " & Err.Description, vbCritical, "Error..."
    Resume hay_error_exit
End Function

Puede adaptar esta función para que retorne únicamente la primera factura faltante. Tenga cuidado creo que la consulta se debe hacer con base en la serie y el año, algo que otros no incluyeron.

Esta función: CÓDIGO DE LA FUNCIÓN FALTANFACTURAS no se donde ha de ir colocada. Te agaradecia mucho si me indicases el lugar.

Guarde la función en un módulo, de esta forma la puede llamar desde cualquier parte

Estuve revisando la función y arroja error cuando la numeración está completa, por ejemplo.

Observe la serie FC hay 6 facturas pero no hay faltantes, en este caso la función debe informarlo con un mensaje.

En este caso la función cambia porque debe controlar si no hay información, no obstante, es diferente cuando NO hay registros de la serie, en este caso inicia con 0001.

NUEVA FUNCIÓN

Public Function faltanfacturas(strSerie As String, mperiodo As Integer) As String
   On Error GoTo hay_error
'Función para determinar las facturas que faltan en una serie
'Parámetros:
'           strSerie, por ejemplo FC,GD,HT
'           mperiodo = 2022 (es decir el año)
'Ejemplo llamada:
'                   faltanfacturas("FC",2023)
'Elaborada por:
'               EDUARDO PÉREZ FERNÁNDEZ - 22/06/2022
    Dim rst As DAO.Recordset
    Dim num As Integer
    Dim flag As Boolean
    Dim dbID As Integer
    Dim strFaltan As String
    Dim strsql As String
    Dim periodo As Integer
    Dim ctafacturas As Integer
   periodo = Right(mperiodo, 2)
  strsql = "SELECT tbfacturaserie.factura" & vbCrLf
  strsql = strsql & "           , tbfacturaserie.fecha" & vbCrLf
  strsql = strsql & "        FROM tbfacturaserie" & vbCrLf
  strsql = strsql & "       WHERE Mid([factura],3,2)='" & UCase(strSerie) & "'" & vbCrLf
  strsql = strsql & "         AND Right(Year([fecha]),2)=" & periodo & vbCrLf
  strsql = strsql & "    ORDER BY tbfacturaserie.factura;"
    Set rst = CurrentDb.OpenRecordset(strsql)
    If rst.RecordCount > 0 Then
     ctafacturas = Right(Nz(DLast("factura", "tbfacturaserie", "Mid([factura],3,2)='" & strSerie & "'")), 2)
    Else
      faltanfacturas = periodo & strSerie & "0001"
      Exit Function
    End If
     For num = 1 To ctafacturas
        flag = False
        Do While Not rst.EOF
            dbID = Val(Right(rst!factura, 4))
            If dbID = num Then
                flag = True
            End If
            rst.MoveNext
        Loop
        If flag = False Then
            strFaltan = strFaltan & periodo & UCase(strSerie) & Format(num, "0000") & ","
        End If
         rst.MoveFirst
     Next
     If Len(strFaltan) > 0 Then
        faltanfacturas = mid(strFaltan, 1, Len(strFaltan) - 1)
     Else
        faltanfacturas = "LA NUMERACIÓN ESTA COMPLETA"
     End If
    rst.Close
    Set rst = Nothing
hay_error_exit:
   Exit Function
hay_error:
    MsgBox "Ocurrió el error " & Err.Number & " " & Err.Description, vbCritical, "Error..."
    Resume hay_error_exit
End Function

Puede guardar la función en un módulo, también puede dejarla como una función a nivel de formulario o como un procedimiento con algunos cambios mínimos.

Le complemento porque se debe utilizar la función en lugar de clonar un formulario clonado. Ventajas:

1. No se abusa del uso de Dmax(), esto sería traumático en una tabla de gran tamaño

2. Permite crear consultas con base en la función. Observe este ejemplo en donde con base en la función hago una consulta para todos las series con la fecha del año de la fecha del sistema.

Creamos una consulta de agrupación.

Resultado de la consulta

Con base en la consulta puede crear un reporte o exportarla a Excel, PDF etc.

Hacer esto con un formulario clonado implica muchísimo trabajo. Resumiendo trate de diseñar funciones en lo posible.

Te había valorado ya la respuesta y no si he de hacerlo formulando otra pregunta o si con esta aun me puedes contestar.

He intentado adaptar todo lo que me indicas pero me esta dando el error 13 y no se ya donde mirar para evitarlo.

Esta es la tabla que esta trabajando:

Nombre Tabla: FACTURASGENERALIVA

IdTabla -> Autonumérico

FechaFactura ->Fecha/Hora

Numero -> Alfanumrico (10)

NombreFiscal -> 40

ImporteFactura -> Numero (Doble)

Te agradecería muchísimo si me dijeses como he de adaptar todo lo que me has indicado adaptándolo a esta Tabla ya que no se donde pueda estar el error.

Lo he colocado a través de una funcio y dentro de un botón que realice la búsqueda y me sigue dando error de las dos formas.

Sin ver como está adaptado el código es imposible decirle algo, todo indica que el error corresponde a tipos de datos que no concuerdan con los solicitados por la función.. Si puede envíeme la base de datos a [email protected] favor en el asunto anotar la consulta

Veo que la función NO sirve porque en la primera pregunta el tamaño del campo de las facturas era de 8 caracteres y esta nueva pregunta es de 10, en este caso si no puede enviar la base de datos por lo menos es necesario conocer cómo está compuesto el campo de los 10 caracteres, algo como lo explicó. Por ejemplo:

NFactura: Alfanumerico -> con esta composicion: 22FC0256

Año+SerieFactura+NºOrden

Muchas gracias por tu nueva atención.

La tabla: FACTURASGENERALIVA es una tabla intermedia que recoge los movimientos de las Facturas realizadas al igual que sirve para otros procesos de reorganización de datos para otros procesos.

Es creada y borrada por cada realización del proceso.

Tiene más Campos pero en este formulario solo trabajan estos.

He reorganizado esta tabla dejándola con estos elementos:

IdFactura: Autonumérico

FechaFactura1: Fecha/Hora

NumeroFactura1: Alfanumerico (8)  [22FC0256]

ImporteFactura: Numerico Doble

NombreFiscal: Alfanumerico (40)

Si necesitas más detalles dímelo y los envío de nuevo.

Sin tener la tabla y revisar cómo ha adaptado la función es imposible entrar en detalles.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas