Aplicación en access 2007 para el control de usuarios

Este es el código que utilizo para validar el ingreso de los usuarios, a la hora de ingresar necesito que me abra un formulario por cada usuario que tenga registrado en base de datos, ya que cuento con 30 usuarios y un administrador del sistema.

Dim rst As New ADODB.Recordset
Dim stDocName As String
Dim stLinkCriteria As String
Private Sub Cmd_Ingresar_Click()
If Not IsNull(Me.txt_usuario) And Not IsNull(Me.txt_contraseña) Then
rst.Open "SELECT * FROM [Usuarios]" & _
"WHERE [usuario] ='" & Me.txt_usuario & "' AND [contraseña] = '" & Me.txt_contraseña & "' ORDER BY [usuario]", CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdText
If rst.RecordCount > 0 Then
If CBool(rst![administrador]) Then
DoCmd.OpenForm "Form2", , , stLinkCriteria
End If
If CBool(rst![contable]) Then
DoCmd.OpenForm "Form3", , , stLinkCriteria
End If
If CBool(rst![producto]) Then
DoCmd.OpenForm "Form4", , , stLinkCriteria
End If
If CBool(rst![ventas]) Then
DoCmd.OpenForm "Form5", , , stLinkCriteria
End If
If CBool(rst![operaciones]) Then
DoCmd.OpenForm "Form6", , , stLinkCriteria
End If
Else
MsgBox "Usuario y contraseña invalidos", vbCritical, "Mensaje de Error"
End If
rst.Close
Set rst = Nothing
Else
MsgBox "Debe colocar el usuario y la contraseña", vbCritical, "Mensaje de Error"
End If
End Sub

1 Respuesta

Respuesta
1

1. El modo natural de trabajar con recordsets en Access es mediante DAO. Trabajar con ADo, si bien es posible, es forzar a un trabajo menos efectivo. Obviamente no tendrá repercusiones en pocos registros pero ya puestos hagámoslo bien.

Dim rst As DAO.Recordset

Set rst = CurrentDb.OpenRecordset(laSQL)

2. Parece que abres el recordset de usuario y, en función de los valores de administrador, contable, producto, ventas y operaciones abres uno u otro formulario. Si un usuario tuviera todos esos permisos se le abrirían varios formularios por lo que intuyo que no debe ser así. Enese caso no entiendo porque no se utiliza un solo campo (llamado por ejemplo Rol) que te discrimine eso. Si ese campo Rol lo relacionas con un formulario (en una tabla), la cosa se simplifica.

3. Veo una variable stCriteria declarada y utilizada en el OpenForm pero no veo dónde se asigna dicha variable

4. If Not IsNull. En esos casos casi es mejor tratarlo como cadenas vacías. Un cuadro de texto puede parecer nulo cuando en realidad es una cadena vacía o incluso un espacio. Para evaluar las 3 posibilidades de golpe se utiliza una combinación de 2 funciones: Nz para convertir el nulo a "algo" y Trim para quitar espacios. If Trim(Nz(elcampo, "")) = "" Then ... nulo, vacío o espacios.

Resumiendo (y dando por supuesto el punto 2)

Dim rst As ADO.Recordset

Dim stDocName As String

Dim stLinkCriteria As String

Private Sub Cmd_Ingresar_Click()

' Evaluamos si se han rellenado los campos (se podría hacer en otro procedimiento que sólo se activara el botón ingresar cuando ambos campos estuvieran rellenados)

If Trim(Nz(Me!txt_usuario, "")) = "" Or Trim(Nz(Me!txt_contraseña, "")) = "" Then

MsgBox "Debe colocar el usuario y la contraseña", vbCritical, "Mensaje de Error"

Exit Sub

End If

Set rst = CurrentDb.OpenRecordset("SELECT * FROM [Usuarios] WHERE [usuario] ='" & Me!txt_usuario & "' AND [contraseña] = '" & Me!txt_contraseña & "' ORDER BY [usuario]"

If rst.EOF Then

MsgBox "Usuario y/o contraseña inválidos", vbCritical, "Mensaje de Error"

rst.Close

Set rst = Nothing

Exit Sub

End If

Dim strFormulario As String

strFormulario = DLookup("Formulario", "Roles", "IdRol=" & rst!Rol)

DoCmd. OpenForm strFormulario

Rst. Close

Set rst = Nothing

¿Te vale?

Que tal gracias por el aporte, pero me surgen dudas tengo que crear una tabla con los usuarios y otra con el rol, o en la de usuarios tengo que poner rol para cada usuario.

así quedaría el código, la verdad soy aprendiz en esto de la programación.

Dim rst As ADO.Recordset
Dim stDocName As String
Dim stLinkCriteria As String
Private Sub Cmd_Ingresar_Click()
If Trim(Nz(Me!txt_usuario, "")) = "" Or Trim(Nz(Me!txt_contraseña, "")) = "" Then
MsgBox "Debe colocar el usuario y la contraseña", vbCritical, "Mensaje de Error"
Exit Sub
End If
Set rst = CurrentDb.OpenRecordset("SELECT * FROM [Usuarios] WHERE [usuario] ='" & Me!txt_usuario & "' AND [contraseña] = '" & Me!txt_contraseña & "' ORDER BY [usuario]"
If rst.EOF Then
MsgBox "Usuario y/o contraseña inválidos", vbCritical, "Mensaje de Error"
rst.Close
Set rst = Nothing
Exit Sub
End If
Dim strFormulario As String
strFormulario = DLookup("Formulario", "Roles", "IdRol=" & rst!Rol)
DoCmd.OpenForm strFormulario
rst.close
Set rst = Nothing

este código lo tengo que poner en el boten de ingresar para que ala hora que el usuario le de clic se ejecute.

En pocas palabras me podrás decir como aplico este código por favor

Primero decirte que me equivoqué en (al menos) una línea. Yo vendiéndote el tema de DAO y voy y declaro mal el recordset

Dim rst As DAO.Recordset

En cuanto a las tablas. Necesitas una tabla de Roles con el IdRol (autonumérico), la descripción (texto) y el nombre del formulario asociado.

En la tabla de usuarios añades el campo IdRol de forma que cada usuario tenga uno asignado.

Y si, ese código va al botón de ingresar.

mira estos son los campos que contienen mis tablas:

Tabla usuarios

IdRol Autonumérico

usuario Texto

contraseña Texto

Tabla Roles

IdRol Autonumérico

descripción Texto

nom_formulario Texto

La relación entre las tablas es el IdRol de usuarios con IdRol de la tabla roles.

y el código

Dim rst As DAO.Recordset
Dim stDocName As String
Dim stLinkCriteria As String
Private Sub Cmd_Ingresar_Click()
If Trim(Nz(Me!txt_usuario, "")) = "" Or Trim(Nz(Me!txt_contraseña, "")) = "" Then
MsgBox "Debe colocar el usuario y la contraseña", vbCritical, "Mensaje de Error"
Exit Sub
End If
Set rst = CurrentDb.OpenRecordset("SELECT * FROM [Usuarios] WHERE [usuario] ='" & Me!txt_usuario & "' AND [contraseña] = '" & Me!txt_contraseña & "' ORDER BY [usuario]"
If rst.EOF Then
MsgBox "Usuario y/o contraseña inválidos", vbCritical, "Mensaje de Error"
rst.Close
Set rst = Nothing
Exit Sub
End If
Dim strFormulario As String
strFormulario = DLookup("Formulario", "Roles", "IdRol=" & rst!Rol)
DoCmd.OpenForm strFormulario
rst.close
Set rst = Nothing

nuevamente molestándote espero me vuelvas ayudar o aclarar mis dudas.

grs.

jose luis

Me parece que lo único a cambiar es la linea

strFormulario = DLookup("Formulario", "Roles", "IdRol=" & rst!Rol)

dónde debes cambiar el valor a recuperar:

strFormulario = DLookup("nom_formulario", "Roles", "IdRol=" & rst!Rol)

Por cierto, estas dos líneas no me parecen necesarias:

Dim stDocName As String

Dim stLinkCriteria As String

molestándote de nuevo a la hora de ejecutar la aplicación me marca este error.

La expresión 'Al hacer clic' que ha especificado como valor de la propiedad de evento produjo error El miembro ya existe en un modulo de objeto del que proviene.

*La expresión no da como resultado el nombre de una macro, de una función definida por el usuario o [Procedimiento de evento].

*Hubo un error al evaluar la función, evento o macro.

Este error se produce cuando un evento no se ha podido ejecutar debido a que Microsoft Office Access no puede evaluar la ubicación de la lógica del evento. Por ejemplo, si la propiedad OnOpen de un formulario se establece en =[Field], este error se produce porque Access espera que se ejecute un nombre de macro o evento al desencadenarse el evento.

nuevamente me podrías ayudar.

En la hoja de propiedades, en la pestaña eventos, para la propiedad Al hacer clic, ¿qué pone?

Debería poner [Procedimiento de evento] y, al clicar en el botón generador (el de los ···) llevarte justo al código que hemos desarrollado.

¿Es así?

hay 3 opciones:

generador de macros

generador de expresiones

generador de código

y selecciono la de generador de codigo

y ahí coloco el código que me enviaste .

Efectivamente.

Este es el código que debería funcionar una vez corregido todo lo que hemos ido viendo

Dim rst As DAO.Recordset

If Trim(Nz(Me!txt_usuario, "")) = "" Or Trim(Nz(Me!txt_contraseña, "")) = "" Then

MsgBox "Debe colocar el usuario y la contraseña", vbCritical, "Mensaje de Error"

Exit Sub

End If

Set rst = CurrentDb.OpenRecordset("SELECT * FROM [Usuarios] WHERE [usuario] ='" & Me!txt_usuario & "' AND [contraseña] = '" & Me!txt_contraseña & "' ORDER BY [usuario]"

If rst.EOF Then

MsgBox "Usuario y/o contraseña inválidos", vbCritical, "Mensaje de Error"

rst.Close

Set rst = Nothing

Exit Sub

End If

Dim strFormulario As String

strFormulario = DLookup("Formulario", "Roles", "IdRol=" & rst!Rol)

DoCmd.OpenForm strFormulario

rst.close

Set rst = Nothing

Pon todo eso entre el Private Sub... y el End Sub

hola buenos dias molestandote desde temprano.

me sale nuevamente otro error:

Se ha produccido el error '3265' en tiempo de ejecucion:

No se encontro el elemento en esta colección.

en este apartado del codigo:

Dim strFormulario As String
strFormulario = DLookup("nom_formulario", "Roles", "IdRol=" & rst!Rol)   'en esta linea del codigo es donde me marca el error  "Formulario" lo cambie por "nom_formulario" por que asi lo tengo en mi tabla de Roles.
DoCmd.OpenForm strFormulario
rst.Close
Set rst = Nothing

Saludos

Ahora sólo falta indicar correctamente el campo del recordset (fallo mio)

....."IdRol=" & rst!IdRol)

Un saludo (y perdón por la demora)

Hola !!!!!!!

Gracias por corregirme el error ya lo probé y funciona perfectamente bien. El problema ahora es que como le hago para que cuando vuelva abrir este mismos formulario me aparesca limpo para que pueda volver a introduccir nuevos datos ya que a la hora de borrar esos datos que me muestra el formulario me los borra de mi tabla usuarios.

Espero me puedas ayudar nuevamente,

saludos.

Para que esto funcione correctamente el formulario dónde se ejecuta debe ser independiente. Es decir, la propiedad Origen del registro debe estar vacía.

A ver si es eso.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas