Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Access es lo mejor

82 views
Skip to first unread message

SqlRanger

unread,
May 12, 2004, 7:21:56 PM5/12/04
to
Sí, señores.
 
Después de darle muchas vueltas y probar muchas tecnologías como C++ Builder, Delphi, Visual Basic 6.0, Visual Basic .NET, C# etc, he llegado a la conclusión de que nuestro querido Access es la mejor elección para construir el interfaz de usuario de una aplicación cliente/servidor con SQL Server como gestor de base de datos. Y no estoy hablando de los famosos adp's que también terminé por enfadarme con ellos, sino una MDE o una MDB. Cuando usamos aplicación de Access de una única base de datos, nada de tablas vinculadas a otras bases de datos de Access ni tablas vinculadas por ODBC, sólo un único archivo con todo, tablas, formularios, informes código, etc. Repito, cuando usamos una aplición de Access de una única base de datos MDB en local accedida por un único usuario, va de maravilla, el enlace a datos (databinding) es excelente, no hay ningún otro producto en el mercado que se le pueda comparar, es tremendamente eficiente, y muy pero que muy fácil y rápido de desarrollar, y no nos olvidemos de que además estas aplicaciones son muy fáciles de usar.
 
Pero ¿cómo es posible que una aplicación Access de este tipo trabaje como capa de presentación en una aplicación cliente/servidor contra SQL Server?.
 
La respuesta es aparentemente simple: construyendo la capa de negocio y acceso a datos adecuada.
 
He probado a hacer la capa de negocio y acceso a datos en Visual Basic .NET usando COM Interop, es decir, exponiendo mis ensamblados .NET como si fueran dll's ActiveX y llamándolas desde Access. Los resultados han sido francamente decepcionantes. Sin bien la funcionalidad era la requerida, los tiempos eran excesivos en las máquinas que aún usamos en la Empresa. Se necesitan maquinones para que .NET y COM Interop se ejecuten en tiempos aceptables. Muy a pesar mío tuve que abandonar esta idea.
 
Así que aunque es un paso hacia atrás en la tecnología, me decidí a probar a implementar la capa de negocio y acceso a datos en una dll ActiveX hecha en VB 6.0. Los resultados han sido sorprendentes. Nunca me imaginé que los tiempos fueran a ser tan cortos y la funcionalidad tan buena como con .NET. Así que decidido, hasta que no pasen unos años y las máquinas no sean varias veces más rápidas, esta va a ser la técnica para crear mis aplicaciones.
 
¿Como funciona esta capa de negocio y Acceso a datos?
 
Pongamos un ejemplo. Supongamos que tenemos la base de datos Neptuno en SQL Server en un servidor de la red. Bueno, en realidad la tenemos, aunque se llama Northwind. En cada puesto de trabajo hay una copia de Neptuno.mde (la aplicación Access o capa de presentación) y la dll ActiveX de VB 6.0 que se llama DatosNeptuno (la capa de negocio y acceso a datos). Supongamos también que tenemos que mostrar al usuario un determinado pedido sabiendo su IdPedido en un formulario para que lo revise o lo modifique. Bien, primero cargaríamos los datos de SQL Server en tablas locales de Access ejecutando el siguiente código VBA en un módulo de Access o en un formulario:
 
DatosNeptuno.Pedidos.CargarPorIdPedido( IdPedido )
 
Después simplemente mostramos el formulario de pedidos cuyo origen del registro es la tabla  local de Access Pedidos y que además tiene un subformulario enlazado a la tabla Detalles de Pedido:
 
DoCmd.OpenForm "Pedidos"
 
El ususario podría en cualquier momento pulsar el botón guardar en una barra de herramientas asociada al formulario, o al cerrar el formulario le preguntaríamos si quiere guardar los cambios. Los cambios han sido realidados en las tablas locales de Access, no hay nada guardado todavía en SQL Server. Para guardarlos ejecutaríamos el siguiente código VBA en un módulo o formulario de Access:
 
DatosNeptuno.Pedidos.Guardar
 
 
Lo que hace DatosNeptuno es acceder a SQL Server, leer los datos, cargarlos en tablas locales de Access y después los cambios introducidos en estas tablas locales, revertirlos a las tablas de SQL Server. DatosNeptuno usa DAO para acceder a Neptuno.mde y ADO para acceder a SQL Server. El acceso a SQL Server se produce únicamente por medio de procedimientos almacenados.
 
Bueno, creo que ya no os voy a aburrir más ni a calentaros más la cabeza con los detalles de la implementación. En realidad solo quería deciros a todos que "Access es lo mejor".
 

