Buscar un registro en Recordset para modificarlo

Tengo una tabla para registrar los comerciales. A cada comercial le quiero asignar un cliente, es decir que cada comercial, a su vez figure en la Tabla_Clientes. He creado un código para que al crear un comercial, cree automáticamente el correspondiente cliente, y funciona correctamente.

Ahora quiero crear un código, para que al actualizar los datos de un comercial, los actualice automáticamente en la Tabla_Clientes, pero no me funciona bien, ya que al intentar buscar el registro correspondiente en la Tabla_Clientes, el la línea:

rstTabla_Clientes.FindFirst "Referencia = " & Id_Cliente

Me da error:

"Se ha producido el error '424' en tiempo de ejecución: Se requiere un objeto"

"Referencia" es el campo clave de la tabla de clientes, he verificado que la variable Id_Cliente tomo correctamente el valor correspondiente.

No se como solucionarlo, ¿Alguna idea?

Dim Nombre_Comercial As String
Dim Fecha_alta As Date
Dim Captura_Cliente As String
Dim Direccion As String
Dim Codigo_postal As String
Dim Poblacion As String
Dim Provincia As String
Dim Email As String
Dim Web As String
Dim Telefono As String
Dim Contactos As String
Dim Id_Cliente As Integer
'Toma de valores
Nombre_Comercial = Nz(Forms![Formulario Comerciales]![Nombre])
Fecha_alta = Forms![Formulario Comerciales]![Fecha alta]
Direccion = Nz(Forms![Formulario Comerciales]![Direccion])
Codigo_postal = Nz(Forms![Formulario Comerciales]![Codigo postal])
Poblacion = Nz(Forms![Formulario Comerciales]![Población])
Provincia = Nz(Forms![Formulario Comerciales]![Provincia_Facturas])
Email = Nz(Forms![Formulario Comerciales]![E-mail])
Web = Nz(Forms![Formulario Comerciales]![Web])
Telefono = Nz(Forms![Formulario Comerciales]![Telefono])
CIF = Nz(Forms![Formulario Comerciales]![CIF])
DoCmd.SetWarnings False
If SysCmd(acSysCmdGetObjectState, acForm, "Tabla_Clientes") <> 0 Then
       ' The object is open.
        IsObjectLoaded = True
        DoCmd.Close acForm, "Tabla_Clientes", acSaveYes
    Else
       ' The object is not open.
        IsObjectLoaded = False
    End If
If IsNull(Forms![Formulario Comerciales]![Cliente_Asociado]) Then
    Set dbsBase = CurrentDb
    Dim rstTabla As DAO.Recordset
    Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes")
    rstTabla.AddNew
        rstTabla![Nombre Comercial] = Nombre_Comercial
        rstTabla![Fecha alta] = Fecha_alta
        rstTabla![CIF] = CIF
        rstTabla![Direccion pedidos] = Direccion
        rstTabla![Codigo postal pedidos] = Codigo_postal
        rstTabla![Población pedidos] = Poblacion
        rstTabla![Provincia_Pedidos] = Provincia
        rstTabla![Telefono] = Telefono
        rstTabla![E-mail] = Email
        rstTabla![Web] = Web
        rstTabla.Update
    'Abrimos el Formulario "Tabla_Clientes"
    DoCmd.OpenForm "Tabla_Clientes"
    DoCmd.GoToRecord acDataForm, "Tabla_Clientes", acLast
    'Tomamos el valor de Referencia (autonumerico)
    Id_Cliente = Forms![Tabla_Clientes]![Referencia]
    'Introducimos el valor de Id_Cliente en la tabla Comerciales
    Forms![Formulario Comerciales]![Cliente_Asociado].Enabled = True
    Forms![Formulario Comerciales]![Cliente_Asociado] = Id_Cliente
    Forms![Formulario Comerciales]![Cliente_Asociado].Enabled = False
Else
    Id_Cliente = Forms![Formulario Comerciales]![Cliente_Asociado]
    Set dbsBase = CurrentDb
    Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes")
    rstTabla_Clientes.FindFirst "Referencia = " & Id_Cliente
    rstTabla.Edit
        rstTabla![Nombre Comercial] = Nombre_Comercial
        rstTabla![Fecha alta] = Fecha_alta
        rstTabla![CIF] = CIF
        rstTabla![Direccion pedidos] = Direccion
        rstTabla![Codigo postal pedidos] = Codigo_postal
        rstTabla![Población pedidos] = Poblacion
        rstTabla![Provincia_Pedidos] = Provincia
        rstTabla![Telefono] = Telefono
        rstTabla![E-mail] = Email
        rstTabla![Web] = Web
        rstTabla.Update
