Imprimir página | Cerrar ventana

PROBLEMA AL RECOCORRER LOS REGISTROS DE UN RECORDS

Impreso de: Foro de Access y VBA
Categoría: Access y VBA
Nombre del foro: Access y VBA
Descripción del foro: Foro de programacion en Access (Con código y sin código)
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=87059
Fecha de impresión: 26/Marzo/2026 a las 15:43


Tema: PROBLEMA AL RECOCORRER LOS REGISTROS DE UN RECORDS
Publicado por: AgustinMN
Asunto: PROBLEMA AL RECOCORRER LOS REGISTROS DE UN RECORDS
Fecha de publicación: 09/Abril/2025 a las 20:21
Estimados amigos, os presento un código con el que tengo un problema que no puedo resolver y es el siguiente:

Desde un formulario situado en cualquier registro de la tabla "T_INGRESOS", al pulsar el botón ANADIR REGISTRO, me dirige a una "Sub" donde al abrir el Recordset, quiero tomar el valor del campo  "T_ING_CODSRV" del último registro del recordset, para ello utilizo dentro de WITH la función ".Movelast", pero mi sorpresa es que no me trae el valor de ese campo para el último registro sino del registro que está mostrándose en el formulario. ¿Alguien puede orientarme en por qué no se traslada al último registro?.
Sea como fuere, muchas gracias.


CODIGO:
' Código para actualizar o grabar un registro
Private Sub B_ANADIR_Click()
    Dim CODIGO_SOLICITUD As String, SQL_CODSRV As String, ANO_SOLICITUD As String, CODSRV As String, ORDEN As String
    Dim TOTAL As Integer, NUEVA_SOLICITUD As Integer, CONTADOR As Integer, NUEVO_ANO As Integer, NUEVO As Integer, NUMERODEREGISTROS As Integer
    Dim Conn As Object 'ADODB.Connection

    ANO_SOLICITUD = LTrim(Str(Year(Date)))
    NUEVO = 0
    CONTADOR = 0
    SQL_CODSRV = "SELECT * FROM T_INGRESOS " 'WHERE ([T_INGRESOS.T_ING_ANO] Like '" + ANO_SOLICITUD + "');"

    Set DB = CurrentDb
    Set RS = CurrentDb.OpenRecordset("T_INGRESOS")
 
    With RS
        If RS.EOF Then   'SI NO ESTÁ VACÍO ES QUE YA HAY REGISTROS EN ESE AÑO
            NUEVO_ANO = 1  ' SI ES NUEVO AÑO
            ORDEN = 1
            CODSRV = "1-" & ANO_SOLICITUD
        Else 'AL NO SER UN NUEVO AÑO....
            NUMERODEREGISTROS = Recordset.RecordCount
            .MoveLast
            ORDEN = Trim(InStr(1, T_ING_CODSRV, "-"))
            ORDEN = Left(T_ING_CODSRV, ORDEN - 1) ' El ORDEN será el último más 1
            T_ING_CODSRV.Value = ORDEN & "-" & ANO_SOLICITUD
        
            .MoveFirst
            Do While Not .EOF
                CONTADOR = CONTADOR + 1     ' CUENTA TODOS LOS REGISTROS QUE HAY EN LA TABLA
                ORDEN = Trim(InStr(1, T_ING_CODSRV, "-"))
                ORDEN = Left(T_ING_CODSRV, ORDEN - 1) ' El ORDEN será el último más 1
                .MoveNext
            Loop

            .AddNew
            DoCmd.GoToRecord , , acNewRec
            !T_ING_CODSRV = Me.T_ING_CODSRV
            !T_ING_ORDEN = Me.T_ING_ORDEN
            !T_ING_ANO = Me.T_ING_ANO
            !T_ING_DNI = Trim(Me.T_ING_DNI)
            !T_ING_FI = Me.T_ING_FI
            !T_ING_FACTURA = Me.T_ING_FACTURA
            !T_ING_N_FACTURA = Me.T_ING_N_FACTURA
            !T_ING_DESCUENTO = Me.T_ING_DESCUENTO
            !T_ING_IVA = Me.T_ING_IVA
            !T_ING_IMPORTE = Me.T_ING_IMPORTE
            !T_ING_FIANZA = Me.T_ING_FIANZA
            !T_ING_FIANZA_DEVUELTA = Me.T_ING_FIANZA_DEVUELTA
        End If
        .Close
    End With