--

Saludos:
 
Jesús López
MVP Microsoft .NET
 
"No darás tropezón ni desatino que no te haga adelantar camino"
 
 

Juan M Afán de Ribera

unread,
May 13, 2004, 1:33:15 AM5/13/04
to
Hola Jesús, a mí no me aburres, todo lo contrario.
 
Me dejas sorprendido con lo que comentas. Pero, de este método que dices ¿cómo enfocas el tema de más de un usuario?
 
Cuenta, cuenta...

--
Saludos :-)
happy [MVP Access]
"SqlRanger" <sqlran...@mvps.org> escribió en el mensaje news:%23ad4%23WHOE...@TK2MSFTNGP11.phx.gbl...

Búho

unread,
May 13, 2004, 2:52:45 AM5/13/04
to
Hola Jesús. Como dice el Buitre de Juan, cuenta, cuenta...
 
A ver si te he entendido.
El intreface de usuario es un fichero MDE de Access en el cual existen tablas locales.
Existen tambien unos formularios locales, ligados a esas tablas locales.
 
Alguien desea ver los pedidos de un cliente. Mediante la Dll que comentas, se accede a Sql Server y se extraen los datos que el suuario ha pedido y se cargan en ese mismo momento en la tabla local de access. Una vez cargados, el usuario ya les puede visualizar en pantalla. En esos momentos ya estamos desconectados de Sql Server, pues en realidad la conexion se ha hecho instantaneamente mediante la peticion hecha por la DLL.
Bien...
Un usuario cambia datos en la pantalla local de Access y al salir se le pide conformidad para que dichos cambios se graben o no en las tablas del servidor Sql. Si escoge que sí, mdediante la DLL se graban efectivamente en las tablas de Sql.
 
Si lo que he dicho hasta aquí es correcto (Es decir, si he entenido bien tu explicación....
¿Por qué utilizar tablas locales de Access y la DLL?
¿Que ventajas tiene esto, en vez de que la MDE ataque directamente tablas de Sql?
En efecto, como dice Juan....¿Como controlas los cambios en los registros, si hay 100 aplicaciones MDE trabajando simultaneamente?

--

                    Saludos desde Valladolid
                 Francisco Javier García Aguado
                    buho...@mvp-access.com
---
http://www.mvp-access.com/
http://www.mvp-access.com/foro
http://groups.msn.com/Access2000VisualBasic/
---
 

---
Mi antivirus te dice que no tengo virus (Al menos conocidos).
Saludos del Buho.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.683 / Virus Database: 445 - Release Date: 12/05/2004

Eva Etxebeste

unread,
May 13, 2004, 2:32:25 AM5/13/04
to
Eso, eso.... :)
--
Eva Etxebeste
[MVP Office Systems - Access]
"Juan M Afán de Ribera" <happy...@ya.com> escribió en el mensaje news:OxKYMvKO...@TK2MSFTNGP12.phx.gbl...

dgironal

unread,
May 13, 2004, 3:17:41 AM5/13/04
to
"Bueno, creo que ya no os voy a aburrir más ni a calentaros más la cabeza con los detalles de la implementación. .."
 
Lástima diseccionar la capa de Negocio/Datos hubiera sido emocionante.
 
Gracias por tús comentarios!!!

Eva Etxebeste

unread,
May 13, 2004, 5:27:45 AM5/13/04
to
Me tienes que contar lo del enfado con los adp's
 
Un saludo

--
Eva Etxebeste
[MVP Office Systems - Access]
"SqlRanger" <sqlran...@mvps.org> escribió en el mensaje news:%23ad4%23WHOE...@TK2MSFTNGP11.phx.gbl...

karlitox

unread,
May 13, 2004, 5:32:47 AM5/13/04
to
Como siempre, comentarios excelentes.
 
Tal como comentan los demás, de aburrimiento nada ... nada más ver From:"SQLRanger" me he dicho ... VAMOS "pallá". Ahh, por cierto, la disección de la capa de acceso con ADO seguro que no soy el único a quien interesa ... ;)
 
Mucho abrazos chavalote (aunque peines canas)
 
:))

Eva Etxebeste

unread,
May 13, 2004, 5:46:24 AM5/13/04
to
No le digas estas cosas, no sea que se enfade y no vuelva!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :(
 
;)

--
Eva Etxebeste
[MVP Office Systems - Access]
Mucho abrazos chavalote (aunque peines canas)
 
:))

Jesús López