End If
DoCmd. RunCommand acCmdSaveRecord
1

1 respuesta

Respuesta
2

Si tu recordset se llama rstTabla, ¿por qué buscas en un recordset que se llama rstTabla_Clientes?...

Ahí está tu error, y por eso te pide un objeto (rstTabla_Clientes, que no existe) ;-)

Un saludo.


La tabla se llama Tabla_Clientes, pero establezco que tabla=Tabla_Clientes (set rstTabla=dbsBase.OpenRecordset("Tabla_Clientes")

Las tablas da lo mismo como se llamen, y un recodset no es igual que una tabla. El problema lo tienes en el nombre del recordset, que usas uno que a priori no existe:

En la parte del Else tienes:

Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes")

    rstTabla_Clientes.FindFirst "Referencia = " & Id_Cliente

RstTabla. Edit

Si tu recordset es rstTabla, no puedes hacer el findfirst sobre un recordset que no existe (rstTabla_Clientes). Has de usar siempre el mismo nombre, a no ser que trabajes con dos recordsets distintos, claro...

Siguiendo tu consejo, he cambiado la expresión:

rstTabla_Clientes.FindFirst "Referencia = " & Id_Cliente

Por:

rstTabla.FindFirst "Referencia = " & Id_Cliente

Pero me surge un nuevo error:  "Se ha producido el error '3251' en tiempo de ejecución: Operación no válida para este tipo de objeto"

¡Vaya! Es la primera vez que veo que un findfirst no es una operación válida para un recordset...

La sintaxis es correcta (https://msdn.microsoft.com/es-es/library/office/ff194787.aspx ), y supongo que en tu tabla Tabla_Clientes tienes el campo "Referencia" y es de tipo numérico.

Prueba así:

rstTabla.FindFirst "[Referencia]=" & Id_Cliente

o modifica la linea anterior así:

Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes",dbOpenDynaset)

En efecto, lo he conseguido salvar con la opción "dbOpenDynaset", pero ahora me surge un nuevo problema. No consigo salir del formulario, ya que me da error al intentar guardar los cambios (DoCmd.RunCommand acCmdSaveRecord) al final del código.

El error que me da es: "Se ha producido el error "2115" en tiempo de ejecución: La macro o función establecida para la propiedad ReglaDeValidación o AntesDeActualizar de este campo impide que Microsoft Office Access guarde los datos del campo"

Ahora si que no se por donde salir

Private Sub Form_AfterUpdate()
Dim Nombre_Comercial As String
Dim Fecha_alta As Date
Dim Captura_Cliente As String
Dim Direccion As String
Dim Codigo_postal As String
Dim Poblacion As String
Dim Provincia As String
Dim Email As String
Dim Web As String
Dim Telefono As String
Dim Contactos As String
Dim Id_Cliente As Integer
'Toma de valores
Nombre_Comercial = Nz(Forms![Formulario Comerciales]![Nombre])
Fecha_alta = Forms![Formulario Comerciales]![Fecha alta]
Direccion = Nz(Forms![Formulario Comerciales]![Direccion])
Codigo_postal = Nz(Forms![Formulario Comerciales]![Codigo postal])
Poblacion = Nz(Forms![Formulario Comerciales]![Población])
Provincia = Nz(Forms![Formulario Comerciales]![Provincia_Facturas])
Email = Nz(Forms![Formulario Comerciales]![E-mail])
Web = Nz(Forms![Formulario Comerciales]![Web])
Telefono = Nz(Forms![Formulario Comerciales]![Telefono])
CIF = Nz(Forms![Formulario Comerciales]![CIF])
DoCmd.SetWarnings False
If SysCmd(acSysCmdGetObjectState, acForm, "Tabla_Clientes") <> 0 Then
       ' The object is open.
        IsObjectLoaded = True
        DoCmd.Close acForm, "Tabla_Clientes", acSaveYes
    Else
       ' The object is not open.
        IsObjectLoaded = False
    End If
If IsNull(Forms![Formulario Comerciales]![Cliente_Asociado]) Then
    Set dbsBase = CurrentDb
    Dim rstTabla As DAO.Recordset
    Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes")
    rstTabla.AddNew
        rstTabla![Nombre Comercial] = Nombre_Comercial
        rstTabla![Fecha alta] = Fecha_alta
        rstTabla![CIF] = CIF
        rstTabla![Direccion pedidos] = Direccion
        rstTabla![Codigo postal pedidos] = Codigo_postal
        rstTabla![Población pedidos] = Poblacion
        rstTabla![Provincia_Pedidos] = Provincia
        rstTabla![Telefono] = Telefono
        rstTabla![E-mail] = Email
        rstTabla![Web] = Web
        rstTabla.Update
   rstTabla.MoveLast
        Id_Cliente = rstTabla![Referencia]
    'Abrimos el Formulario "Tabla_Clientes"
    DoCmd.OpenForm "Tabla_Clientes"
    DoCmd.GoToRecord acDataForm, "Tabla_Clientes", acLast
    'Tomamos el valor de Referencia (autonumerico)
    Id_Cliente = Forms![Tabla_Clientes]![Referencia]
    'Introducimos el valor de Id_Cliente en la tabla Comerciales
    Forms![Formulario Comerciales]![Cliente_Asociado].Enabled = True
    Forms![Formulario Comerciales]![Cliente_Asociado] = Id_Cliente
    Forms![Formulario Comerciales]![Cliente_Asociado].Enabled = False
Else
    Id_Cliente = Forms![Formulario Comerciales]![Cliente_Asociado]
    Set dbsBase = CurrentDb
    Set rstTabla = dbsBase.OpenRecordset("Tabla_Clientes", dbOpenDynaset)
    rstTabla.FindFirst "Referencia = " & Id_Cliente
    rstTabla.Edit
        rstTabla![Nombre Comercial] = Nombre_Comercial
        rstTabla![Fecha alta] = Fecha_alta
        rstTabla![CIF] = CIF
        rstTabla![Direccion pedidos] = Direccion
        rstTabla![Codigo postal pedidos] = Codigo_postal
        rstTabla![Población pedidos] = Poblacion
        rstTabla![Provincia_Pedidos] = Provincia
        rstTabla![Telefono] = Telefono
        rstTabla![E-mail] = Email
        rstTabla![Web] = Web
        rstTabla.Update
End If
DoCmd.RunCommand acCmdSaveRecord
End Sub

Ese error no parece originado por tu código (al menos no por el que transcribes). MIra lo que te dice el error (es bastante descriptivo) y comprueba que no tengas ninguna regla de validación en algún campo de tu tabla o que tengas algún código en el evento "antes de actualizar".,

Además, si tu formulario es dependiente de una tabla, ya te guardará automáticamente los cambios, no te hace falta poner el acCmdSaveRecord.

Haciendo pruebas y yendo instrucción por instrucción, he detectado que el problema es que crea o modifica bien el registro en la tabla_Clientes, pero no me permite guardar los cambios en la Tabla_Comerciales y por tanto entro en un bucle, ya que si intento guardar manualmente el registro, vuelvo a activar el modulo, por ser un Form_afterupdate.

No consigo entender porque no me permite guardar los cambios.

¿Igual se puede solucionar poniendo el código en cada campo en afterupdate?

Prueba a ver, pero te repito, si tu formulario tiene como origen de datos la tabla, los cambios te los guardará automáticamente.

Lo que no me parece que tenga mucho sentido es que uses el evento "después de actualizar" del formulario para asignar valores del propio formulario... lo más conveniente, creo yo, es que esa asignación de valores al propio formulario lo hagas después de actualizar los controles correspondientes.

¡Gracias! 

He probado asignando a cada control y funciona. Así puede valerme, aunque tenía un código asignado al formulario para que cuando se actualizase un registro exportará un informe actualizado en formato pdf. Antes esto me funcionaba bien, cuando acababa de actualizar el formulario me exportaba el pdf, y ahora lo hace varias veces, cada vez que cambio un control.

Pues divide el código y pon la exportación donde la tenías antes, y no en cada control (si te he entendido bien...)

Así lo tengo, pero ahora, cada que cambio un control, parece ser que actualiza el formulario y por tanto ejecuta la acción afterupdate

Quita todos los SaveRecord de los eventos de los controles para que no te pase

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas