Ü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_upper( firstname(1) ). endif.
if lastname is not initial. initials = initials && to_upper( lastname(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.
clear: mansp, madat, mahns.
data: knb5 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.
maber = config=>parameter( 'maber' ).
endmethod.
method build_knb5_data.
clear: mansp, madat, mahns.
data: knb5 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.
|