Gestión de Usuarios avanzada

Retomamos el tema donde lo dejamos en el post anterior, vamos a ampliar nuestra gestión de usuarios añadiendo un nivel mas de seguridad. El método que propongo es el siguiente: Vamos a controlar a que formularios pueden entrar nuestros usuarios y a cuales no.

Para ello seguiremos los siguiente pasos:

  1. Añadiremos una nueva tabla «tblUsuariosPermisos».
  2. La relacionaremos con la tabla «tblUsuarios».
  3. Crearemos una tabla «tblUsuarioActivo».
  4. Crearemos un formulario para gestionar los permisos.
  5. Crearemos un código para guardar el usuario activo una vez entremos en la aplicación.
  6. Crearemos un módulo que al pasarle el nombre de un formulario si no tiene permiso, lo cierre directamente.
  7. Creamos un par de formularios de prueba y los probamos.

Dicho esto, vamos a ponernos manos a la obra.

Paso 1

Vamos a crear una tabla «tblUsuariosPermisos» que nos servirá para indicar, por cada uno de los usuarios de la tabla «tblUsuarios» a que formularios tiene acceso y a cuales no.

Dicha tabla ha de llevar los siguientes campos:

Nombre                                      Tipo       
IdPermiso                                  Autonumérico y clave principal
IdUsuario                                  Texto (Mismo tamaño que el IdUsuario de la tabla tblsUsuarios)
NombreFormulario                     Texto
Acceso                                     Si/No

Paso 2

Relacionamos dicha tabla con la tabla «tblUsuarios», ya he comentado en alguna ocasión la importancia de las relaciones, en nuestro caso debemos hacerlas porque sin ellas, podríamos borrar un Usuario de la tabla «tblsUsuarios» y dejar sus registros relacionados de la tabla «tblUsuariosPermisos» en el aire, ocupando un espacio absurdo.

Como veis he Marcado las tres casillas «Exigir integridad referencial» para que no me deje dar de alta un permiso de un usuario que no exista, «Actualizar en cascada….» para que si cambio el DNI de un Usuario me lo actualice en las dos tablas el solo y «Eliminar en cascada…..» para que si elimino un usuario automáticamente me elimine también los registros relacionados en la tabla «tblUsuariosPermisos» y no se nos queden registros huérfanos por ahí.

Paso 3

¿Para que necesitamos una tabla como la de «tblUsuarioActivo», bien vamos a intentar explicarlo, cuando vallamos a abrir un formulario y le pidamos a nuestro programa que compruebe si el usuario que inició la aplicación puede abrir dicho formulario, en algún sitio tenemos que indicarle a Access quien fue el usuario que inició la aplicación, esto como otras muchas cosas se puede hacer de mil maneras distintas, cada programador es un mundo, una de ellas es, una vez que hemos validado al usuario y lo hemos dejado entrar, guardar su «Id» en dicha tabla y así lo tenemos disponible cada vez que queramos saber quien es.

Nuestra tabla solo necesita un campo «IdUsuario» tipo «Texto» con el mismo tamaño que el «IdUsuario» de la tabla «tblUsuarios» y de momento solo contendrá un registro que grabaremos y leeremos mediante código cada vez que nos haga falta.

Paso 4

Lo ideal es tener un formulario para gestionar cómodamente los permisos así que aquí va una propuesta, formulario de la tabla «tblUsuarios» con un subformulario de la tabla «tblUsuariosPermisos» relacionados por el campo «IdUsuario» que hace el asistente automáticamente.:

No me critiquéis el diseño que no me he esmerado nada en él, lo he dejado tal cual me lo ha sacado el asistente que para ilustrar nuestro ejemplo sobra. Vosotros que tendréis mas tiempo ya le vais dando un toque mas bonito.

Como podéis ver al usuario «EL PEQUEÑO SALTAMONTES» solo puede entrar al formulario «frmAlmacen» que es al único donde le he marcado la casilla.

Paso 5

En nuestro formulario de acceso, donde validamos usuario y contraseña, vamos a ampliar el código para que, una vez lo valide y nos deje entrar en la aplicación, guardemos dicho usuario en nuestra tabla «tblUsuarioActivo»

El código que pongo aquí es el mismo de la entrega anterior, incluyendo las nuevas modificaciones.

Private Sub cmdAceptar_Click()

' Buscamos el dni en la tabla tblUsuarios, en caso de no
' encontrarlo avisaremos con un mensaje y saldremos del
' procedimiento.

If IsNull(DLookup("IdUsuario","tblUsuarios","IdUsuario = '" & Me.txtIdUsuario & "'" )) Then
Call MsgBox("El usuario no existe en nuestra base de datos.", vbCritical, "Atención")
Exit Sub
End If

' Si llegamos hasta aquí es porque el dni existe
' en la base de datos, por lo tanto vamos a
' comprobar si la contraseña coincide con la del
' dni introducido.

' Primero creamos una variable para
' guardar la contraseña del usuario
' que previamente hemos validado.

Dim sContraseña As String
sContraseña = DLookup("Contraseña", "tblUsuarios", _
& "IdUsuario = '" & Me.txtIdUsuario & "'")

' Una vez tenemos la contraseña en la variable "sContraseña"
' la contrastamos con la que ha introducido el usuario
' en el formulario de validación.

If sContraseña = Me.txtContraseña Then
' Informamos al usuario de que la contraseña
' es correcta y cerramos el formulario
' dándole paso al resto de la aplicación

' Además, como somos un programador que mimamos
' los detalles le daermos el mensaje personalizado
' con su nombre al usuario, para ello, buscamos primero
' en la tabla, el nombre que corresponde con el dni
' introducido.

Dim sNombre As String
sNombre = DLookup("Nombre" , "tblUsuarios" , "idUsuario= '" & _
  Me.txtIdUsuario & "'")

' Con el nombre del usuario en la variable "sNombre"
' procedemos a mostrar el mensaje personalizado.

Call MsgBox("Bienvenido " & sNombre & ", puede acceder al sistema." _
, vbInformation, "Datos correctos")

' Antes de cerrar el formulario vamos a guardar el idUsuario
' en la tabla "tblUsuarioActivo"
Dim sSQL As String
' Creamos una sentencia SQL que es una consulta de
' actualización de la tabla

sSQL = "UPDATE tblUsuarioActivo SET "  _
 "tblUsuarioActivo.IdUsuario = '" & Me.txtIdUsuario & "'"

' Al ejecutar la siguiente línea, al ser una consulta
' de actualización, Access mandará unos mensajes
' muy impertinentes sobre si quieres hacerlo o no
' pero al usuario de la aplicación no tiene que tomar
' esa decisión así que primero desactivamos los mensajes
' del sistema y a continuación ejecutamos la consulta

DoCmd.SetWarnings False
DoCmd.RunSQL sSQL
' Una vez ejecutada volvemos a activar los mensajes del sistema
DoCmd.SetWarnings True

DoCmd.Close
Else

' Si es incorrecta, informamos al usuario y llevamos
' el cursos de nuevo al cuadro de texto de la contraseña
' para que el usuario vuelva a escribirla.
Call MsgBox("La contraseña es incorrecta. Vuelva a intentarlo.", _
vbExclamation, "Datos correctos")
Me.txtContraseña.SetFocus
End If
End Sub

Un inciso, como la sentencia que hemos usado para guardar el usuario en la tabla «UPDATE tblUsuarioActivo SET ……» realmente es una consulta de actualización, para que funcione correctamente, nuestra tabla «tblUsuarioActivo» debe tener por lo menos un registro, que es el que utiliza la consulta para modificarlo por el usuario de nuestro formulario. Para ello podéis entrar en la tabla y añadir a mano el primer registro con el DNI que os de la gana.

Ahora podéis comprobar como al entrar a nuestro programa se guarda en la tabla el usuario con el que hemos entrado.

Paso 6

Ahora tenemos un usuario al que le hemos asignado una serie de permisos (nombres de formularios y si puede o no entrar a ellos) y lo que vamos a hacer es que al abrir un formulario, este compruebe antes de abrirse, si el usuario tiene permisos para ello, en caso afirmativo el formulario se abrirá y en caso negativo el formulario se cerrará avisando al usuario de que es un «Pringado» y no puede acceder.

Como el código que escribiremos para ello lo vamos a tener que repetir en todos los formularios que tengamos en nuestro programa, los actuales y los que vallamos añadiendo según crezca nuestra aplicación, no sería correcto REPETIR una y otra vez el mismo código en cada uno de ellos, ¿Y por que os digo eso? pues muy sencillo, vamos a suponer que con el tiempo y gracias a nuevos conocimientos, podemos mejorar el código que hemos escrito añadiéndole nuevas funciones, una vez tengamos la mejora tendríamos que ir uno por uno en todos los formularios donde lo hemos usado y actualizar el nuevo código, obviamente esto es un engorro.

¿Que os propongo? pues escribirlo solo una vez, crearemos un módulo independiente, que no esté asociado a ningún formulario, y escribiremos el código ahí, luego solo tendremos que llamarlo desde cada formulario que lo necesitemos y el día que tengamos que mejorarlo solo lo haremos una vez.