-------------
AgustinMN



Respuestas:
Publicado por: xavi
Fecha de publicación: 10/Abril/2025 a las 10:22
Hola,

Respondiendo estrictamente tu pregunta (y sin saber exactamente los campos y lo que contienen) , yo no me complicaría tanto para localizar el valor que buscas: un DLast de ese campo creo que debería devolver lo que estás buscando.

Por otra parte hay cosas que, para mi gusto y comprensión, son mejorables em ese código. Apunto algunas mejoras, consejos e incoherencias.

- Una manía personal mía es no utilizar nombres  para las variables con palabras "peligrosas" o que me puedan inducir a error. Así no utilizaría la variable ORDEN si no, por ejemplo strOrden
- Hay varias variables que no se utilizan para nada y hay variables utilizadas que se suponen definidas de forma pública
- Para obtener ANO_SOLICITUD te sobra 1 función: Trim(Year(Date)) o, incluso, lo puedes hacer en una sola función: Format(Date, "yyyy")
- No veo que utilices SQL_CODSERV para nada
- En la WHERE comentada estás utilizando el signo + en lugar del del operador de concatenación &
- En las clausulas WHERE, si no hay operadores OR, casi siempre se pueden ahorrar los parentesis (excepto los de las funciones que contenga)
- Utilizas el Like cuando sospecho que un = tendría la misma efectividad
- Utilizas Recordset.RecordCount sin calificar. Supongo que es Me.Recordset.Recordcount
- Haces el RecordCount antes del MoveLast lo que puede devolver resultados erroneos
- Utilizas T_ING_CODSERV sin calificar por lo que no se sabe si es un control, un campo, una variable o una constante.
- Abres un bucle para contar registros cuando un DCount lo hace en una sola línea
- Después del AddNew mueves el formulario a un nuevo registro (el GoToRecord) y asignas a los campos del recordset los valores de los controles del formulario. Sólo se me ocurre que eso tenga sentido si los controles del formulario tienen valores predeterminados
- No haces el Update por lo que no salvas los valores en la tabla

En resumen, yo creo que todo ese código puede verse reducido a unas pocas líneas.

Se supone que este código (escrito al vuelo) hace prácticamente lo mismo que el tuyo... aunque creo que no es lo que verdaderamente deseas hacer.

    Dim rst As DAO.Recordset, arrMisCampos As Variant, i As Integer
    
    Set rst = CurrentDb.OpenRecordset("SELECT * FROM T_INGRESOS")

    DoCmd.GoToRecord,, acNewRec
    
    arrMisCampos = Array("T_ING_ORDEN", "T_ING_ANO", "T_ING_DNI", "T_ING_FI", "T_ING_FACTURA", _
                    "T_ING_N_FACTURA", "T_ING_DESCUENTO", "T_ING_IVA", "T_ING_IMPORTE", "T_ING_FIANZA", "T_ING_FIANZA_DEVUELTA")
    
    With rst
        .AddNew
        !T_ING_CODSRV = Nz(DCount("*", "T_INGRESOS"), 0) + 1 & "-" & Format(Date, "yyyy")
        For i = LBound(arrMisCampos) To UBound(arrMisCampos)
            .Fields(arrMisCampos(i)) = Me.Controls(i)
        Next
        .Update
        .Close
    End With
    Set rst = Nothing

Un saludo


-------------
Xavi, un minyó de Terrassa

http://www.llodax.com" rel="nofollow - Mi web


Publicado por: AgustinMN
Fecha de publicación: 10/Abril/2025 a las 16:44
Hola Xavi, he eliminado todas las líneas superfluas tal como me has indicado, pero al pasar por la lineal de código "  .Fields(arrMisCampos(i)) = Me.Controls(i)" me da un error que dice:

ha producido el error"438" en tiempo de ejecución:
El objeto no admite esta propiedad o método




-------------
AgustinMN


Publicado por: AgustinMN
Fecha de publicación: 02/Mayo/2025 a las 18:07
Tenía mal escrito el código. Ha funcionado correctamente.
Asunto cerrado


-------------
AgustinMN



Imprimir página | Cerrar ventana