Hrátky s výběrovou obrazovkou - průvodce

Po delší odmlce se vracím zase s jedním článkem na téma SAP. Bude se jednat o návrh programu s interaktivní výběrovou obrazovku (selection screen), na které se budou postupně zobrazovat další pole v závislosti na tom, jak byla vyplněna pole předcházející. Půjde tedy o jakéhosi jednoduchého průvodce.

Program sám o sobě nebude mít žádné praktické využití, jeho cílem je pouze demonstrovat řešení daného problému.

Ve výchozím stavu bude na výběrové obrazovce pouze blok s polem po zadaní roku. Vstup je třeba potvrdit známým tlačítkem Execute (klávesová zkratka F8)

Průvodce 1
Vstupní obrazovka po spuštění programu

Podle toho, zda uživatel zadá buď aktuální nebo jiný než aktuální rok, se zobrazí následující blok s polem pro zadání měsíce. U pole rok se zároveň znemožní editace a také se zobrazí tlačítko pro návrat k předcházejícímu kroku.

Průvodce 2
Vstupní obrazovka pokud byl zadán aktuální rok

Průvodce 3
Vstupní obrazovka pokud byl zadán jiný než aktuální rok

Obdobně bude fungovat i krok následující. Zobrazení dalšího bloku se bude opět řídit tím, zda je zadaný měsíc shodný či různý od měsíce aktuálního.

Průvodce 4
Vstupní obrazovka pokud byl zadán aktuální měsíc

Na závěr se ve stavovém řádku zobrazí výsledné datum.

Průvodce 5
Výsledek

Řešení

Tolik pro ilustraci, nyní k samotnému řešení. Nejprve si „nakreslíme“ výběrovou obrazovku, která bude zahrnovat všechny bloky, některé však budou po spuštění programu schované. Na konec ještě přidáme návratové tlačítko (PUSHBUTTON) s funkčím kódem BAK.

*--- rok - vychozi blok ---*
SELECTION-SCREEN: BEGIN OF BLOCK b0 WITH FRAME TITLE text-000.
PARAMETERS: p_year LIKE mkpf-mjahr OBLIGATORY MODIF ID s0.
SELECTION-SCREEN: END OF BLOCK b0.

* --- mesic v tomto roce ---*
SELECTION-SCREEN: BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS: p_month TYPE scmamonth OBLIGATORY MODIF ID s1.
SELECTION-SCREEN: END OF BLOCK b1.

* --- mesic v jinem roce ---*
SELECTION-SCREEN: BEGIN OF BLOCK b2 WITH FRAME TITLE text-002.
PARAMETERS: p_month2 TYPE scmamonth OBLIGATORY MODIF ID s2.
SELECTION-SCREEN: END OF BLOCK b2.

* --- den v tomto mesici ---*
SELECTION-SCREEN: BEGIN OF BLOCK b3 WITH FRAME TITLE text-003.
PARAMETERS: p_day LIKE scgenappt-week_day OBLIGATORY MODIF ID s3.
SELECTION-SCREEN: END OF BLOCK b3.

* --- den v jinem mesici ---*
SELECTION-SCREEN: BEGIN OF BLOCK b4 WITH FRAME TITLE text-004.
PARAMETERS: p_day2 LIKE scgenappt-week_day OBLIGATORY MODIF ID s4.
SELECTION-SCREEN: END OF BLOCK b4.

SELECTION-SCREEN: PUSHBUTTON /2(12) text-bak USER-COMMAND bak
                  MODIF ID bak.

U každého pole nastavíme MODIF ID, což je jakýsi identifikátor pro nastavování jeho atributů zobrazení (zda bude pole viditelné nebo ne, bude-li editovatelné atd.). Atributy všech objektů na obrazovce jsou uloženy v systémové tabulce SCREEN a právě prostřednictvím tohoto identifikátoru k nim budeme moci přistupovat. Stejné MODIF ID může mít více polí současně.