Pues ala, manos a la obra, pestaña «Crear», os recuerdo que estoy en Access 2010, al final encontramos el grupo «Macros y Código», pulsamos sobre «Módulo»

Ahora vamos a escribir un procedimiento que al llamarlo, si no tiene permiso, cerraremos el formulario antes siquiera de abrirlo, para ello, al llamarlo le pasaremos el nombre del formulario.

Public Sub Permiso(sNombreFormulario As String)

' Lo primero que haremos es cargar el usuario activo
Dim sUsuarioActivo As String
sUsuarioActivo = DLookup("IdUsuario", "tblUsuarioActivo")

' A continuación buscaremos de la tabla "tblUsuariosPermisos"
' que dice el campo "acceso" de ese formulario del usuario
' activo. Para ello usamos el Dlookup añadiendo los
' filtros por IdUsuario y Nombre del Formulario

Dim bPermisoFor As Boolean
bPermisoFor = DLookup("Acceso", "tblUsuariosPermisos", "IdUsuario= '" _
& sUsuarioActivo & "' AND NombreFormulario= '" _
& sNombreFormulario & "'")
' Con un Si o un No, en la variable "bPermisoFor"
' tomamos una decisión.
If bPermisoFor = False Then 'Informamos al usuario y le cerramos el formulario.
Call MsgBox("Usted no tiene permisos para visualizar este formulario" _
," Contacte con el administrador", vbCritical, Atención)
DoCmd.Close acForm, sNombreFormulario
End If

' Logicamente si la variable es SI no hacemos nada y
' dejamos que el formulario siga abriéndose.
End Sub

Paso 7

El que haya llegado hasta aquí es un campeón porque mira que se me ha hecho extenso 🙂 . ¿Queréis verlo funcionar, verdad? pues vamos a dar el último paso. Vamos a crearnos un par de formularios. Para hacer mis pruebas han sido dos formularios en blanco, ya habrá lugar de asignarle origen de datos y meterles sus campos y demás, para el caso que nos ocupa, están vacíos. Les he llamado «frmAlmacen» y «frmVentas» tal y como queda reflejado en el paso 4 del tutorial.

Las siguientes líneas de código las he colocado en el evento «Al abrir» del formulario, comento esto porque también tenéis otro evento en los formularios que se llama «Al Cargar», la diferencia entre ellos es que «Al abrir» se produce antes de que se muestre el formulario en pantalla y el evento «Al cargar» cuando ya se muestra el formulario en pantalla con todos sus controles. Como veis, poniéndolo en el evento «Al abrir» tomamos la decisión antes de que se muestre en pantalla.

Private Sub Form_Open(Cancel As Integer)
'Llamos al procedimiento de nuestro módulo
'pasándole el nombre del formulario
Call Permiso(Me.Name)
End Sub

Funcionamiento

Al abrir el formulario llamamos al procedimiento «Permiso» que tenemos en el módulo, pasándole como parámetro el nombre de nuestro formulario, una vez pasado el testigo al procedimiento este cargará el usuario activo y comprobará si el permiso que le hemos puesto a ese usuario concreto y con ese nombre de formulario le permite abrir dicho formulario, en caso negativo, nuestro procedimiento cierra directamente el formulario avisando al usuario de que no puede abrirlo y que se busque un enchufe con el administrador para que le deje hacerlo.

Consideraciones finales

He resumido mucho el código para que sea fácil de entender pero me he dejado algunas cosas en el tintero, tampoco os lo voy a dar todo hecho ¿no? 🙂 algunas de las mejoras que debéis incorporar por ejemplo es el control de errores en todos los procedimientos, ¿Que pasa si se os ha olvidado asignar los permisos de un usuario concreto? pues que vuestro procedimiento no encontrará el nombre del formulario en la tabla «tblUsuariosPermisos» y os devolverá un bonito error. ¿Que pasa, por ejemplo, si os equivocáis al escribir el nombre del formulario cuando estáis asignando los permisos? pues al igual que antes que no lo encontrará y devolverá otro error, por lo que deberíais de implementar algún método para que la selección de los formularios en la asignación de permisos sea automática y no podáis cometer errores al escribirlo, ¿Que pasaría si……….? Pues eso, que podría tirarme horas y horas sacándole pegas y mejorando muchiiiiiiiiiiiiisimo la aplicación.

Eso precisamente, es lo que hace tan entretenido, provechoso y didáctico la labor de un programador y de la cual yo disfruto mucho.

