Übersicht
Durch die Definition einer build-Methode in einer ABAP Klasse können Sie erreichen, dass vor der Anzeige eines Attributs zunächst eine ABAP-Methode (die build-Methode) aufgerufen wird, um den Wert des Attributs zu bestimmen. Das S10 Framework nimmt dabei an, dass der Wert des Attributs nur vom Wert der Import-Parameter der build-Methode abhängt. Wenn sich die Import-Werte nicht geändert haben, wird die Methode nicht aufgerufen.

Eine build-Methode kann mehr als einen Export-Parameter haben. Das ist dann sinnvoll, wenn die Werte der Parameter besser gemeinsam berechnet werden als jeweils eine separate Methode für die einzelnen Parameter durchzuführen.

Für alle Import-Parameter einer build-Methode wird ebenfalls zunächst die entsprechende build-Methode aufgerufen. Generell wird bei allen Methoden des S10 Frameworks, in denen der Wert eines Attributs über den Attributnamen als Parameter angesprochen wird, zunächst die entsprechende build-Methode aufgerufen, zum Beispiel bei s10getuservalue(). Dagegen wird bei Zugriffen auf den Attributwert durch ABAP Anweisungen, zum Beispiel  "x = x + 1", keine build-Methode ausgeführt.

Als Import-Parameter sind alle atomaren Attribute der aktuellen Klasse möglich, aber keine Objektreferenzen oder Tabellen. Als Export-Parameter sind auch Objektreferenzen und Tabellen unterstützt.

Der build-Mechanismus kann für ein einzelnes Attribut auch explizit aufgerufen werden durch s10build( attrname ). Nach Datenbankupdates ist es oft sinnvoll, die build-Methoden bei dem nächsten Zugriff wieder ablaufen zu lassen, was durch s10rebuild() insgesamt für alle Attribute des Objekts erreicht werden kann.

Wichtig beim Einsatz der build-Methoden ist, dass die Import-Parameter die gesamte funktionale Abhängigkeit abbilden. Falls beispielsweise die Liste der Ansprechpartner zum Kunden vom jeweiligen Vertriebsbereich abhängen würde - was im SAP-System nicht der Fall ist -, dann sollte der Vertriebsbereich zusätzlich zur Kundennummer als Import-Parameter der build-Methode genannt werden. Selbst wenn in der Anwendung zurzeit kein Wechsel des Vertriebsbereichs vorgesehen ist, sollten Sie ihn dann mit aufzunehmen, um für zukünftige Erweiterungen der Anwendung gewappnet zu sein.

Vorteile
Statt das Konzept der build-Methoden zu nutzen, könnte man die Attributwerte auch in Abhängigkeit von Benutzereingaben für den anzuzeigenden Screen durch eigene Methodenaufrufe ermitteln. Das führt allerdings zu Coding der Art: "Wenn der Benutzer eine neue Kundennummer eingegeben hat, und gerade der Screen xyz angezeigt wird, in dem die Ansprechpartner zum Kunden angezeigt werden, dann ermittle jetzt die Ansprechpartner aus der Datenbank". Erfahrungsgemäß werden Dialogprogramme durch eine derartige Logik komplexer und fehleranfälliger. Durch den Einsatz von build-Methoden erreichen Sie eine größere Unabhängigkeit der Anwendungslogik von der Benutzeroberfläche bei gleichzeitig besserer Performance. Im Beispiel der Ansprechpartner werden diese nur dann gelesen, wenn sie auf der aktuellen HTML-Seite angezeigt werden, und sie werden solange nicht neu gelesen, wie die Kundennummer sich nicht ändert. Statt einer zeitlichen Abhängigkeit "Benutzer hat Kundennummer eingegeben und wählt Screen xxx an" haben Sie eine feste funktionale Abhängigkeit "die Liste der Ansprechpartner hängt von der Kundennummer ab".

Implementierung
Eine build-Methode eines Attributs ist eine öffentliche Methode des Objekts (keine Klassenmethode), die einen Export-Parameter besitzt, dessen Name mit dem Attributnamen identisch ist. Der Methodenname beginnt mit "build_" und ist ansonsten frei wählbar. Der Typ des Export-Parameters sollte mit dem Typ des Klassenattributs identisch sein. Für alle Import- und Export-Parameter müssen ebenfalls öffentliche Attribute mit gleichem Namen existieren.

 
Beispiel 1 (Einzelfeld)

Eine Telefonnummer soll so ausgegeben werden, dass ein Klick darauf die Nummer wählt.

data:
  telf1                    
type kna1-telf1,

* phone link
  telf1_html               
type string.

methods:
  build_telf1_html
     
importing
        telf1      
type telf1
      
exporting
        telf1_html 
type string.

build phone link
  
method build_telf1_html.

   
if telf1 is initial.
      
clear telf1_html.
    
else.
      telf1html 
'<span onclick="event.stopPropagation()">'
                      && 
'<a href="tel:' && telf1
                      && 
'" style="color:inherit; text-decoration-color: #afa9a9;">'
                      && 
'<span class="output">'
                      &&   telf1
                      && 
'</span></a></span>'.
    
endif.
  
endmethod.

HTML
<
span class="outputhtml" name="telf1_html"> </span>

Beispiel 2 (Zwei Einzelfelder als Eingabe)
Für einen Ansprechpartner sollen die Initialen des Namens ausgegeben werden

data:
   lastname
           type string,
   firstname
          type string,
   initials
           type string.

methods:
   build_initials
     
importing
        
firstname type string
        lastname  
type string
     
exporting
        initials  
type string .

 * contact initials
method build_initials.

  
clear initials.

  
if firstname is not initial.
     initials 
to_upperfirstname(1) ).
  
endif.

  
if lastname is not initial.
     initials 
initials && to_upperlastname(1) ).
  
endif.

 
endmethod.

HTML
<
span class="output" name="initials"> </span>

Bei der Ausgabe in einer Tabelle wird die build-Methode automatisch pro Tabellenzeile ausgerufen. Die Ausgabe sieht dann zum Beispiel wie folgt aus:

 

wobei die farbige Darstellung der Namensinitialen als Avatar in der HTML-Seite über eine CSS-Klasse und etwas JavaScript gemacht wird, was an anderer Stelle näher erklärt wird.

In HTML im Fall der Tabellendarstellung oben sieht es wie folgt aus:

<div class='outputcelldiv avatar'
  
style="float:left; width: 32px;"
  
name="initials">
</
div>

Wenn Sie sich dafür entscheiden in dieser oder einer anderen Tabelle der Ansprechpartner die Initialen nicht anzuzeigen, genügt es, in der HTML-Datei die Spalte herauszunehmen. Die build-Methode für die Initialen wird dann auch nicht mehr aufgerufen, ohne dass Sie im ABAP-Coding etwas anpassen müssen.

Beispiel 3 (Drei Einzelfelder als Eingabe, Tabelle als Ausgabe)
Für einen Kunden sollen Auftragsprobleme (fehlende Lieferung u.ä.) angezeigt werden. Zur Selektion der Probleme sind die Kundennummer, eine maximal zu selektierende Anzahl von Aufträgen sowie ein Mindestauftragswert erforderlich.

 data:
    orderproblems
 type table of ref to orderproblem,

    
maxrowcount type string,
    
kunnr       type kunnr,
    minvalue
    type string,

methods:
 build_orderproblems
      
importing
          
maxrowcount type string
          kunnr       
type kunnr
          
minvalue    type string
        
exporting
          
orderproblems type table,

 order problems
method build_orderproblems.
     ...
endmethod.

HTML
<form class='table' name='orderproblems'>
  ...
</form>

 

Die Tabelle wird automatisch neu gelesen, wenn sich einer der Eingabewerte Kundennummer, minimaler Auftragswert oder maximale Trefferzahl geändert hat.

 

 

Beispiel 4 (mehrere Ausgabefelder)
Als Information zu einem Kunden sollen Mahndaten angezeigt werden.

 data:
     kunnr   
type kunnr,

     mansp   type knb5-mansp,
     madat   
type knb5-madat,
     mahns   
type knb5-mahns.

methods:
  build_knb5_data
   
importing
     
kunnr     type kunnr
   
exporting
     mansp 
type knb5-mansp
     madat 
type knb5-madat
     mahns 
type knb5-mahns.

 
method build_knb5_data.

  clearmanspmadatmahns.

  
dataknb5 type knb5.

from configuration
  knb5
-bukrs config=>parameter'bukrs).
  knb5
-maber config=>parameter'maber).


 select single mansp madat mahns
   
from knb5
      
into corresponding fields of knb5
        
where kunnr kunnr
        
and bukrs knb5-bukrs
        
and maber knb5-maber.

    mansp 
knb5-mansp.
    madat 
knb5-madat.
    mahns 
knb5-mahns.

endmethod.

HTML
<div class="subtitle">
    Mahndaten
</div>

<div style="padding:10px 10px 0px 10px">

   
<div class="infoblock">
        <label class='label' name="madat@label"></label><br />
       
<span class="output" name="madat"></span>
    </div>

   
<div class="infoblock">
        <label class='label' name="mahns@label"></label><br />
       
<span class="output" name="mahns"></span>
    </div>

   
<div class="infoblock">
        <label class='label' name="mansp@label"></label><br />
       
<span class="output" name="mansp@text"></span>
    </div>

</div>

 

In der build-Methode werden dabei der Buchungskreis sowie der Mahnbereich als fest angenommen (Konfiguration der Anwendung). Noch variabler wäre, diese ebenfalls als Import-Parameter zu definieren und außerhalb der Build-Routine aus der Konfiguration zu besetzen. Dann würde es wie folgt aussehen:

data:
     kunnr   type kunnr,
     bukrs   type bukrs,
     maber   type maber,

     mansp   type knb5-mansp,
     madat   
type knb5-madat,
     mahns   
type knb5-mahns.

methods:
  build_bukrs
   
exporting
     bukrs type bukrs,

 build_maber
   
exporting
     maber type maber,


 build_knb5_data
   
importing
     
kunnr type kunnr

     bukrs type bukrs

     maber type maber

   
exporting
     mansp 
type knb5-mansp
     madat 
type knb5-madat
     mahns 
type knb5-mahns.

method build_bukrs.
  bukrs config=>parameter'bukrs).
endmethod.

method build_maber.
  maberconfig=>parameter'maber' ).
endmethod.

method build_knb5_data.

  clearmanspmadatmahns.

  
dataknb5 type knb5.

 select single mansp madat mahns
   
from knb5
      
into corresponding fields of knb5
        
where kunnr kunnr
        
and bukrs bukrs
        
and maber maber.

    mansp 
knb5-mansp.
    madat 
knb5-madat.
    mahns 
knb5-mahns.

endmethod.

Falls eine build-Methode wie im Falls von "bukrs" und "maber" keine Import-Parameter hat, wird die build-Methode nur bei dem ersten Zugriff aufgerufen und dann immer der ermittelte Wert genommen.

Bemerkenswert ist hier noch, dass durch

<span class="output" name="mansp@text"></span>

folgendes abläuft:

- Der Wert von "mansp.text" wird angefordert, also die Standardbezeichnung der Mahnsperre
- Dazu wird der Wert der Mahnsperre ermittelt
- Das geschieht über die build-Methode "build_knb5_data"
- Dazu müssen zunächst die Werte der Importparameter "bukrs" und "maber" über ihre build-Methoden ermittelt werden
- Jetzt kann die Mahnsperre gelesen werden
- Zum Schluss nun der Text zu Mahnsperre

Tipps zum Schreiben von build-Methoden

  • Von Anfang an mit build-Methoden arbeiten, da man gerade in frühen Projektphasen viele Änderungen der Benutzeroberfläche hat und durch die build-Methoden flexibel ist. Verschiebt man den Einbau der build-Methode auf eine spätere Projektphase, hat man bei Änderungen während der Entwicklung mehr Arbeit und muss später ein bereits gewachsenes komplexeres Coding nochmal ändern.
  • Bei den Import-Parametern kein Feld vergessen, von dem die Ausgabefelder abhängen. Dazu am besten den Code kritisch durchgehen, ob noch irgendwelche noch nicht bei "importing" genannten Attribute benutzt werden. Andernfalls bleiben alter Ausgabewerte trotz einer neuen Benutzereingabe stehen.
  • Am Anfang der build-Methode die Ausgabefelder mit "Clear" zurücksetzen
  • Die build-Methoden besonders stabil schreiben, also zum Beispiel berücksichtigen, dass einige Import-Felder leer sein können, wenn die build-Methode in einer Datenerfassung aufgerufen wird.

  • Darauf achten, dass die Import und Export-Parameter den gleichen Typ haben wie die entsprechenden Attribute. Andernfalls kann es bei dem automatischen Aufruf der build-Methode einen Abbruch geben, oder Ausgabewerte werden abgeschnitten.

Komponente: S10 Framework