Dále budeme potřebovat globální proměnnou g_step_id, která si bude pamatovat v jakém kroku průvodce se právě nacházíme a kompletní historii všech kroků předcházejících. V souvislosti s tím je však třeba upozornit na jeden problém, který nám to trochu znesnadní. Po stisknutí tlačítka Execute program přejde k obsluze události START-OF-SELECTION, kde dle výše popsaného algoritmu zvolíme krok, který bude následovat

START-OF-SELECTION.
  PERFORM choose_step.

FORM choose_step.
  DATA: l_step_id(2) TYPE c.

  CASE g_step_id(2).
    WHEN 'S0'.
      IF p_year = sy-datum(4).
        l_step_id = 'S1'.
      ELSE.
        l_step_id = 'S2'.
      ENDIF.
    WHEN 'S1'.
      IF p_month = sy-datum+4(2).
        l_step_id = 'S3'.
      ELSE.
        l_step_id = 'S4'.
      ENDIF.
    WHEN 'S2'.
      IF p_month2 = sy-datum+4(2).
        l_step_id = 'S3'.
      ELSE.
        l_step_id = 'S4'.
      ENDIF.
  ENDCASE.

  CONCATENATE l_step_id g_step_id INTO g_step_id.

  SET PARAMETER ID 'STEP_ID' FIELD g_step_id.
ENDFORM.

Tím je obsluha START-OF-SELECTION u konce a program se vrací zpět na výběrovou obrazovku, přesněji řečeno následuje událost AT SELECTION-SCREEN OUTPUT. Zmíněný problém spočívá v tom, že v tomto momentu program „zapomíná“ obsah globálních proměnných (nastavuje je na iniciální hodnotu). Já jsem to obešel malým trikem – uložením proměnné g_step_id do globálního paměťového prostoru pomocí příkazu SET PARAMETER ID.

Nyní se věnujme obsluze události SELECTION-SCREEN OUTPUT, která předchází zobrazení výběrové obrazovky. Bude vypadat následovně:

AT SELECTION-SCREEN OUTPUT.
  PERFORM handle_sel_screen.

FORM handle_sel_screen.
* obsluhuji obrazovku pri startu transakce?
* (poznam podle toho, ze dosud nebylo vyplneno povinne pole rok)
  IF p_year IS INITIAL.
    g_step_id = 'S0'.
    SET PARAMETER ID 'STEP_ID' FIELD g_step_id.
  ELSE.
*   ... nebo jiz byl zvolen krok?
    GET PARAMETER ID 'STEP_ID' FIELD g_step_id.
  ENDIF.

  LOOP AT SCREEN.
    IF screen-group1 = g_step_id(2)
     OR ( screen-group1 = 'BAK' AND g_step_id(2) <> 'S0' ).
      screen-active = 1.
      screen-input = 1.
      MODIFY SCREEN.
    ELSEIF g_step_id+2 CS screen-group1.
      screen-active = 1.
      screen-input = 0.
      MODIFY SCREEN.
    ELSE.
      screen-active = 0.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.
ENDFORM.

Nejprve je třeba rozlišit zda obsluhujeme událost při spuštění programu (pak nastavíme proměnné g_step_id iniciální hodnotu) nebo po návratu z události START-OF-SELECTION. V tom případě si proměnnou g_step_id přečteme z globální paměti. Jak už jsem uvedl výše v řetězci g_step_id máme uložen aktuální i všechny předešlé kroky. Aktuální krok je obsažen v prvních dvou znacích, předcházející v následujících dvou znacích atd., viz FORM choose_step.

Následuje průchod systémovou tabulkou SCREEN, která obsahuje atributy prvků na obrazovce. Modifikací těchto atributů dosáhneme požadovaného vzhledu obrazovky. Identifikátor aktuálního kroku odpovídá MODIF ID aktivního bloku – tomu nastavíme atributy tak, aby byl viditelný a editovatelný. Dále chceme aby již vyplněné bloky byly viditelné, ale needitovatelné (opět je identifikuje na základe shody MODIF ID a g_step_id předchozích kroků) a všechny ostatní bloky zůstanou skryté.