Si estás interesado en aprender mas puedes solicitar información sobre nuestros cursos de programación orientada a objetos con Visual Basic para Access.

59 comentarios

  1. Hola Arturo, tienes razón, no funcionaba el enlace. Realmente no se había borrado solo que hace poco cambié la forma de nombrar las páginas del blog y los enlaces que ya habían siguen apuntando a la forma antigua. Ya lo he arreglado.

    Gracias por avisar del error.

    1. Amigo Angilmen… gracia por tu apoyo, fíjate que todo anda bien, menos la última parte de llamar al Permiso Call Permiso. Me da un error y medice que no espera un módulo, sino un procedimiento o variable… lo he hecho tal lo pusiste, pero no me sale… podrías sacarme del aprieto. gracias.

          1. FLSalinas. el problema es que el módulo tiene el mismo nombre que el procedimiento. Solución: renombra el módulo. A mí me funcionó.
            Saludos.

            Dario
            desde Argentina.

  2. Por que me sale error y me dice que » se esperaba: fin de la instrucción»

    sSQL = «UPDATE tblUsuarioActivo SET » _
    «tblUsuarioActivo.IdUsuario = ‘» & Me.txtIdUsuario & «‘»

    1. ayuda yo tengo el mismo problema me sale error
      sSQL = «UPDATE tblUsuarioActivo SET » _
      «tblUsuarioActivo.IdUsuario ='» & Me.txtIdUsuario & «‘»

      error de compilación
      los comentarios solamente pueden aperecer después de end sub,end fuction o end property

      aque se deberá gracias

    2. Hola como estas, acuerdate que & sirve como pegamento entre dos expresiones
      SQL = “UPDATE tblUsuarioActivo SET ” _
      & “tblUsuarioActivo.IdUsuario = ‘” & Me.txtIdUsuario & “‘”
      al añadirlo tu código funcionará

    3. Me dio el mismo error y le eché un poco de cocoloco y lo resolví así: luego de SET borré las comillas, eliminé esa sublínea y subí el tblUsuarioActivo.IdUsuario =…. y sí funcionó. Suerte.

  3. Hola,

    Primero que todo agradecerte por el granito de arena que aportas a todos los que iniciamos en el mundo de las Base de Datos en Access, ha sido de mucha ayuda en mi aprendizaje.

    Por otro lado quería preguntar si esta «gestión de usuarios avanzada» podría funciona en multiusuario, es decir cuando la Bd es dividida (Front-End yBack-End) y son varios los usuarios que ingresan.

    Gracias

    1. Por supuesto que te vale para un entorno de red. De hecho está pensado para eso más que para varios usuarios en un mismo PC.

      Te animo a que lo pruebes.

  4. Hola! muy buena página, pero tengo una duda en el código del botón aceptar, cuando dices que se guarda en la tabla UsuarioActivo, no se guarda si no que se actualiza cada vez, la pregunta es ¿Se puede guardar el usuario con la fecha y la hora?, no sé programar así que si puedes ayudarme te lo agradecería mucho 🙂

    1. Hola Daniela, efectivamente, en este ejemplo no se añade el usuario sino que se actualiza en el único registro de la tabla con el objetivo de saber en todo momento que usuario es el que ha iniciado en la base de datos.
      ¿Se puede guardar el usuario para llevar un registro completo de quien inicia la base de datos? por supuesto pero ello daría para otro artículo. Lo tengo en cuenta y en cuanto disponga de un hueco para el siguiente artículo te hago el ejemplo.
      Un saludo.

      1. Pero es muy complicado? porque este tutorial es el que he encontrado mejor explicado y en este me base para hacer la parte de la gestión de usuarios para la BD de la empresa donde estoy haciendo la práctica. Y eso me lo pidieron, pero como te digo mi conocimiento de VisualBasic es nulo, me manejo en Access y tampoco a un 100%, si puedes ayudarme te lo agradecería! 🙂

        1. No lo es, solo que necesito un rato para hacerlo y ando un poco liado. Como te dije, lo tengo en cuenta.

  5. ante todo gracias por compartir tus conocimientos.

    desearía mucho recibir las actualizaciones del tema en mención a acces y al ejemplo expuesto.

    muchas gracias por tu apoyo

    Alex

  6. Te agradezco mucho que hayas dedicado un poco de tu tiempo para compartir tu conocimiento. Tu post está excelente, más claro no creo que pueda estar. Me sirvió en gran manera en la aplicación que estoy programando, en realidad solo soy un aficionado en la programación.

    JUAN: En lugar de escribir el nombre del formulario debes escribir el nombre del informe o consulta en la tabla de los permisos, y el código que se escribe al abrir el formulario (la función que está en el módulo), debes escribirlo también al abrir el informe o la consulta que quieres.

    Saludos desde Ciudad Guatemala!

  7. Me queda una duda, ¿¿cómo le hago para que el usuario activo pueda cambiar su contraseña??

    Corrijo mi opinión quie le dì a Juan, el código de llamar la función de Permisos se debe escribir en el «Comand Button» para abrir el informe o consulta. Espero ahora estar en lo correcto. Soy un programador aficionado.

  8. Muchas gracias amigo, excelente aporte, me hizo sufrir la última parte, pero se logró maestro de maestros, muy bueno de los que he visto anteriormente.

    Private Sub cmdAceptar_Click()

    If IsNull(DLookup(«IdUsuario», «tblUsuarios», «IdUsuario = ‘» & Me.txtIdUsuario & «‘»)) Then
    Call MsgBox(«El usuario no existe en nuestra base de datos.», vbCritical, «Atención»)
    Exit Sub
    End If

    Dim sContraseña As String
    sContraseña = DLookup(«Contraseña», «tblUsuarios», «IdUsuario = ‘» & Me.txtIdUsuario & «‘»)

    If sContraseña = Me.txtContraseña Then

    Dim sNombre As String
    sNombre = DLookup(«Nombre», «tblUsuarios», «idUsuario= ‘» & Me.txtIdUsuario & «‘»)
    Call MsgBox(«Bienvenido » & sNombre & «,puede acceder al sitema.», vbInformation, «Datos correctos»)

    Dim sSQL As String
    sSQL = «UPDATE tblUsuarioActivo SET » & «TblUsuarioActivo.IdUsuario = ‘» & Me.txtIdUsuario & «‘»
    DoCmd.SetWarnings False
    DoCmd.RunSQL sSQL
    DoCmd.SetWarnings True
    DoCmd.Close
    Else
    Call MsgBox(«La contraseña es incorrecta. Vuelva a intentarlo.», vbExclamation, «Datos correctos»)
    Me.txtContraseña.SetFocus
    End If

    End Sub

    Private Sub cmdCancelar_Click()
    DoCmd.Quit

    End Sub

    Esta es el módulo.

    Option Compare Database
    Public Sub Permiso(sNombreFormulario As String)
    Dim sUsuarioActivo As String
    sUsuarioActivo = DLookup(«IdUsuario», «tblUsuarioActivo»)

    Dim bPermisoFor As Boolean
    bPermisoFor = DLookup(«Acceso», «tblUsuariosPermisos», «IdUsuario= ‘» & sUsuarioActivo & «‘ AND NombreFormulario= ‘» & sNombreFormulario & «‘»)

    If bPermisoFor = False Then
    Call MsgBox(«Usted no tiene permisos para visualizar este formulario. Contacte con el administrador.», vbCritical, Atención)
    DoCmd.Close acForm, sNombreFormulario

    End If

    End Sub

    1. Saludos y aprobechando el comentario te agradesco por tu tiempo que empleaste para darno esta introduccion en el VBA, que he de mucha ayuda para mi.

      Ahora bien en la siguiente linea de codigo 13 me aparece el siguiente error: Error 94 en tiempo de ejecucion si me pueden ayudar a la mayor brevedad. entiendo con facilidad las infomaciones.

  9. Hola,

    En primer lugar queria agradecerte el aporte ya que lo considero bastante bueno. Yo estoy desarrollando una aplicación y únicamente me falta aplicar la gestión de usuarios (va a ser un entorno multiusuario). La forma que tengo pensada varia un poco respecto al ejemplo pero me resuelve la gran duda que tenia que era donde guardar el nombre de usuario para gestionar los permisos de dicho usuario dentro de la aplicación.

    En tu ejemplo lo haces creando una tabla con el nombre del usuario activo. Buena idea! y para un único usuario esta genial actualizas el campo y ya esta…pero ¿que ocurre si varios usuarios acceden al mismo tiempo?

    Es decir, si solo se actualiza un campo usuario y accedemos dos usuarios al mismo tiempo puede ocurrir que un usuario acceda a formularios para los cuales no tiene permisos no? Voy a intentar ser más gráfico.

    1. Juan accede al sistema
    2. La tabla usuarios activos carga a Juan como usuario activo
    3. Juan sigue navegando por los formularios del sistema
    4. Diego entra al sistema. (Diego tiene más privilegios que Juan)
    5. La tabla usuarios activos se actualiza con Diego — cargando sus permisos
    6. Juan sigue navegando por el sistema y hace click en un formulario que no tiene permisos pero Diego si…al estar cargado el perfil de diego, juan podría acceder a dicho formulario para el cual no tiene derechos no?

    Si no estoy en lo cierto, me gustaría que me aclarases mi error.

    En caso contrario la alternativa seria crear varios usuarios activos…pero entonces me surge la duda de como saber cual es el usuario que quiere acceder al formulario, es decir, si juan y diego aparecen en la tabla de usuarios activos…¿cómo se cual de los dos usuarios es el que quiere acceder a un formulario concreto para comprobar si tiene permisos o no?

    Muchas gracias de antemano por tu ayuda con estas dudas que tengo.

    Muchas gracias.

    1. Esa tabla, donde guardasen usuario activo, debe estar en el front-end y no en una tabla vinculada. De esa forma cuando guardes el usuario en la tabla lo estarás haciendo solo en el ordenador donde estas ejecutando el programa y no en el servidor.

      1. Muy buenas tardes, no entiendo mucho esta parte.
        pero para mi caso tengo la base de datos divida en cliente y servidor, he hecho la prueba en donde todos acceden a la misma cliente y quedan varios registros de los que accedieron a la base, esto podría funcionar si la cliente es independiente en cada PC, mas no si la cliente es única y todos los usuarios acceden a ella.
        No se si exista la posibilidad de guardar el idusuario en memoria y asi poder usarlo.

  10. Saludos y aprobechando el comentario te agradesco por tu tiempo que empleaste para darno esta introduccion en el VBA, que he de mucha ayuda para mi.

    Ahora bien en la siguiente linea de codigo 13 me aparece el siguiente error: Error 94 en tiempo de ejecucion si me pueden ayudar a la mayor brevedad. entiendo con facilidad las infomaciones.

  11. Buenos dias

    He seguido tus instrucciones para crear un gestion de usuarios en una base de datos que estoy creando.

    Todo funciona perfecto, a excepcion de que me da un error al cargar cualquier usuario me da

    Error de Compilacion
    Error de Sintaxis

    y me sale automaticamente el codigo del boton aceptar con estas dos lineas remarcadas

    sSQL = «UPDATE tblUsuarioActivo SET » _
    «tblUsuarioActivo.IdUsuario = ‘» & Me.txtIdUsuario & «‘»

    Podrias ayudarme ?? Que estoy haciendo mal ??

    Gracias

    1. El problema lo tienes en el salto de libra que haces.

      Tras el «_» en la siguiente línea debes indicarle que es continuación de la anterior. Empieza la segunda línea con & y a ver qué tal.

      1. Gracias campeón………………….. eres el number one, crack

        Aprovecho para “molestarte” con un par de cuestiones más :

        1) Si en este modelo, que funciona a la perfeccion, tenemos al usuario A con unos permisos o unas limitaciones correspondientes al usuario A, y desde otro equipo entra el usuario B con sus correspondientes permisos y limitaciones, que ocurre?? No hay conflictos ¿?? Gracias, y
        2) Estoy diseñando una base de datos para una ONG que tendrá alrededor de 1.000 usuarios activos, podrias decirme como puedo hacer para que a cada registro que se visualice en un determinado formulario (el formulario de Usuarios en este caso), le asigne su correspondiente “foto” que estará en una carpeta dentro del mismo directorio de la BBDD, de manera tal que:
        – Pongamos que los usuarios tienen un código en formato 01xxxxx, y que en la carpeta de las fotos existe la foto de cada uno de ellos en formato 01xxxx. (jpg, jpeg, bmp o cualquier otra extensión asociada a un archivo de imagen), evidentemente todos con la misma extensión.

        Como puedo hacer para que a cada cambio de registro en el formulario, me aparezca la foto de la persona en cuestión ¿??

        Se que puede ser un trabajazo, pero si no puedes…. Podrias enviarme algún enlace donde esté explicado ?

        Gracias por todo crack
        Saludos
        Rafa

  12. Buenos días, querría hacer una pregunta que quizás se vaya de madre, pero seguro que el nivel con el que trabajas lo sabrás contestar.
    En cada registro que tengo creado hay un campo que es usuario. Es decir, el formulario es igual para todos, pero cada uno tiene que indicar que usuario lo ha creado y el problema es que cualquiera puede cambiar este registro y cambiarlo de usuario, a parte de que ya no me interesa que un usuario A, pueda ver los clientes del usuario B.
    Cómo podría hacer para que al entrar con el usuario determinado, sólo pueda ver los registros relacionados con él mismo y no con todos.

    Muchas gracias de antemano.

    1. Hola, eso que pretendes no es complicado pero si tienes que elaborarlo. En líneas generales puedes crear una tabla donde guardar el nombre del usuarios que inicia el sistema. Esa tabla tendría que estar en la base de datos local, suponiendo que la tengas compartida en red, o sea, en el front-end. Cuando inicias la aplicación, validando al usuario, podrías aprovechar para copiar sus datos en esa tabla. Con esto ya tiene el nombre o el ID de la persona que está usando la aplicación. Cada vez que creas un registro nuevo, mediante código o alguna consulta, o simplemente configurando el valor predeterminado, hay varias formas de hacerlo, puedes recuperar el nombre del usuario o, preferiblemente su ID, para guardarlo en ese registro.
      Sobre como hacer para que cada usuario vea sólo sus datos tendrías que jugar con las consultas que muestran los datos en los formularios para filtrar las que pertenezcan a uno u otro.

      Con paciencia puedes elaborar el sistema, todo dependerá de lo avanzada que tengas la base de datos que te obligará a realizar más o menos trabajo.

  13. Hola,
    Antes que nada agradecerte estos aportes tan valiosos. Poder avanzar en nuestras bases de datos, con tus explicaciones detalladas y ejemplos, es una gozada.
    Mi consulta es, tengo una base de datos con un menú inicial, a la que voy a incorporar los usuarios. Me gustaría que, además de los permisos, según el usuario que acceda a la bd ya empiece con un menú más completo u otro más simple. ¿Alguna pista de qué código añadir? Muchas gracias.

  14. Hola, me encuentro con que necesito tener una base de datos a la cual han de acceder clientes para insertar datos. La idea que tenia hasta el momento era, creación de usuarios como has explicado tu para que solo ciertos usuarios puedan acceder a sus formularios y seguidamente dividir la base de datos para tener el fe y el be, de manera que cifro por contraseña el BE y así no pueden ver la información de las tablas.
    El problema que tengo es que al cifrar el BE e intentar acceder con el usuario y contraseña no me deja, me sale el error 3031 indicando que no es una contraseña valida, este problema me sale únicamente al cifrar el BE, a ver si me podrías ayudar. Gracias.

    Por otro lado, como quistión secundaria me gustaría saber si también puedo cifrar u ocultar los Módulos a los clientes, ya que mi intención es que el cliente únicamente tenga acceso a los formularios a los que pueda acceder y nada mas.

    1. Hola. Algo estás haciendo mal. Cuando cifras el be solo necesitas una contraseña para acceder a él, no un usuario.

      1. No me he explicado bien. Empiezo desde cero. Yo he creado la gestión de usuarios como se explica en este post, en el cual tengo las tablas necesarias y además tengo otras tablas con información «confidencial». Todo el tema explicado en este post va bien para filtrar los accesos a otros formularios.
        Ahora lo que yo he querido realizar ha sido dividir mi base de datos, de manera que tengo el FrontEnd, con los formularios y las tablas vinculadas y el BackEnd con las tablas. Al BackEnd lo cifro con una contraseña para que a no ser que se sepa la contraseña no puedan acceder al contenido de las tablas.
        Mi error viene cuando desde el FrontEnd, al abrir la base de datos, me aparece el formulario de Login y al introducir el usuario y contraseña para acceder a los formularios me sale el error 3031 ese que te he comentado.
        No se si me explico del todo bien.

        1. Ahora sí. Has dividido la base de datos antes de poner la contraseña al backend por ello, tu frontend no la conoce. Debes revincular nuevamente el frontend. Busca en los menús de Access la opción de tablas vinculadas y te aparecerá un listado con todas las tablas vinculadas que tienes actualmente. Tendrás que seleccionarlas todas y darle a vincular, en ese momento te debe pedir la contraseña que tiene el backend. Una vez la pongas ya no te la volverá a pedir más.
          Saludos.

          1. No me deja realizar la vinculación una vez asignada la contraseña al backend. Me sigue diciendo que la contraseña no es valida, directamente no me deja poner la contraseña.

          2. Por otro lado, si realizo el cifrado antes de dividir la base de datos, al acceder al front end me pide la contraseña, yo lo que quiero es que los usuarios no accedan a las tablas pero si a sus respectivos formularios.
            Siguiendo la gestión de usuarios que has explicado en este post hay alguna manera de bloquear el acceso a las tablas? Algo similar a la gestión de usuarios por roles, por ejemplo yo entro con admin1 el cual ha de poder visualizar todo, pero si entro con user1 solo ha de poder ver y acceder al formulario1.

          3. Las tablas siguen siendo accesibles desde el front-end. Depende de ti que configures el front-end para que el usuario no sea capaz de «visualizar» las tablas. Hay soluciones para eso también.

          4. Me podrías dar alguna recomendación para hacerlo? Te explico lo que necesito y si me puedes ayudar genial.
            Necesito una base de datos en Access en la que tenga varias tablas accesibles únicamente por administradores y seguidamente formularios para realizar diferentes consultas. Por ejemplo tengo un formulario para que la empresa X visualice información sobre sus pedidos y otro formulario donde la empresa Y visualice información sobre ellos pero que no puedan verse entre ellos.
            Muchas gracias de antemano.

          5. Lo que tú necesitas es complejo para poder resumirlo en una respuesta por aquí. Mi recomendación es que aproveches los recursos que tienes, entre otros lo que yo he escrito aquí, y con ello vayas dándole forma. Donde más apoyo encontrarás es en los foros. Un blog no es el mejor medio para responder dudas, sin embargo, los foros están llenos de respuestas a dudas que otros, antes que tú, han tenido y encontraras más expertos en Access dispuestos a colaborar para ayudarte. No es que yo no quiera hacerlo pero es quiere seas muchas de esas dudas y yo no siempre estoy on-line. En este blog hay enlaces a foros donde encontraras esa ayuda, incluso yo me muevo por ellos y estaré encantado de ayudarte por allí.
            Saludos.

    2. Respecto a los módulos no comprendo muy bien la pregunta. Si te refieres a los módulos de código VBA, desde el mismo editor tienes la opción de ponerles contraseña y, aunque el módulo sea visible no podrán acceder a su contenido.

    3. Quizas no me he explicado bien. Yo tengo una base de datos en la que he realizado todo el tema de gestión de usuarios, para permitir que por ejemplo usuario1 pueda acceder al formulario1 solamente y usuario2 pueda acceder a formulario2. Ahora lo que quiero realizar es que tampoco puedan acceder a las tablas creadas.
      La idea principal era dividir la base de datos, de forma que me queda el backend con las tablas y el frontend con las tablas vinculadas y los formularios. Si lo dejo de esta manera, sin cifrar el backend, el tema de los usuarios me sigue funcionando, peor si cifro el backend, el frontend me deja de funcionar, saliendo todo el rato el error 3031 mencionado.

  15. Buen dia!! muchas gracias por la info!!esta excelente. Salvo un detalle, segui al pie todo, y cuando le asigno los permisos y reviso que el usuario activo quede bien grabado, no me permite abrir ningun formulario. Por que puede ser? el usuario activo queda bien grabado, los permisos estan bien asignados y el modulo esta exactamente igual.
    Cargue en todos los formularios la sentencia para que llame al modulo permiso y no me deja entrar a ninguno…
    que podria estar mal??

    1. Hola me sucede exaptamente lo mismo. no se como hacer para que al colocar el usuario y contraseña se abra el furmulario designado. porfavor si lo resolviste comentame. gracias.!

  16. Hola, buenas tardes, todo excelente pero me sale un error que dice :
    – Se ha producido el error 13 en tiempo de ejecución:
    No coinciden los tipos

    Alguien me podría ayudar por favor , seguí las instrucciones al pie de la letra pero no consigo que quede.

    Gracias de antemano

  17. Hola buenas tardes. pido disculpa por mi ignoracia sobre el tema, me es completamente nuevo este tema de profundizar en access. Primeramente gracias al creador un excelente aporte y de gran ayuda. Pero tengo un pequeño problema. He echo todo al pies de la letra y todo parece estar bien. Pero me ha de faltar algun detelle que no consigo hacer que al loguearse el usuario me abra automenticamente el formulario al que debe dirigirse…. Porfavor agradezco toda ayuda al respecto, Gracias desde ya.

  18. Hola Ángel, aunque hayan pasado unos años de esta entrada, espero puedas ayudarme, te explico.
    En el módulo me da un error,
    Se ha producido el error 94 en tiempo de ejecución:
    Uso no válido de Null
    Y el error me lo marca aquí
    bPermisoFor = DLookup(«Acceso», «tblUsuariosPermisos», «IdUsuario= ‘» _
    & sUsuarioActivo & «‘ AND NombreFormulario= ‘» _
    & sNombreFormulario & «‘»)
    Espero puedas ayudarme

  19. hola,una consulta,si tengo un mismo usuario que tiene acceso a dos formularios,como se podria hacer en la tabla permisos,trate de ponerlo en la tabla permisos el id ususrio y el nombre del otro formulario con acceso,pero dice q no acepta duplicados,por favor como se haria,gracias.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.