Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
MÚLTIPLES USUARIOS1
Para suplir esta carencia he desarrolla el ejemplo que ahora estáis leyendo. Ya os adelanto que
este es un ejemplo que no se puede recrear “a lo rápido”, puesto que hay bastantes variables a
tener en cuenta y la estructura resulta un tanto compleja. Evidentemente lo intentaré explicar
lo mejor y más claro que pueda, pero, como consejo, os diría que “tengáis los ojos bien
abiertos”
Cuando decía que el ejemplo está basado en el ejemplo “Entrada según administrador o
usuario” me refería a que se basa sólo en la “idea” de la utilidad del ejemplo. En seguida
vamos a ver cómo, prácticamente desde el comienzo, la operativa de programación es
bastante diferente. Así que... paciencia...
Para no liar la cosa reutilizando elementos de ese ejemplo original lo que haremos será
empezar de cero con la creación de la estructura. Mejor hacerlo así que indicaros las
diferencias entre uno y otro ejemplo, pues cabe la posibilidad de que “se me pase” algo, con lo
que la confusión podría ser monumental... je, je...
Finalmente, el ejemplo se desarrollará sobre una hipotética situación común en este “mundo
mundial”: tendremos unos trabajadores, a los que deberemos dar de alta, asignarles un
nombre de usuario, un password y definir su tipo de usuario, y a partir de ahí... ¡a trabajar!
1
Visítame en http://neckkito.siliconproject.com.ar
Hecho esto vamos a crearnos una segunda tabla que
gestionara la identificación del login, y que además nos
enlazará con los datos de TTrabajadores. A esta nueva tabla
la llamaremos TPass, y tendrá la siguiente estructura:
…
Private Sub cmdCerrar_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FMenu"
End Sub
…
2 Para asignar un nombre a un control lo que debemos hacer es sacar las propiedades de ese control e irnos a la Pestaña Otras →
Nombre. Ahí escribimos el nombre que queramos.
3 Para generar código debemos sacar las propiedades del control → Pestaña Eventos, y nos situamos en la parte “blanca” a la
derecha del evento que queremos programar. Veremos un pequeño botón de puntos suspensivos. Si hacemos click sobre él nos
aparecerá una ventana que nos pedirá qué operación deseamos realizar. Le indicamos que queremos “generar código”.
2
Visítame en http://neckkito.siliconproject.com.ar
A continuación vamos a crearnos otro formulario 4, basado
en la tabla TPass, que guardaremos como FDatosPass. Igual
que en el caso anterior añadimos un botón de comando en
el encabezado, le ponemos de nombre cmdCerrar y le
asignamos este código en el evento “Al hacer clic”:
…
Private Sub cmdCerrar_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FMenu"
End Sub
…
1.- Insertamos un cuadro combinado, al que pondremos de nombre cboUser. Cuando nos salga
el asistente lo configuraremos de la siguiente manera:
2.- Insertamos un textbox al que pondremos de nombre txtPass. Sacamos sus propiedades y
en Pestaña Datos → Máscara de entrada, escribimos PASSWORD
4 Según qué versión de Access tengamos, si hemos realizado correctamente las relaciones, es posible que al crear el formulario
FTrabajadores se nos haya creado, automáticamente, un subformulario relacionado con la tabla TPass. Podríamos dejar esa
estructura para gestionar, a la vez, datos de trabajadores y sus datos de password. En ese caso no importaría que creáramos
FDatosPass. Sin embargo, como hay versiones de Access que no realizan este proceso, en el ejemplo yo voy a seguir con el
método “tradicional” y voy a explicarlo cómo hacerlo a través de dos formularios separados.
5 Si no sabéis configurar ese formulario de inicio echad un vistazo a este artículo.
3
Visítame en http://neckkito.siliconproject.com.ar
El código que asignaremos a cmdCancelar en el evento “Al hacer clic” es:
…
Private Sub cmdCancelar_Click()
DoCmd.Quit
End Sub
…
El código que debemos asignar al botón cmdLogin, en el mismo evento que el anterior, es el
que os indicaré a continuación. Sin embargo, permitidme que antes os advierta de un par de
puntos interesantes para que, cuando examinéis el código, podáis entenderlo mejor:
• Vamos a recurrir a la sistemática del ejemplo “Formulario Chivato”. Por ello veréis que
en el código se hace una llamada para operar con FChivato y sus controles. Eso lo
explicaremos en un apartado posterior.
…
Private Sub cmdLogin_Click()
'Neckkito -- 13/04/13
'Declaramos las variables
Dim vUser As String, vPass As String
Dim vCompruebo As Variant
'Cogemos los valores introducidos
vUser = Nz(Me.cboUser.Value, "")
vPass = Nz(Me.txtPass.Value, "")
'Si no hay usuario avisamos y salimos
If vUser = "" Then
MsgBox "No ha introducido el nombre de usuario", vbExclamation, "SIN DATOS"
Exit Sub
End If
'Si no hay password avisamos y salimos
If vPass = "" Then
MsgBox "No ha introducido la contraseña", vbExclamation, "SIN DATOS"
Exit Sub
End If
'Buscamos la contraseña correcta en la tabla TPass según el usuario que ha accedido
vCompruebo = DLookup("Pass", "TPass", "NomUser='" & vUser & "'")
'Si vCompruebo no devuelve ningún valor es que el usuario introducido no existe
If IsNull(vCompruebo) Then
MsgBox "Usuario inexistente", vbExclamation, "NO EXISTE"
Exit Sub
End If
'Comprobamos si la contraseña introducida coincide con la de la tabla
4
Visítame en http://neckkito.siliconproject.com.ar
If vPass = vCompruebo Then
'Si coincide utilizamos vCompruebo para ver el tipo de usuario
vCompruebo = DLookup("TipoUser", "TPass", "NomUser='" & vUser & "'")
Else
'Si no coincide avisamos y salimos
MsgBox "La contraseña introducida no es correcta", vbCritical,
"INCORRECTO"
Exit Sub
End If
'Abrimos el formulario chivato en modo oculto
DoCmd.OpenForm "FChivato", , , , , acHidden
'Pasamos a los textbox los valores que nos interesan: tipo de usuario
y nombre de usuario
With Forms!FChivato
.txtTipoUser = vCompruebo
.txtNomUser = vUser
.txtIdTrab = DLookup("IdTrabPass", "TPass", "NomUser='" & vUser & "'")
End With
'Abrimos el formulario FMenu
DoCmd.OpenForm "FMenu"
'Comprobamos cómo debemos abrir el menú principal: si para admin o para user
If vCompruebo = 2 Then '2=usuario normal
'Realizamos el maquillaje del formulario
With Forms!FMenu
.imgLogo.Visible = True 'Mostramos la imagen
.cmdAbreFTrabajadores.Visible = False 'Ocultamos el botón para dar de alta trabajadores
.cmdAbreFDatosPass.Visible = False 'Ocultamos el botón para dar de alta los datos del pass
.cmdAbreFMenuAdmin.Visible = False 'Ocultamos el botón para acceder al menú de administrador
End With
End If
'Cerramos el formulario FPass
DoCmd.Close acForm, Me.Name
End Sub
…
Y ya está. Lo que harán estos textbox será guardarnos la información del usuario que ha
entrado en la BD, información que vamos a necesitar para poder operar con formularios,
consultas e informes6.
Aviso: si vais a hacer testeos en vuestra BD es importante que FChivato esté cargado y
con información en los textbox. Pensad que cualquier acción que vayamos a programar, antes
6 El textbox que hemos llamado txtNomUser no lo vamos a utilizar durante el ejemplo. Sin embargo, lo dejamos ahí por si, en algún
momento de vuestra aplicación, necesitarais conocer ese dato. Además, refuerza la idea de que en FChivato podemos guardar
cualquier información que necesitemos durante la sesión del usuario que entre en la BD. Por ejemplo, podría interesarnos
discriminar por el año de trabajo (si queremos filtrar por un campo que nos dé el año de trabajo). En ese caso simplemente
añadiríamos el txtAnoTrab y llevaríamos ahí el año de trabajo que el usuario hubiera seleccionado. Os lo dejo como sugerencia.
5
Visítame en http://neckkito.siliconproject.com.ar
de realizarse, va a “consultar” el tipo de usuario y su nombre, y esa información la sacará de
FChivato. Si FChivato no está cargado y con valores vamos a obtener siempre un error.
Os doy una idea para confeccionar la estructura de este formulario (es sólo una idea. La podéis
aplicar o no. No influye para nada en la mecánica del ejemplo). Se trata de dividir en dos
partes, verticalmente, el conjunto de botones que vamos a utilizar: a un lado pondremos los
botones que sólo pueda ver el usuario y al otro los botones que sean comunes.
OK. Si lo dejamos así nuestro menú, de cara a un usuario “normal”, va a parecer que el
formulario está “descentrado”. Para corregir eso elegiremos una imagen (el logotipo de la
empresa, nuestra foto... je, je...). Situaremos esa imagen cubriendo la botonera de uso
exclusivo del administrador, enviándola al fondo (de manera que los botones queden encima de
la imagen).
Os pongo una ilustración para que veáis lo que quiero decir, y que además me servirá de base
para haceros referencia a los botones un poco más adelante.
Como el ejemplo es “complejo”, para que entendáis y aprendáis el funcionamiento del sistema
vamos a contemplar, en el epígrafe siguiente, varios puntos que será necesario desarrollar. Sin
embargo, ya que tenemos nuestro FMenu delante, vamos a definir algunas características de
los controles:
Sacamos las propiedades de la imagen y le ponemos de nombre imgLogo. Nos vamos, en esas
mismas propiedades, a la pestaña Formato → Visible, y le situamos la propiedad en NO.
6
Visítame en http://neckkito.siliconproject.com.ar
El botón que veis como “Alta trabajadores” tendrá de nombre cmdAbreFTrabajadores. En su
evento “Al hacer clic” le generaremos este código:
…
Private Sub cmdAbreFTrabajadores_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FTrabajadores", , , , acFormAdd
End Sub
…
El botón “Alta datos acceso”, llamado cmdAbreFDatosPass, tendrá una estructura muy similar
de código:
…
Private Sub cmdAbreFDatosPass_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FDatosPass", , , , acFormAdd
End Sub
…
El botón que veis como “Menú Administrador” es simplemente una idea que os propongo para
no cargar el formulario principal. La esencia de la propuesta sería crearnos un formulario en
blanco, llamarle, por ejemplo, FMenuAdmin, y en él añadir todos los botones de que queramos
para el administrador. De esta manera tendríamos los botones de trabajo más habituales en
FMenu y los botones no tan habituales en FMenuAdmin.
…
Private Sub cmdAbreFMenuAdmin_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FMenuAdmin"
End Sub
…
Al resto de botones, por ahora, nos limitaremos a ponerles nombre. Así, tendremos que:
Veremos cómo podemos operar con tres elementos: Formularios, Consultas e Informes, y las
particularidades de cada caso.
Tened en cuenta que en este ejemplo yo os voy a explicar lo que considero que podría ser
“más típico”. Lo digo en el sentido de que no os quedéis con la idea de que “sólo se puede
7
Visítame en http://neckkito.siliconproject.com.ar
hacer lo que se indica en este ejemplo”. Se pueden hacer muchas más cosas, pero
evidentemente me saldría un “tocho” de ejemplo.
Vamos a crearnos una tabla que llamaremos TProyectos, con la siguiente estructura:
Sobre esta tabla nos crearemos un formulario, que llamaremos FProyectos. Una vez lo
tengamos creado vamos a realizar los siguientes cambios:
Para que os hagáis una idea a mí me ha quedado como podéis ver en la imagen:
8
Visítame en http://neckkito.siliconproject.com.ar
Finalmente, vamos a crearnos, sobre la tabla TProyectos, un informe que llamaremos
RProyectos. Nos lo construiremos utilizando el asistente, que configuraremos de la siguiente
manera:
Como el informe nos muestra el identificador del trabajador, y no su nombre, lo que haremos
será:
Y, ahora sí, ya tenemos los elementos que necesitamos para completar el ejemplo.
9
Visítame en http://neckkito.siliconproject.com.ar
Así pues, situamos el formulario FProyectos en vista diseño, seleccionamos el campo
[Proyecto], sacamos sus propiedades y en el evento “Después de actualizar” le generamos el
siguiente código:
…
Private Sub Proyecto_AfterUpdate()
'Comprobamos que, efectivamente, se trata de un nuevo registro
If Me.NewRecord Then
'Cogemos el valor que nos guarda el formulario chivato en cuanto
al
'identificador del usuario y lo pasamos a [IdTrabajadorProyecto]
Me.IdTrabajadorProyecto.Value = Forms!FChivato.txtIdTrab.Value
End If
End Sub
…
Como veis, gracias a todo el trabajo anterior “de estructura” que hemos hecho, la
programación de este código es relativamente sencilla.
Conclusión: cada vez que queramos asignar un identificador de trabajador a algún campo
simplemente “leemos” el valor correspondiente que nos guarda FChivato.
Únicamente nos queda abrir el formulario desde FMenu. Para ello, nos vamos al botón que
habíamos llamado cmdAbreProyectosAdd y le generamos el código:
…
Private Sub cmdAbreProyectosAdd_Click()
DoCmd.Close acForm, Me.Name
DoCmd.OpenForm "FProyectos", , , , acFormAdd
End Sub
...
Así pues, situamos FMenu en vista diseño y nos centramos en el botón que hemos llamado
cmdAbreProyectosModif. En su evento “Al hacer clic” generaremos el siguiente código:
…
Private Sub cmdAbreProyectosModif_Click()
'Declaramos las variables
Dim vAdmin As Boolean
Dim vUser As Long
Dim miSql As String
'Miramos si el usuario es administrador. Si lo es vAdmin será TRUE; si no FALSE
If Forms!FChivato.txtTipoUser.Value = 1 Then
vAdmin = True
Else
vAdmin = False
End If
'Cogemos el identificador del trabajador, por si no fuera administrador
vUser = Forms!FChivato.txtIdTrab.Value
'Abrimos el formulario FProyectos en vista diseño, oculto
DoCmd.OpenForm "FProyectos", acDesign, , , , acHidden
'Si el usuario es administrador le decimos al formulario, a través de su Recordsource,
'que simplemente se abra con todos los registros de TProyectos
10
Visítame en http://neckkito.siliconproject.com.ar
If vAdmin = True Then
Forms!FProyectos.RecordSource = "TProyectos"
Else
'Si el usuario no es administrador creamos una SQL que nos filtrará
'por el id del trabajador
miSql = "SELECT * FROM TProyectos" _
& " WHERE TProyectos.IdTrabajadorProyecto=" & vUser
'Asignamos esa SQL como recordsource del formulario
Forms!FProyectos.RecordSource = miSql
End If
'Cerramos FProyectos guardando los cambios
DoCmd.Close acForm, "FProyectos", acSaveYes
'Abrimos FProyectos en vista formulario, sólo para edición
DoCmd.OpenForm "FProyectos", , , , acFormEdit
'Nos aseguramos que no se puedan añadir registros
Forms!FProyectos.AllowAdditions = False
'Hacemos visible el nombre del trabajador
Forms!FProyectos.txtNomTrab.Visible = True
'Cerramos FMenu
DoCmd.Close acForm, Me.Name
End Sub
…
Y listo7!
Estoy en FMenu → Para ir a FormX lo que hago es: Cierro FMenu → Abro FormX.
Estoy en FormsX → Para volver a FMenu lo que hago es: Cierro FormX → Abro FMenu
Y eso lo hago con lo códigos que habéis podido ver un poco más arriba:
En este ejemplo tenemos un pequeño “problema”. Para volver a FMenu desde un formulario
debemos saber qué tipo de usuario (administrador o no) está en esa sesión, dado que si
utilizáramos la operativa “normal” FMenu se nos abriría con todos los botones visibles y la
imagen oculta.
Por ello, para poder cerrar los formularios a los que también tengan acceso los usuarios
normales y volver a FMenu, antes de abrirlo, debemos hacer una comprobación del tipo de
usuario.
Para no tener que escribir todo el código cada vez vamos a servirnos de un módulo. El código
no es muy largo, pero nos servirá como idea por si os encontrárais ante un caso similar en
vuestras aplicaciones.
…
Public Sub checkUserParaAbrirFMenu()
7 Sé que quizá esta no sea la operativa más adecuada, pues probablemente lo mejor hubiera sido utilizar un Form continuo. Sin
embargo, no se trata de desarrollar una aplicación perfecta, sino de explicaros la sistemática. Estos detalles de “conseguir una
aplicación perfecta” os los dejo para vosotros.
8 Para insertar un módulo estándar podemos abrir el editor de VB (ALT+F11) y nos vamos a Menú → Insertar → Módulo
11
Visítame en http://neckkito.siliconproject.com.ar
'Abro FMenu
DoCmd.OpenForm "FMenu"
'Si el usuario es administrador
If Forms!FChivato.txtTipoUser.Value = 1 Then
'No hago nada. Sin embargo, dejo indicada aquí esta posibilidad
'por si en un futuro necesitamos que se produzca alguna acción.
Else 'Si el usuario no es administrador...
'Modifico la visibilidad de botones e imagen
With Forms!FMenu
.imgLogo.Visible = True
.cmdAbreFTrabajadores.Visible = False
.cmdAbreFDatosPass.Visible = False
.cmdAbreFMenuAdmin.Visible = False
End With
End If
End Sub
…
Ahora sólo nos queda operar con el botón para cerrar el formulario. Como sólo tenemos, en
este ejemplo, un formulario común para administrador y usuario, que es FProyectos, lo
situamos en vista diseño, insertamos un botón de comando en el encabezado del formulario,
que llamaremos cmdCerrar, y en su evento “Al hacer clic” le generamos el siguiente código:
…
Private Sub cmdCerrar_Click()
DoCmd.Close acForm, Me.Name
Call checkUserParaAbrirFMenu
End Sub
…
Lo dicho: eso es complicado y no lo explicaré aquí. Si tenéis curiosidad de cómo realizar este
proceso está explicado en el “Curso de SQL”, a vuestra disposición en la web.
Sin embargo, os voy a explicar un pequeño “apaño” que es más trabajoso pero que quizá os
pueda ser útil.
Vamos a crearnos una consulta sobre la tabla TProyectos y TTrabajadores, que guardaremos
con el nombre de CProyectos. Tendrá una estructura como la que os muestro a continuación.
12
Visítame en http://neckkito.siliconproject.com.ar
A continuación copiamos esa consulta y la pegamos con el nombre de CProyectosUser.
Situamos CProyectosUser en vista diseño y lo que haremos será añadir un campo de filtro
sobre [IdTrab]. El filtro será:
[Forms]![FChivato].[txtIdTrab].[value]
La estructura nos quedaría así (fijaos en que el check de “Mostrar” de [IdTrab] está
desmarcado):
OK. Ahora, en FMenu, nos vamos al botón que hemos llamado cmdAbreCProyectos y, en el
evento “Al hacer clic”, le generamos el siguiente código:
…
Private Sub cmdAbreCProyectos_Click()
'Si el usuario es administrador...
If Forms!FChivato.txtTipoUser = 1 Then
'Abrimos la consulta CProyectos en modo sólo lectura
DoCmd.OpenQuery "CProyectos", , acReadOnly
Else 'Si el usuario es usuario normal...
'Abrimos CProyectosUser en modo sólo lectura
DoCmd.OpenQuery "CProyectosUser", , acReadOnly
End If
End Sub
…
13
Visítame en http://neckkito.siliconproject.com.ar
OPERATIVA CON INFORMES
La operativa con informes es el punto final de este ejemplo. Vamos a ver cómo podemos abrir
nuestro RProyectos en función de si somos usuario normal o administrador.
…
Private Sub cmdAbreRProyectos_Click()
'Declaramos las variables
Dim miFiltro As String
Dim vIdTrab As Long
'Cogemos el identificador del trabajador
vIdTrab = Forms!FChivato.txtIdTrab.Value
'Examinamos el tipo de usuario y creamos el filtro en consecuencia
If Forms!FChivato.txtTipoUser.Value = 1 Then 'Si es administrador
miFiltro = "" 'No hay filtro
Else 'Si es usuario normal...
miFiltro = "[IdTrabajadorProyecto]=" & vIdTrab
End If
'Abrimos el informe filtrado
DoCmd.OpenReport "RProyectos", acViewPreview, , miFiltro
End Sub
…
¡suerte!
14
Visítame en http://neckkito.siliconproject.com.ar