APLICACIÓN COMPRAS EN SQLSERVER 2000 (Libro de apoyo: Iniciación a las bases de datos con Access 2002. Eduardo Mora, Marta Zorrilla, Joaquín Díaz de Entresotos. Díaz de Santos, 2003) A continuación se presentan los pasos para construir una aplicación sobre la base de datos COMPRAS. Esta constará de formularios que permitan la gestión y consulta de datos y de informes que permitan la impresión y/o visualización de datos con un formato preestablecido. Con objeto de construir de forma rápida la aplicación, se utilizará Access como herramienta de desarrollo, evitando así aprender una herramienta y lenguaje de programación nuevos. Generalmente este tipo de aplicaciones se construyen con herramientas denominadas RAD (Desarrollo Rápido de Aplicaciones) como Visual Basic.Net, C#.Net, Power Builder, J2E, u otros. Centrándonos en Access, se tienen dos posibilidades, crear un proyecto Access con lo que Access se conecta vía OLEDB a SQL Server 2000 o crear una base de datos Access y vincular vía ODBC las tablas que se encuentran en SQL Server u otro gestor (ver capítulo 9 del libro Iniciación a las bases de datos con Access 2002 ). En la primera opción, Access solo contiene objetos de aplicación, es decir, formularios, informes y módulos de programación Visual Basic para Access; mientras que en la segunda, Access además actúa como motor de la base de datos. PROYECTOS ACCESS Pasos para desarrollar el prototipo de aplicación sobre la base de datos COMPRAS. 1. Crear Nuevo Proyecto (datos existentes). Access solicita autentificación en SQL Server y seleccionar la base de datos para establecer el vínculo a través de OLEDB. Figura 1.1. Establecer conexión Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 1
Una vez conectados se observarán los objetos de Access: tablas, consultas (funciones y procedimientos almacenados y vistas) y diagramas que se encuentran en SQL Server (desde este entorno se puede hacer lo mismo que desde el Administrador Corporativo de SQL Server) y los Formularios, informes, macros y módulos que residen en el fichero Access con extensión adp. 2. Decidir los formularios que se van a diseñar en función de la estructura de tablas que se dispone y de las necesidades del cliente, en nuestro caso: artículos, proveedores y pedidos con sus líneas. La aplicación debe incluir, al menos, los formularios que permitan gestionar todas las tablas aunque también puede contener otros de solo consulta atendiendo así las necesidades de los distintos roles de usuarios. 3. Decidir los informes, impresos que se ofrecerá a la organización o al cliente. En nuestro caso el catálogo de artículos, la factura del pedido y las compras realizadas a cada proveedor por año. 4. Para realizar controles en los formularios e informes se podrá hacer uso de macros y de módulos de Visual Basic. a. Macros, son ciertos automatismos y controles que permite definir Access sin tener que programar. Estos se ejecutan cuando se produce el evento al cual se asignan. b. Módulos de VB: para definir funcionalidades generales de la aplicación. En cada formulario se programa lo específico de él, como se verá en el formulario de pedidos y el subformulario de líneas. Formularios Todos los formularios, así como los informes, tienen asociado una consulta o vista. Esta se puede definir antes, en el entorno de consultas, o bien se construye utilizando el asistente del formulario. Cuando se trata de información de una sola tabla, se puede actuar de la segunda forma, pero en el caso de que participen varias tablas se aconseja crear la vista. 1. Artículos: este formulario no tiene nada especial, se utilizará el asistente seleccionando toda la tabla de artículos. El botón que abre el informe catálogo de artículos se pondrá posteriormente, una vez se haya definido el mismo. Este se construirá también con el asistente seleccionando la tabla directamente. Propiedades modificadas en el formulario de Artículos: a) Selectores de registro = No b) Separadores de registro = No c) Índice de tabulación y Punto de tabulación (orden que sigue el cursor al rellenar los campos) d) Tipo recordset = snapshot actualizable (permite consultar y actualizar la información. Se usará siempre en formularios de gestión de datos) e) Nº máx. registros = 1000 (máximo número de registros que se traen del servidor al cliente) Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 2
Figura 1.2. Formulario de Artículos 2. Formulario Proveedores: Del mismo modo que artículos, se selecciona con el asistente todos los campos de la tabla. Además se realizan las siguientes mejoras: Crear cuadro combinado para el campo procepro (opción Cambiar a cuadro combinado). En propiedades carpeta Datos tipo origen de la fila = lista de valores y en origen de la fila = UE; No UE. Campo mailpro con propiedad Es hipervínculo = Sí (carpeta Todas). En los datos anteponer mailto: o http:// si queréis que se active el programa del correo o el navegador al pulsar sobre él. Campo código postal, se puede establecer la máscara de entrada = 00000;; (carpeta Datos). El cero indica número obligatorio y el 9, número opcional. Hay asistente para su definición. Campo teléfono y fax, también se les puede aplicar máscara si se quiere guardar el formato hay que tener en cuenta que los espacios y otros símbolos ocupan lugar por lo que hay que dimensionar el campo adecuadamente. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 3
Figura 1.3. Formulario de proveedores 3. Formulario Pedidos: Como este formulario requiere trabajar con dos tablas (pedidos y líneas) y presentar información adicional de las otras dos (proveedores y artículos) se crearán dos vistas con los datos que queremos que presente el formulario. Crear vistas Encabezado del pedido y Detalle del pedido como se muestra en las figuras Figura 1.4 y Figura 1.5: Figura 1.4. Vista Encabezado del pedido Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 4
Figura 1.5. Vista detalle del pedido Crear formulario con el asistente seleccionando ambas vistas. Access creará un formulario con un subformulario vinculados por el campo numped. En esta pantalla se realizarán varias modificaciones como se ve en la imagen Figura 1.6: a) Se ordenarán los campos y se establecerá la fecha del pedido con la fecha del día (la toma de la base de datos o bien se pone en la propiedad Valor predeterminado = Ahora()). b) Se buscará el proveedor apoyándose en el cuadro combinado ( tipo origen de la fila = Tabla/Vista/ProcAlmacenado y Origen de la fila = SELECT codigpro, nombrpro FROM Proveedores, Columna dependiente = 1, Número de columnas = 2, Ancho de columnas = 2 cm; 6 cm) y se establecerá como el primer campo a rellenar (punto de tabulación = 0) c) Se bloquearán todos campos del proveedor, a excepción del código, y se les quitará el punto de tabulación para evitar que el cursor entre en el campo. Además, el IVA se establecerá al 16 por defecto (propiedad valor predeterminado). d) Se fijará en el formulario que la actualización de datos corresponde solo a la tabla pedidos (propiedad tabla única = pedidos) Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 5
Figura 1.6. Formulario de Pedidos e) Se establecerá el número del pedido con el siguiente al último existente y la fecha prevista a 15 días de la fecha del pedido (ver procedimiento Form_BeforeInsert que se encuentra en el cuadro Código asociado al formulario de EncabezadoPedido ). f) Se establecerá el código VB restante del formulario a través de los eventos de los objetos que se indican en el cuadro siguiente, a excepción del botón Factura que se realizará con el asistente. Option Compare Database Private Sub btn_factura_click() ' Este código es creado por el Asistente para botones de comando. On Error GoTo Err_btn_factura_Click Dim stdocname As String stdocname = "Factura" DoCmd.OpenReport stdocname, acviewpreview,, "numped = " + CStr(Me.numped) Exit_btn_factura_Click: Exit Sub Err_btn_factura_Click: ' Si el usuario cancela la acción, no mostrar un mensaje de error. Const conerrdocmdcancelled = 2501 Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 6
If (Err = conerrdocmdcancelled) Then Resume Exit_btn_factura_Click Else MsgBox Err.Description Resume Exit_btn_factura_Click End If End Sub Private Sub codigpro_afterupdate() 'ejecuta el comando de salvar el registro de pedido para que se actualice y 'muestre la información del proveedor RunCommand accmdsaverecord End Sub Private Sub codigpro_beforeupdate(cancel As Integer) ' Muestra un mensaje si el cuadro combinado proveedor está en blanco. Dim strmsg As String, strtitle As String Dim intstyle As Integer If IsNull(Me!codigpro) Or trim(me!codigpro) = "" Then strmsg = "Debe elegir un valor de la lista Proveedor." strtitle = "Proveedor requerido... " intstyle = vbokonly MsgBox strmsg, intstyle, strtitle Cancel = True End If End Sub Private Sub Form_BeforeInsert(Cancel As Integer) If IsNull(Me!fentrped) Then Me!fentrped = DateAdd("d", 15, Now()) End If If IsNull(Me!numped) Then Me!numped = DMax("[numped]", "pedidos", "[numped]>0") + 1 End If Me!codigpro.SetFocus End Sub Código asociado al formulario de EncabezadoPedido En el subformulario: Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 7
a) Se establecerá un cuadro combinado para localizar el artículo (del mismo modo que en el proveedor pero en este caso vinculando el código y ocultándolo, es decir, que el tamaño de la primera columna sea 0 y el número de columnas sea 2). b) Se establecerá el artículo como primer campo a rellenar (punto de tabulación), dejando el número de línea sin él. c) Se asignará el precio por línea con el precio que tiene éste en la tabla de artículos y se establecerá en automático el número siguiente de línea que le aplique al pedido (procedimiento codigart_afterupdate). d) Se ocultará el campo numped. Se pondrá el formato moneda al campo precio y total línea. e) Se ocultarán los botones de desplazamiento. Option Compare Database Private Sub codigart_afterupdate() On Error GoTo Err_Codigart_AfterUpdate Dim strfilter As String If IsNull(preunlin) Then strfilter = "codigart = " & Me!codigart Me!preunlin = DLookup("preunart", "articulos", strfilter) End If If IsNull(Me!numlin) Then Me!numlin = IIf(IsNull(DMax("numlin", "lineas", "numped=" & Form_EncabezadoPedido.numped)), 1, DMax("numlin", "lineas", "numped=" & Form_EncabezadoPedido.numped) + 1) End If Exit_Codigart_AfterUpdate: Exit Sub Err_Codigart_AfterUpdate: MsgBox Err.Description Resume Exit_Codigart_AfterUpdate End Sub Código asociado al formulario de DetallePedido En el formulario EncabezadoPedido: Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 8
f) A continuación, se creará un campo calculado que presente el valor del pedido completo. Para ello se creará un campo de texto y se indicará en la propiedad origen del control = [DetallePedido Subformulario]![ImporteNeto]*(1+[ivaped]/100) donde ImporteNeto será un campo del pie del subformulario que hace la suma del importe por línea (ImporteNeto = Suma([totallin] ). Ver Figura 1.7 Figura 1.7. Formulario de Pedidos en vista de diseño g) Por último, se creará el botón de imprimir la Factura del pedido que se visualiza en cada momento (debe estar creado el informe previamente). Esto se le indicará por código al informe según se muestra en el evento clic de este botón en el cuadro de código asociado al formulario EncabezadoPedido. Informes Para crear informes se deben realizar consultas o bien procedimientos almacenados que devuelvan los datos que se solicitan. Se harán tres ejemplos: dos con consulta, Catálogo de artículos y Pedidos y otro con procedimiento almacenado, Compras a proveedores por año. El Informe Catálogo de artículos recoge todos los datos de la tabla artículos. Se crea una consulta con los campos a mostrar, ver Figura 1.8, con nombre CatalogoArticulos. A continuación se crea el botón que llama a este informe desde el formulario de Artículos. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 9
Figura 1.8. Informe Catálogo de artículos El Informe Factura se apoya en la consulta Factura que se muestra en la Figura 1.9 Figura 1.9. Consulta para obtener las facturas Se utilizará el asistente para generar el informe y en vista de diseño se colocará la información al gusto del usuario, ver Figura 1.10, de forma que por un lado estén los datos del encabezado y por otro los de la línea. Nótese que aparece el encabezado de grupo numped por el que la información que se presenta en esa zona sólo se muestra una vez por cada número de pedido (numped) distinto, mientras que en detalle se presenta cada fila devuelta por el Select. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 10
Figura 1.10. Informe Factura en vista de diseño El Informe de proveedores por año, se apoya en un procedimiento almacenado Compras_por_año_proveedor que se presenta a continuación. Este tiene dos parámetros de entrada: fecha de inicio y de fin, por lo que para su ejecución será necesario pasarle dos valores. Esto se hará con un formulario específico. create Procedure "Compras_por_Año_Proveedor" @FechaInicio datetime, @FechaFin datetime AS SELECT Proveedores.nombrpro, DATENAME(yy,fechaped) as año, sum(totalped) as Importe FROM Pedidos,Proveedores WHERE Pedidos.codigpro = Proveedores.codigpro and Pedidos.totalped is not null and Pedidos.fechaped Between @FechaInicio And @FechaFin Group by Proveedores.nombrpro, DATENAME(yy,fechaped) order by proveedores.nombrpro Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 11
Este formulario tendrá dos campos que les denominaremos (propiedad Nombre ) [fecha_ini] y [fecha_fin] y un botón que al ser pulsado llamará al informe creado previamente Compras_por_Año_proveedor. Figura 1.11. Formulario para el informe Compras por año proveedor El informe creado Compras_por_Año_proveedor tiene el aspecto que muestra la Figura 1.12. Se crea utilizando el asistente. Figura 1.12. Informe Compras por año proveedor en vista de diseño Seleccionando el informe y accediendo a la propiedad input parameters de la carpeta Datos, se pondrá el siguiente texto para que al visualizarse se tome como parámetros de entrada los indicados en el formulario creado: Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 12
@FechaInicio datetime = Forms![compras por año y proveedor]![fecha_ini], @FechaFin datetime = Forms![compras por año y proveedor]![fecha_fin] La propiedad InputParameters se utiliza para especificar o determinar los parámetros de entrada que se pasan a una instrucción SQL de la propiedad OrigenDelRegistro (RecordSource) de un formulario o informe o un procedimiento almacenado cuando se utiliza como el origen de registros de un formulario o informe dentro de un proyecto de Microsoft Access (.ADP). Pantalla principal Se creará una pantalla principal con los botones que permiten acceder a las distintas opciones de menú como se muestra en la Figura 1.13. Figura 1.13. Formulario principal A continuación se creará una barra de herramientas con las opciones necesarias para la gestión de datos: insertar y borrar datos pues modificar se realiza directamente sobre el registro que se muestra en la pantalla y búsqueda por formulario con establecer filtro y quitar filtro o su alternativa de filtro de servidor por formulario y aplicar filtro de servidor en función de si se decide traer directamente los datos o solicitar previamente una condición de búsqueda con idea de reducir el tráfico de datos por la red (aplicaciones cliente/servidor). Para realizar esto último se debe establecer a Sí la propiedad de formulario Filtro de Servidor por Formulario. Finalmente se establecerá la barra de tipo menú para que se utilice con la barra de herramientas de la aplicación. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 13
Figura 1.14. Barra de herramientas para la aplicación Por último, se accederá a la opción de menú Herramientas Inicio y se establecerá como ventana de inicio el formulario principal y como barra de menú, la creada anteriormente, como se muestra en la Figura 1.15. Se deshabilitarán todas las opciones para que el usuario final no tenga acceso a los objetos de la base de datos Access. Para abrir en modo diseño este proyecto, se debe pulsar doble clic sobre el fichero Access al tiempo que se tiene pulsada la tecla de mayúsculas. Figura 1.15. Barra de herramientas para la aplicación Mejoras en el formulario que gestiona los pedidos La gestión de pedidos no queda completa sino se registra la mercancía cuando esta llega al almacén. Para ello se propone como una alternativa la creación de un formulario Entradas que recoja todos los campos de la tabla y que se invoque por medio de un botón que se cree en el subformulario de líneas. De este modo, el usuario final localiza el pedido y para cada línea de pedido, indica las unidades de entrada. El aspecto que presenta el formulario es el que se muestra en la Fig. 1.16. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 14
Figura 1.16. Formulario para la gestión de pedidos y entradas Por otra parte, con objeto de visualizar y poder consultar si el pedido está completo o no, se crea una función PedidoTerminado que verifica si se han recepcionado todas las unidades de cada línea y se añade su consulta a la vista EncabezadoPedido del siguiente modo: CREATE VIEW dbo.encabezadopedido AS SELECT dbo.pedidos.numped, dbo.pedidos.codigpro, dbo.pedidos.ivaped, dbo.pedidos.fechaped, dbo.pedidos.fentrped, dbo.proveedores.cifpro, dbo.proveedores.nombrpro, dbo.proveedores.direcpro, dbo.proveedores.cpostpro, dbo.proveedores.localpro,dbo.proveedores.telefpro, dbo.proveedores.emailpro, dbo.proveedores.faxpro, dbo.proveedores.procepro, CASE dbo.pedidoterminado(dbo.pedidos.numped) WHEN 0 THEN 'Pendiente' WHEN 1 THEN 'Recepcionado' END AS recepcionado FROM dbo.pedidos INNER JOIN dbo.proveedores ON dbo.pedidos.codigpro = dbo.proveedores.codigpro El código Visual Basic que se requiere para la gestión de esta pantalla se encuentra en el proyecto compras.adp que se ofrece en clase. Marta E. Zorrilla Pantaleón Bases de Datos - 05/06 15