- Introducir 1 ó 2 dígitos, por ejemplo, teclear 5 y asumir el mes y año del SYSDATE transformando ese 5 tecleado por el usuario en la fecha 05/02/2012.
- Introducir 4 dígitos, asumiendo los 2 primeros el día, los 2 dígitos siguientes el mes y el año obtenerlo del SYSDATE.
- Introducir 6 dígitos y asumiendo los 2 primeros el día, los 2 siguientes el mes y los 2 últimos el año en formato de 2 dígitos, es decir, se le debe de sumar 2000, de forma que si el usuario teclea 050212 se asuma la fecha 05/02/2012.
Para hacerlo lo que haremos será capturar el error de conversión de máscara de formato FRM-50026 en el disparador ON-ERROR de la siguiente forma:
DECLARE
v_errtyp VARCHAR2(3):= ERROR_TYPE;
v_errnum NUMBER := ERROR_CODE;
v_errtxt VARCHAR2(1000) := ERROR_TEXT;
v_fecha DATE;
v_dia VARCHAR2(2);
v_mes VARCHAR2(2);
v_anho VARCHAR2(4);
v_error BOOLEAN := TRUE;
v_valor_campo VARCHAR2(30);
v_mascara VARCHAR2(30);
BEGIN
IF v_errtyp = 'FRM'
AND v_errnum = 50026
AND Get_Item_Property(:system.trigger_item, DATATYPE) = 'DATE'
AND UPPER(Get_Item_Property(:system.trigger_item, FORMAT_MASK)) = 'DD/MM/YYYY' THEN
-- Capturamos el FRM-50026 en campos de tipo DATE y con máscara DD/MM/YYYY
BEGIN
v_valor_campo := NAME_IN(:system.trigger_item);
IF LENGTH(v_valor_campo) = 1 THEN
-- El usuario sólo teclea un dígito
v_dia := v_valor_campo;
ELSIF LENGTH(v_valor_campo) IN (2, 4, 6) THEN
-- Obtenemos el día de lo que ha tecleado el usuario
v_dia := SUBSTR(v_valor_campo, 1, 2);
END IF;
IF LENGTH(v_valor_campo) IN (4, 6) THEN
-- Obtenemos el mes, sólo si el usuario ha tecleado algo de 4 ó 6 dígitos
v_mes := SUBSTR(v_valor_campo, 3, 2);
END IF;
IF LENGTH(v_valor_campo) = 6 THEN
-- Obtenemos el año, sólo si el usuario ha tecleado algo 6 dígitos
v_anho := TO_CHAR(TO_NUMBER(SUBSTR(v_valor_campo, 5, 2)) + 2000);
END IF;
-- Obtenemos el mes y el año de SYSDATE en caso de que haber sido tecleado por el usuario
v_mes := NVL(v_mes, TO_CHAR(SYSDATE, 'MM'));
v_anho := NVL(v_anho, TO_CHAR(SYSDATE, 'YYYY'));
v_fecha := TO_DATE(v_dia || '/' || v_mes || '/' || v_anho, 'DD/MM/YYYY');
-- El comando COPY únicamente está preparado para asignar un valor VARCHAR2,
-- con variables de tipo DATE debemos de asegurar la máscar de formato
-- con la que hará conversión.
v_mascara := Get_Application_Property(BUILTIN_DATE_FORMAT);
Set_Application_Property(BUILTIN_DATE_FORMAT, 'DD/MM/YYYY');
COPY(TO_CHAR(v_fecha, 'DD/MM/YYYY'), :system.trigger_item);
Set_Application_Property(BUILTIN_DATE_FORMAT, v_mascara);
v_error := FALSE;
EXCEPTION
WHEN OTHERS THEN
-- Ante cualquier error dejamos el mensaje original de error
NULL;
END;
END IF;
IF v_error THEN
-- No se ha podido transformar lo tecleado por el usuario en una fecha válida
MESSAGE(v_errtyp || '-' || TO_CHAR(v_errnum) || ': ' || v_errtxt);
RAISE Form_Trigger_Failure;
END IF;
END;
1 comentario:
Hola, muchas gracias por este aporte, está muy bien, el problema que tengo es que no me salta el ON-ERROR, es decir, nunca se ejecuta este código.
Si pulso SHIFT+F1, sí que me sale un mensaje el la barra de estado que dice "FRM-50026: Date must be entered in a format like DD/MM/YYYY.", pero nunca se ejecuta el ON-ERROR.
Qué puedo hacer? Gracias, un saludo.
Publicar un comentario