unread,
May 13, 2004, 6:22:16 AM5/13/04
to
Queridos amigos Juan M. Eva, Búho, dgironal. Ya veo que os pica la curiosidad, jeje.
 
Muy bien, intentaré contaros un poco más.
 
 
Por qué utilizar tablas locales de Access y la DLL?
¿Que ventajas tiene esto, en vez de que la MDE ataque directamente tablas de Sql?
 
Tiene varias:
 
El código en una dll ActiveX es código nativo, bastante más rápido que el código P-Code semicompilado de VBA.
 
El problema de hacer una aplicación cliente-servidor lo divido en dos problemas: crear la interfaz del usuario y crear la capa de acceso a datos y además los separo en dos aplicaciones diferentes. Esto tiene las ventajas:
  • Abstracción: cuando estoy haciendo la mde me olvido de que hay una base de datos de SQL, sólo me preocupo de llamar a la dll ActiveX. Y cuando estoy haciendo la dll me olvido de formularios, informes y cajas de texto.
  • Mantenibilidad: es mucho más fácil mantener una aplicación si todo está bien modularizado y organizado, cada cosa tiene su sitio y es fácil de encontrar.
  • Trabajo en equipo: el trabajo puede dividirse más fácilmente, alguien puede dedicarse a hacer la MDE y otra persona la dll ActiveX. La persona que la hace la MDE no tiene que saber nada de ADO ni de SQL Server, sólo tiene que saber de Access. Mientras que la persona que hace la dll ActiveX no tiene que saber nada de Access, sólo de ADO y de SQL Server
La dll ActiveX es una librería de clases, se basa en programación orientada a objetos. Ya sabemos que la POO tiene sus ventajas:
  • Encapsulamiento
  • Abstracción
  • Reutilización del código
  • etc
¿cómo enfocas el tema de más de un usuario?. Eso, eso.... :)

....¿Como controlas los cambios en los registros, si hay 100 aplicaciones MDE trabajando simultaneamente?
 
Bueno .., el tema de la concurrencia es siempre muy problemático y difícil de tratar.
 
La aquitectura que estoy usando es desconectada, es decir, me paso la mayor parte del tiempo desconectado de SQL Server, sólo me conecto para cargar los datos o para actualizarlos y en seguida me desconecto. Con esta arquitectura sólo tengo una opción: usar concurrencia optimista ya que la pesimista requiere mantener una conexión abierta. El modelo de concurrencia optimista tiene el inconveniente de que se pueden producir conflictos de concurrencia, pero tiene la ventaja de la simultaneidad: los usuarios pueden acceder simultáneamente a la información sin ningún problema ya que los bloqueos que se producen son más livianos y de muy corta duración.
 
Un conflicto de concurrencia se produce cuando un usuario A, al intentar guardar un registro R, ese registro R ha sido modificado o eliminado por otro usuario B desde la última vez que lo leyó A. Los conflictos de concurrencia hay que detectarlos y gestionarlos y existen varias alternativas para ello. Por ejemplo, si quisiéramos detectar el conflicto de concurrencia que se produce al actualizar un registro porque otro usuario lo ha modificado, tendríamos que incluir en la clásula WHERE de la instrucción UPDATE los valores que originalmente se leyeron, de esta manera si otro usuario ha modificado el registro, la intrucción UPDATE no actualizaría ningún registro al no cumplir la condición de WHERE y el número de registros afectados por la instrucción UPDATE sería cero, lo que indicaría la presencia de un conflicto de concurrencia, pero también sería posible que lo que haya ocurrido es que el registro se haya eliminado. Para distinguir si el conflicto se ha producido por modificación o por eliminación, tendríamos que intentar volver a leer el registro.
 
El acceso a SQL Server lo hago únicamente por medio de procedimientos almacenados, y son la forma de esos procedimientos almacenados lo que determina como se detectan los conflictos de concurrencia.
 
Pongamos un ejemplo para aclarar ideas. Supongamos que tengo esta tabla en SQL Server:
 
 
CREATE TABLE Empleados(
    IdEmpleado int identity(1,1) PRIMARY KEY,
    DNI varchar(10) NOT NULL UNIQUE,
    Nombre varchar(50) NOT NULL
)
 
y este procedimiento almacenado para actualizar empleados:
 
CREATE PROCEDURE spActualizarEmpleado
    @IdEmpleadoOriginal int,
    @DNINuevo varchar(10),
    @NombreNuevo varchar(50),
    @DNIOriginal varchar(10),
    @NombreOriginal varchar(50)
