Adsense Ad

Wednesday, 19 April 2017

Exit all forms via a strategic procedure using EXIT_FORM

This article is for all of us, who work with OPEN_FORM instead of CALL_FORM.

OPEN_FORM has benefits and problems. The user can easily switch between all open forms, but when he closes one of the forms, he only closes the current form.

Solution: Normally all applications have a start form, from where all other forms were opened. When the user is in this form and he presses exit-form, then he wants to close the whole application and not only the start form. In this case we need a method, which loops through all open forms and closes them.

Finding all open forms is a hard job. So, the best way is to store all of them in a global list named GLOBAL.OPEN_FORMS. Values are separated by semicolons, like: ;STARTFORM;EMP;DEPT;

We need a PRE-FORM and a POST-FORM-trigger for all forms, except the startform. The Pre-Form appends the name of the current form to the list, the Post-Form erases an entry.

PRE-FORM :
DEFAULT_VALUE (';', 'GLOBAL.OPEN_FORMS');
:GLOBAL.OPEN_FORMS := :GLOBAL.OPEN_FORMS || 
                      :SYSTEM.CURRENT_FORM || ';';

POST-FORM :
:GLOBAL.OPEN_FORMS := REPLACE (:GLOBAL.OPEN_FORMS, 
                               ';' || :SYSTEM.CURRENT_FORM || ';', 
                               ';');

Now we have the names of all open forms in a global list.

The KEY-EXIT trigger in the startform needs a loop, which closes all other forms and at then startform.


KEY-EXIT
 in startform :
DECLARE
  V_Form         VARCHAR2 (30);
BEGIN   
  One_Time_Timer.Initialize ('EXIT_STARTFORM');
  DEFAULT_VALUE (';', 'GLOBAL.OPEN_FORMS');
  WHILE :GLOBAL.OPEN_FORMS != ';'
  LOOP
    V_Form := Substr (:GLOBAL.OPEN_FORMS, 
                      2, 
                      InStr (:GLOBAL.OPEN_FORMS, ';', 1, 2) - 2);
    COPY ('J', 'GLOBAL.EXIT_IMMEDIATE');
    GO_FORM (V_Form);
  END LOOP;
END;

The startform is closed through WHEN-TIMER-EXPIRED :
IF One_Time_Timer.Get_Value = 'EXIT_STARTFORM' THEN
  EXIT_FORM (no_validate);
END IF;

All other forms need a WHEN-FORM-NAVIGATE trigger:
DEFAULT_VALUE ('N', 'GLOBAL.EXIT_IMMEDIATE');
IF :GLOBAL.EXIT_IMMEDIATE = 'J' THEN
  EXIT_FORM (no_validate);
END IF;


Now you have a powerful autoclose-method for all opened forms.

PACKAGE Const IS
  gbl_One_Time_Timer CONSTANT VARCHAR2 (61) := 
    upper ('global.One_Time_Timer');
END;

PACKAGE One_Time_Timer IS
  FUNCTION Get_Value RETURN VARCHAR2;
  PROCEDURE Initialize (P_Event IN VARCHAR2);
END;

PACKAGE BODY One_Time_Timer IS
  FUNCTION Get_Value RETURN VARCHAR2 IS
  BEGIN
    Default_Value (NULL, Const.gbl_One_Time_Timer);
    RETURN (NAME_IN (Const.gbl_One_Time_Timer));
  END;
  
  PROCEDURE Initialize (P_Event IN VARCHAR2) IS
    tm_id   timer;
    tm_name VARCHAR2 (30) := 'ONE_TIME_TIMER';
  BEGIN
    tm_id := Find_Timer (tm_name);
    IF ID_Null (tm_id) THEN
      tm_id := Create_Timer (tm_name, 10, NO_REPEAT);
      COPY (p_Event, Const.gbl_One_Time_Timer);
    END IF;
  END;
END One_Time_Timer;

No comments: