GuiXT mit RFC-Funktionsbaustein nutzen

Dezember 21, 2018 0 Von SAP Guy

Die Transaktion FB5L zeigt leider nicht die Sperren zu einem Debitor an. Das haben sich die Kollegen aus der Buchhaltung aber gewünscht um sich die Arbeit zu erleichtern. Die Sperren der Debitoren werden über die Transaktion XD05 gepflegt.
Der Aufwand zur Anpassung der FB5L wurde von uns als sehr hoch eingeschätzt, daher kam die Idee, die Anzeige über GuiXT zu lösen. Nun ist GuiXT ja eher für die Anpassung der Anzeige der Daten auf einem Screen gedacht. In diesem Fall müssen aber weitere Daten aus dem SAP geladen werden. Das ist aber mit GuiXT auch möglich, denn dort können RFC-Funktionsbausteine aufgerufen werden.
Anhand dieses Beispiels soll hier knapp erklärt werden, wie man GuiXT in Verbindung mit RFC-Funktionsbausteinen nutzen kann. Durch diesen Anwendungsfall ergeben sich viele neue Möglichkeiten.
Voraussetzungen
Diese Lösung kann nicht alleine durch GuiXT umgesetzt werden. GuiXT muss an sich vorhanden sein. Zusätzlich muss auch der InputAssistant lizenziert sein, da dieser die Voraussetzung für den Aufruf der RFC-Funktionsbausteine ist.

Außerdem muss natürlich auch der RFC-Funktionsbaustein entwickelt werden, falls es nicht im Standard schon einen passenden gibt, was vermutlich nur selten der Fall sein dürfte.

Der RFC-Funktionsbaustein

Eigentlich müsste es korrekt eher lauten “RFC-fähiger Funktionsbaustein”. Aber solche Bezeichnungen schleichen sich halt schnell ein.
Dieser Funktionsbaustein ist die Voraussetzungen um Daten im SAP abzufragen, denn das kann GuiXT von sich aus nicht. GuiXT hat immer nur Zugriff auf den aktuellen Screen und nicht auf die Datenbank.
Für das oben genannte Beispiel musste also nun ein Funktionsbaustein entwickelt werden, der die Sperren eines Debitors ausliest. Diese in der Transaktion XD05 eingetragene Sperren stehen in den Tabellen KNA1 und KNB1.
Der Funktionsbaustein sieht nun vor, dass er eine Debitorennummer übergeben bekommt und mit dieser dann in beiden Tabellen nach den gewünschten Sperren sucht. Hat er eine Sperre gefunden, dann wird der Eintrag einer Tabelle hinzugefügt die an den Aufrufer zurückgegeben wird. Zusätzlich gibt es noch ein Kennzeichen für die Sperre, dass eventuell noch genutzt werden kann.
Der ganze Baustein sieht dann in etwa so aus:

FUNCTION z_fi_check_lock_indicator.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(IV_KUNNR) TYPE  KUNNR
*"  EXPORTING
*"     VALUE(EV_VALUE) TYPE  UAB_BOOLEAN
*"  TABLES
*"      ET_LOCKS TYPE  ZFI_T_LOCK_LIST
*"----------------------------------------------------------------------

  DATA: ls_knb1      TYPE knb1,
        lt_knb1      TYPE TABLE OF knb1,
        ls_kna1      TYPE kna1,
        lt_kna1      TYPE TABLE OF kna1,
        ls_lock_line TYPE zfi_s_lock_list,
        lv_lines     TYPE i,
        lv_kunnr     TYPE kunnr.

  lv_kunnr = iv_kunnr.
  SHIFT lv_kunnr RIGHT DELETING TRAILING space.
  OVERLAY lv_kunnr WITH '0000000000'.

  SELECT SINGLE * FROM kna1 INTO ls_kna1 WHERE kunnr EQ lv_kunnr AND sperr NE ' '.
  IF sy-subrc EQ 0.
    ls_lock_line-zfi_from = 'KNA1'.
    ls_lock_line-zfi_lock = ls_kna1-sperr.
    ls_lock_line-zfi_type = 'Alle Buchungskreise'.
    APPEND ls_lock_line TO et_locks.
  ENDIF.


  SELECT SINGLE * FROM kna1 INTO  ls_kna1 WHERE kunnr EQ lv_kunnr AND aufsd NE ''.
  IF sy-subrc EQ 0.
    ls_lock_line-zfi_from = 'KNA1'.
    ls_lock_line-zfi_lock = ls_kna1-aufsd.
    ls_lock_line-zfi_type = 'Auftragssperre alle Vert.'.
    APPEND ls_lock_line TO et_locks.
  ENDIF.

  SELECT SINGLE * FROM kna1 INTO ls_kna1 WHERE kunnr EQ lv_kunnr AND lifsd NE ''.
  IF sy-subrc EQ 0.
    ls_lock_line-zfi_from = 'KNA1'.
    ls_lock_line-zfi_lock = ls_kna1-lifsd.
    ls_lock_line-zfi_type = 'Liefersperre alle Vert.'.
    APPEND ls_lock_line TO et_locks.
  ENDIF.

  SELECT SINGLE * FROM kna1 INTO ls_kna1 WHERE kunnr EQ lv_kunnr AND faksd NE ''.
  IF sy-subrc EQ 0.
    ls_lock_line-zfi_from = 'KNA1'.
    ls_lock_line-zfi_lock = ls_kna1-faksd.
    ls_lock_line-zfi_type = 'Fakturasperre alle Vert.'.
    APPEND ls_lock_line TO et_locks.
  ENDIF.

  SELECT * FROM knb1 INTO TABLE lt_knb1 WHERE kunnr EQ lv_kunnr AND sperr NE ' '.
  LOOP AT lt_knb1 INTO ls_knb1.
    ls_lock_line-zfi_from = 'KNB1'.
    ls_lock_line-zfi_lock = ls_kna1-sperr.
    CONCATENATE 'Sperre Buchungskreis ' ls_knb1-bukrs INTO ls_lock_line-zfi_type RESPECTING BLANKS.
    APPEND ls_lock_line TO et_locks.
  ENDLOOP.


  DESCRIBE TABLE et_locks LINES lv_lines.
  IF lv_lines EQ 0.
    ev_value = ' '.
  ELSE.
    ev_value = 'X'.
  ENDIF.

ENDFUNCTION. 

Die Ausgabetabelle enthält in der ersten Spalte den Wert der Sperre, danach eine Beschreibung (hier könnte man auch noch erweitern und den Wertetext auslesen) und in der letzten Spalte die Tabelle aus der der Text kommt (eher eine Info für die Techniker).

RFC Funktionsbaustei

Dadurch ist es nötig die Parameter bei Import und Export auf Werteübergabe umzustellen:

Werteübergabe bei den Parametern

GuiXT Script

Nun kommt noch das Script für GuiXT.

Der Editor dürfte in vielen Fällen ausgeblendet sein, daher erst einmal mit dem Befehl “guixt visible” (Windows + R) anzeigen lassen.

Im Fenster von GuiXT werden bei den Screen Elements immer die ganzen Felder des Bildschirms angezeigt. Bei der Selektion in der FBL5N passt das auch noch, bei der Ausgabe wird man jedoch merken, dass es dort keine Elemente gibt.

Damit taucht das erste Problem auf. Es handelt sich bei der Ausgabe um eine einfache Liste. Diese enthält keine Felder, somit kann auch nicht auf die Werte zugegriffen werden. Wie erhält man jetzt aber die Debitorennummer, die für den RFC-Baustein nötig ist?

Dafür gibt es eine Funktion um auf Einträge einer Liste zuzugreifen. Mit Liste ist dabei aber die reine Textliste gemeint.

Da die Debitorennummer immer oben an der gleichen Stelle steht (abhängig davon ob die Ikonen eingeblendet sind oder nicht), kann man damit die Debitorennummer auslesen.

Es ergibt sich daraus allerdings ein weiteres Problem: Bei mehreren Debitoren funktioniert die Funktion nicht. Das kann eventuell über die aktuelle Cursorposition gelöst werden, da werde ich aber noch einmal weiter testen.

Das ganze Script sieht dann wie folgt aus:

if Q[Transaction=FBL5N] 
CopyText fromText="." toText="sperren"
Call  "Z_FI_CHECK_LOCK_INDICATOR" -currentuser  In.iv_kunnr="&V[_listline(3)](25,31)"   Out.ev_value="sperre" table.et_locks="sperren"
TextBox (0,80) (4,150) name="sperren"
endif

Es sind nur wenige Zeilen Code für diese Funktion nötig.

In der ersten Zeile wird die Transaktion geprüft, da das Fenster sonst auch z.B. in der FBL1N angezeigt wird. Dort liegt wohl das gleiche Programm dahinter.

Anschließend wird erst einmal nur ein Beispieltext in das Feld geschrieben. Das ist nötig, da leider die Rückgabe des Funktionsbausteins immer nur an den Text angehängt wird und diesen nicht komplett ersetzt, wenn man zurück zur Selektion geht und die Liste erneut aufruft.

In der dritten Zeile befindet sich der tatsächliche Aufruf des Funktionsbausteins. Dort ist auch die Funktion _listline(Zeile)(Start,Ende) eingebaut um in der Zeile die Debitorennummer auszulesen.

Danach wird die Textbox mit dem gleichen Namen wie die Rückgabe des Funktionsbausteins definiert und wir sind fertig.

Ich hoffe dieses Beispiel verdeutlicht wie ein RFC-fähiger Funktionsbaustein mit GuiXT verwendet werden kann. Das Beispiel ist noch nicht perfekt, sollte aber die Möglichkeiten schon gut darstellen.