Tlačítko pro návrat o krok zpět bude viditelné vždy s výjimkou situace, kdy je zobrazen pouze výchozí blok s polem pro zadání roku a jeho funkce by tedy postrádala smysl. Zbývá ještě doplnit jeho obsluhu:

AT SELECTION-SCREEN.
  CASE sy-ucomm.
    WHEN 'BAK'.
      PERFORM set_previous_step.
  ENDCASE.

FORM set_previous_step.
  CHECK g_step_id <> 'S0'.

  g_step_id = g_step_id+2.

  SET PARAMETER ID 'STEP_ID' FIELD g_step_id.
ENDFORM.

Jedná se pouze o oříznutí prvních dvou znaků řetězce g_step_id a jeho zápis do globální paměti. Po události SELECTION-SCREEN opět následuje SELECTION-SCREEN OUTPUT a nové vykreslení obrazovky.

Tím máme program hotový. Pokud chcete můžete si stáhnout kompetní zdrojový kód:


Podělte se o tento článek s ostatními… Sdílet

Komentáře

avatar

[1] Sapflow

clock  06. 11. 2009, 11:51

Hezke. Pouziti chapu, ale nejsem si moc jisty s tim prikladem. Koneckoncu mame prece SAP Calendar control. Hezky priklad je ukazany napriklad na programu SAPCALENDAR_DEMO1 nebo SAPCALENDAR_NA­VIGATOR.
Tohle zadavani mne pripada trochu krecovite. Ale na posun mezi virtualnimi selection-screenami je to pekne. 


Pavel

[2] Pavel

clock  06. 11. 2009, 13:01

Reakce na [1] > Jak píšu hned v úvodu, praktické využití konkrétně tohoto příkladu je nulové. Chtěl jsem jenom ukázat, jak lze měnit vzhled výběrové obrazovky v závislosti na uživatelském vstupu a ne navrhnout nejhloupější date picker na světě

Určitě by šlo vymyslet spoustu daleko užitečnějších aplikací, které by využívaly takovéhoto průvodce, ale já jsem nechtěl zbytečně odvádět pozornost od jádra problému. Proto jsem napsal rutinu FORM choose_step, aby byla co nejjednodušší.

Dovedu si představit třeba příklad, kdy uživatel zadá ve výchozím bloku materiál, závod a sklad. Podle toho zda se bude jednat o řízený (WM) či neřízený sklad se rozhodne jaký se zobrazí další blok atd. Různých využití by se našla určitě spousta.

Tento problém by šel také řešit sekvencí vyběrových obrazovek, ale takhle mi to přijde elegantnější, protože má uživatel stále přehled o tom, co již vyplnil.


avatar

[3] Pablo

clock  06. 11. 2009, 13:55

Ahoj,
omlovam se, nojo fakt to tam mas. Nojo, uz jsem asi az moc zvyklej ze cteni vsech tech SAPich manualu preskakovat uvody. 


Pavel

[4] Pavel

clock  06. 11. 2009, 18:36

Reakce na [3] > To je v pohodě…


Přidat komentář

Upozornění: Komentář musí být před publikováním schválen!
: *
: *

: *

:



  • Pole označená hvězdičkou jsou povinná.
  • Můžete použít Texy! syntaxi. HTML tagy nejsou povolené!
    Příklad syntaxe: **tučně**, *kurzíva*.
  • Odkazy začínající http(s)://, ftp:// a mailto: se zformátují automaticky.
  • Na jiné komentáře se můžete odkazovat např. zápisem [1].
  • Gravatar připojený k Vaší e-mailové bude zobrazen u komentáře.
  • Upozorňuji, že komentáře, které se netýkají tématu článku, jsou vulgární nebo urážlivé, mohou být smazány.

Začátek článku Nahoru | Začátek komentářů Nahoru

© Pavel Jaroš [Sektor PJ] · Nahoru Nahoru