RESPUESTA A LA PREGUNTA 1131-VISUAL FOXPRO *** DESENCADENANTES *** *Como su nombre indica, son procedimientos que se desencadenan al hacer cambios en una tabla *que esté contenida en una base de datos. *En Visual Foxpro, las tablas pueden se libres o estar contenidas en una base de datos, no en *si mismas, sino que lo que tienen es una referencia a ellas en la base de datos y ellas tienen *referencia a su vez a la base de la que dependen. La base de datos viene a ser un archivo con *una gran informción sobre sus tablas y conteniendo los procedimientos a ejecutar (desencadenantes), *como si fuera una libreria de procedimientos. *Como se usan? *Supongamos un ejemplo: Creamos una base de datos y luego una tabla de clientes y otra de pedidos *la tabla de clientes tendra un campo de código de cliente que será el principal y los otros campos *necesarios, la de pedidos, tendrá un código de pedido que será el principal, otro código de cliente, *y los restantes campos necesarios. Luego creamos las referencias entre la tablas, para ello, *desde la pestaña "Datos", del proyecto ó con el comando "Modify data?", elegimos la base de datos *en que están las tablas y visualmente, pinchando en el campo de CodigoCliente de clientes lo llevamos *al código de Cliente de Pedidos y nos queda una linea dibujada que es la relación creada, ahora para *establecer los desencadenantes, pulsamos el botón derecho del ratón, en un espacio en blanco *dento de la base de datos, y sale el menu de propiedades, elegimos "Modificar integridad referencial" y *nos sale una ventana con la lista de tablas relacionadas y los desencadenantes a elegir, *en este caso podríamos elegir: *Reglas par la Actualizacion(de la tabla principal "Clientes") -> Cascada, significa que si cambiamos el código de cliente *-en la tabla de Clientes, se llamará a un procedimiento almacenado en la base de datos, *-que ira a la tabla de Pedidos y cambiará todos los códigos del cliente(modificado) *-que hemos cambiado, y pondra el nuevo. *Reglas para la Eliminación (de registros en la tabla principal, la de clientes) -> si elegimos *"RESTRINGIR", quiere decir que al intentar borrar un registro de un cliente, automaticamente *se ira a mirar a la tabla de pedidos a ver si su codigo esta en alguno y si es asi, *no podremos borrar el cliente *Reglas para la inserción(de registros en la tabla secundaria "Pedidos" -> podriamos poner "RESTRINGIR", *que quiere decir que cada vez que vayamos a dar de alta un nuevo pedido, *se mirará que el código de cliente que pongamos exista en la tabla de clientes y si *no existe, no podremos dar de alta un pedido con este código de cliente. *En todos los casos, si elegimos la opción "Ignorar", entonces no se establece ningun desencadenate. *Todos estos desencadenantes se crean automaticamente con la "Integridad referencial", pero *a parte de estos, podemos nosotros crear un código personal y meterlo ahi usando *la opcion del menu de propiedades de la base de datos "Modificar procedimientos almacenados", *y nos sale el editor, con todos los procedimientos de integridad referencial hechos *automaticamente y que no debemos modificar, entonces al principio de todo, vamos *añadiendo nuestras funciones, que se quedan ahi aunque volvamos a crear la integridad referencial. *Para activarlos, hacemos modify struc, en la tabla que queramos, y en la pestaña de "Tabla", *Vemos que hay un apartado de "Validacion de registros" y ahi ponemos el nombre de la funcion *que hayamos creado, entonces cada vez que modifiquemos un registro, se llamara a la *funcion que hemos creado y que si nuestra funcion devuelve .F., entonces no se puede modificar *este registro. Tambien vemos en el recuadro de "Desencadenantes", las funciones que *se han creado don la integridad referencial. *Para Controlar todos estos desencadenates, podemos hacer que el programa salte a una rutina *de control de errore creada por nosotros con la orden: *"ON ERROR DO ErrorAp WITH ERROR(), MESSAGE(1), LINENO(1), PROGRAM()" *El procedimiento de control de control para desencadenantes que yo uso es: *-Control de errores. PROCEDURE ErrorAp PARAMETERS Error_, Mensage_, Lineno_, Prg swError = .T. DO CASE *Case Error_ = otros ... Case Error_ = 1884 &&-Se ha infringido la exclusividad de la clave principal o candidata. DO Errata WITH "ERROR 1884, Clave DUPLICADA", "¡No se acepta!" retry &&-Se controla localmente a traves de swError y AERROR() CASE Error_ = 1539 &&-Falló el desencadenante, lo más seguro es que ; se haya intentado borrar un código. WAIT WIND "Falló el desencadenante" TIMEOUT .3 RETURN &&-Se controla localmente a traves de swError y AERROR(), para que vaya bien; &&-no tiene que tener bufer de datos (0). OTHERWISE = MESSAGEBOX( "ERROR n.: "; + ALLTRIM(STR(Error_)) ; + CHR(13) + CHR(13) ; + Mensage_ ; + CHR(13) + CHR(13) ; + prg ; + " Linea: " ; + ALLTRIM(STR(Lineno_)), ; 0, "¡ ERROR FATAL !") CANCEL ENDCASE RETURN *Ahora, para activar el error, supongamos que intentamos borrar un cliente que tiene *pedidos en un formulario que tiene un botón para borrar el cliente: *{ *-Procedimiento de borrado al que se llega al pulsar; el botón de "Borra". SELECT fcliCli swError = .F. &&-SE USA EN LA RUTINA DE CONTROL DE ERRORES IF Conforme( "¿Seguro que quiere BORRAR este Articulo?" ) IF EOF() DO Atencion WITH "¡Final de fichero, no se puede BORRAR!" ELSE DELETE IF !swError &&-no ha ocurrido ningún error. DO ToqueBorrar wait wind "Borrado .." nowa skip ThisForm.Refresh ELSE swError = .F. = AERROR( xError ) IF xError( 5 ) = 3 DO Errata WITH "¡ No se Puede BORRAR !", "Este código esta en uso en otra parte" ENDIF ENDIF ENDIF ENDIF *} *** Espero no haber liado más el tema y que todo este rollo sirva para entender un poco más el mundo de VFP *** Jatuma JATUMA@teleline.es