AS
    UPDATE Empleados
    SET DNI = @DNINuevo, Nombre = @NombreNuevo
    WHERE IdEmpleado = @IdEmpleadoOriginal AND DNI = @DNIOriginal AND Nombre = @NombreOriginal
 
    SELECT * FROM Empleados WHERE IdEmpleado = @IdEmpleadoOriginal
 
Los nuevos son los valores nuevos que han introducido los usuarios y los originales son los que originalmente leyeron.
 
Supongamos que
    el usuario A carga el empleado 1
    el usuario B carga el empleado 1
    el usuario B lo modifica y lo guarda  
    el usuario A lo modifica
 
Cuando el usuario A intenta guardar el registro, update no actualiza ningún registro porque no se cumple la where, hay un conflicto de concurrencia, pero la SELECT devuelve el registro tal y como lo guardó B produciendo un refresco.
 
Esto es lo que hace la dll:
  • Si el procedimiento almacenado no afecta a ningún registro considera que hay un conflicto de concurrencia y entones:
    • Si el procedimiento almacenado devuelve un recordset:
      • Si ese recordset tiene un registro el conflicto ha sido por modificación por parte de otro usuario y refresca el registro local de Access.
      • Si ese recordset no tiene ningún registro el conflicto ha sido por eliminación por parte de otro usuario y lo elimina de la tabla local
    • Si el procedimiento almacenado no devuelve un recordset, no se puede determinar si es por eliminación o por modificación y simplemente tira por la calle de en medio: considera que se ha eliminado.
  • Si el procedimiento almacenado afecta a un registro considera que no hay conflicto de concurrecia y si el procedimiento almacenado devuelve un recordset, coje el primer registro devuelto y lo usa para refrescar el registro en la tabla local de Access.
  • En caso de un conflicto de concurrencia o cualquier otro tipo de error, la dll lanza un error en tiempo de ejecución y registra el error en una tabla local de Access
 
Pero ha veces no nos interesa complicarnos tanto la vida, puede que no nos interese detectar conflictos de concurrencia porque otro usuario haya modificado el registro desde la última vez que lo leyó y simplemente queremos forzar la actualización. Este método se conoce como la técnica de que "el último que llega gana". El procedimiento almacenado sería entonces más sencillo y eficiente:
 
CREATE PROCEDURE spActualizarEmpleado
    @IdEmpleadoOriginal int,
    @DNINuevo varchar(10),
    @NombreNuevo varchar(50),
AS
    UPDATE Empleados
    SET DNI = @DNINuevo, Nombre = @NombreNuevo
    WHERE IdEmpleado = @IdEmpleadoOriginal 
 
Con esta técnica aún se pueden detectar conflictos por eliminación aunque no por actualización.
 
La técnica de "el último que llega gana" no es mala, pero tiene algunos inconvenientes. Entre otros, está el tema de la posibilidad de pérdida de actualización. Por ejemplo:
  • El usuario A carga empleado 1
  • El usuario B carga empleado 1
  • El usuario B cambia el nombre y lo guarda
  • El usuario A cambia el DNI y lo guarda
En esta situación la modificación hecha por el usuario B se pierde, reescribiéndose el nombre por lo que leyó A.
 
Lástima diseccionar la capa de Negocio/Datos hubiera sido emocionante.
 
Prometo diseccionarla más tarde, ahora tengo cosas que hacer ...
 
 
Saludos:
 
Jesús López
MVP .NET
 

 
 
 

dgironal

unread,
May 13, 2004, 8:00:32 AM5/13/04
to
1;- Imprimo TODO el mensaje
2;- En la pared tengo un corcho donde coloco notas "importantes"
3;- Hago sitio en el corcho y clavo un par de chinchetas a lo recién impreso (para que el viento no se las lleve).
 
Simplemente gracias.

karlitox

unread,
May 13, 2004, 8:40:42 AM5/13/04
to
Clases magistrales, edición SQLRanger.
 
Sin más comentarios.
 
 
muchos abrazos

José Mª

unread,
May 13, 2004, 11:15:48 AM5/13/04
to
Un gustazo leerte, Jesús.
Con tu permiso, copiado a un txt y almacenado en "cosas importantes" ;-)

Salu2
--
José Mª Fueyo
[MS-MVP Access]


Rubén Vigón

unread,
May 14, 2004, 3:19:11 AM5/14/04
to
¡¡Jesús!! ¡¡Cuanto tiempo!! ¿Donde te habías metido? ;-)

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://www.mvp-access.com/rubenvigon

0 new messages