In der Anleitung Reiter ist beschrieben, wie ein Screen im S10 Framework in verschiedene Bereiche aufgeteilt wird, zu denen der Benutzer über Reiter (Registerkarten) navigieren kann.
In diesem Tutorial implementieren wir die Technik anhand eines Beispiels und besprechen mögliche Varianten.
Unsere Musteranwendung stellt einige Informationen zum Kunden auf drei Reitern dar:


Das S10 Framework leistet dabei folgendes:
Die Darstellung der Reiter wie oben dargestellt ist einfach und platzsparend, sodass Sie auch im Hochformat ca. 4-5 Reiter ohne Zeilenumbruch unterbringen können:
Falls Sie mehr Reiter benötigen, ist empfehlenswert, statt des Textes ein Icon anzuzeigen. Sie können dabei im Querformat ein Icon plus Text anzeigen und im Hochformat nur das Icon. Das sieht dann in unserem Beispiel wie folgt aus:


Nun zur Implementierung. Wir benötigen erstens die Reiterleiste und zweitens für jeden Reiter einen Bereich, der bei Klick auf den Reiter eingeblendet wird. In unserem Beispiel sieht das wie folgt aus:
HTML<!-- tabstrip -->
<table class='tabstrip'>
<tr>
<td id='tabaddr'
class='tabactive'
onclick='S10ActivateTab(this);'>
Adresse
</td>
<td id='tabpart'
class='tab'
onclick='S10ActivateTab(this);'>
Partner
</td>
<td id='tabsales'
class='tab'
onclick='S10ActivateTab(this);'>
Umsatz
</td>
</tr>
</table>
<!-- Adresse -->
<div class="tabpageactive"
id="tabaddr.area">
...
</div>
<!-- Partner -->
<div class="tabpage"
id="tabpart.area">
...
</div>
<!-- Umsatz -->
<div class="tabpage"
id="tabsales.area">
...
</div>
Bitte dabei auf folgendes achten:
Falls Sie ein Icon plus Text anzeigen und wie im Beispiel oben Hochformat und Querformat unterscheiden, wird es etwas komplizierter:
<!-- tabstrip -->
<table class='tabstrip'
style="height: 36px;">
<tr>
<td id='tabaddr'
style='width: 120px;
height: 36px;
--portrait-width: 80px'
class='tabactive'
onclick='S10ActivateTab(this);'>
<img src="../../../icons/home.png"
style="height: 28px;
vertical-align: bottom;" />
<span class='landscape'>
Adresse
</span>
</td>
<td id='tabpart'
style='width: 120px;
height: 36px;
--portrait-width: 80px'
class='tab'
onclick='S10ActivateTab(this);'>
<img src="../../../icons/partners.png"
style="height: 28px;
vertical-align: bottom;" />
<span class='landscape'>
Partner
</span>
</td>
<td id='tabsales'
style='width: 120px;
height: 36px;
--portrait-width: 80px'
class='tab'
onclick='S10ActivateTab(this);'>
<img src="../../../icons/sales.png"
style="height: 28px;
vertical-align: bottom;" />
<span class='landscape'>
Umsatz
</span>
</td>
</tr>
</table>
Damit ist das Grundgerüst der HTML-Seite fertig. Das S10 Framework blendet nun bei einem Klick auf einen Reiter den entsprechenden Teil ein und fordert die nötigen Daten vom Backend an.
Auf ABAP-Seite implementieren wir build-Methoden für die anzuzeigenden Elemente. Sie werden durch das S10 Framework automatisch aufgerufen, sobald die Daten gebraucht werden.
Für das Thema "Reiter" kommt es jetzt zwar nicht auf die Details der ABAP-Methoden an, aber trotzdem hier das gesamte nötige ABAP-Coding mit einigen Kommentaren:
ABAP* partnerinfo
class partnerinfo definition inheriting from /s10/any.
public section.
data:
parvw type parvw,
partnerkey type string,
partnername type string,
city type string.
endclass.
* salesinfo
class salesinfo definition inheriting from /s10/any.
public section.
data:
prodh type vbrp-prodh,
netwr1 type p decimals 0,
netwr2 type p decimals 0,
percentage type p decimals 1.
methods:
build_percentage
importing
netwr1 type p
netwr2 type p
exporting
percentage type p.
endclass.
class salesinfo implementation.
method build_percentage.
if netwr1 eq 0.
percentage = 0.
else.
percentage = netwr2 * 100 / netwr1.
endif.
endmethod.
endclass.
class kna1_detail definition inheriting from /s10/any.
public section.
* Kundeninfo (Name, Adresse)
data:
kunnr type kna1-kunnr, " Debitor
name1 type kna1-name1, " Name
name2 type kna1-name2, " Name 2
ort01 type kna1-ort01, " Ort
pstlz type kna1-pstlz, " Postleitzahl
land1 type kna1-land1, " Land using Text
stras type kna1-stras, " Straße
telf1 type kna1-telf1, " Telefon-1
partners type table of ref to partnerinfo,
sales type table of ref to salesinfo.
* database table name
constants:
dbtablename type string value 'kna1'. " for select
methods:
* partners
build_partners
importing
kunnr type kunnr
exporting
partners type table,
* sales
build_sales
importing
kunnr type kunnr
exporting
sales type table.
endclass.
class kna1_detail implementation.
* partners
method build_partners.
refresh partners.
data: begin of pt,
parvw type knvp-parvw,
parnr type knvp-parnr,
kunn2 type knvp-kunn2,
pernr type knvp-pernr,
end of pt,
kna1 type kna1,
pa0002 type pa0002,
line(80) type c.
select * from knvp
into corresponding fields of pt
where kunnr = kunnr
and vkorg = '1010' "fixed demo values for sales area
and vtweg = '10'
and spart = '00'
and ( kunn2 ne space or pernr ne space )
order by parvw.
data: pi type ref to partnerinfo.
create object pi.
pi->parvw = pt-parvw.
if pt-kunn2 ne space.
write pt-kunn2 to line no-zero.
pi->partnerkey = line.
select single name1 ort01
from kna1
into corresponding fields of kna1
where kunnr = pt-kunn2.
pi->partnername = kna1-name1.
pi->city = kna1-ort01.
endif.
if pt-pernr ne space.
write pt-pernr to line no-zero.
pi->partnerkey = line.
clear pa0002.
select nachn vorna from pa0002
into corresponding fields of pa0002 where pernr = pt-pernr.
endselect.
concatenate pa0002-nachn pa0002-vorna
into pi->partnername separated by space.
endif.
append pi to partners.
endselect.
s10sort( foldername = 'partners'
columns = 'parvw' userformat = 'X' ).
endmethod.
* sales
method build_sales.
data: year1 type vbrk-gjahr,
year2 type vbrk-gjahr.
year2 = sy-datum(4).
year1 = year2 - 1.
data: begin of s,
prodh type vbrp-prodh,
gjahr type vbrk-gjahr,
netwr type vbrp-netwr,
end of s,
stab like table of s,
totals type ref to salesinfo.
data: ps type ref to salesinfo.
refresh sales.
select
left( vbrp~prodh, 5 ) as prodh,
vbrk~gjahr as gjahr,
sum( vbrp~netwr ) as netwr
from vbrp
inner join vbrk
on vbrk~vbeln = vbrp~vbeln
where vbrk~kunag = @kunnr
and vbrp~posar in (' ','A')
and vbrk~gjahr in (@year1,@year2)
group by prodh, gjahr
order by prodh
into corresponding fields of table @stab.
create object totals.
totals->prodh = '***'.
loop at stab into s.
at new prodh.
create object ps.
ps->prodh = s-prodh.
endat.
case s-gjahr.
when year1. ps->netwr1 = s-netwr.
when year2. ps->netwr2 = s-netwr.
endcase.
at end of prodh.
append ps to sales.
* totals
add ps->netwr1 to totals->netwr1.
add ps->netwr2 to totals->netwr2.
endat.
endloop.
append totals to sales.
* emphasize totals
totals->s10addcss( attrname = 'prodh' cssclassname = 'totals' ).
totals->s10addcss( attrname = 'netwr1' cssclassname = 'totals' ).
totals->s10addcss( attrname = 'netwr2' cssclassname = 'totals' ).
totals->s10addcss( attrname = 'percentage' cssclassname = 'totals' ).
endmethod.
endclass.
Zeile 2: Die Klasse "partnerinfo" beschreibt die Zeilen der Tabelle "Partner". Sie besteht nur aus der Deklaration, da wir keine Methoden benötigen.
Zeile 16: Entsprechend für die Umsatztabelle die Klasse "salesinfo". Hier ist eine build-Methode zum Berechnen des Prozentsatzes implementiert.
Zeile 50: Hier beginnt die Klasse "kna1-detail", welche die eigentlichen Kundendaten enthält.
Zeilen 66 und 67: Die beiden Tabellen "partners" und "sales"
Zeilen 95 und 162: Die build-Methoden für die beiden Tabellen.
Zeile 225: Um die Umsatzsummen hervorzuheben, ordnen wir den Attributen des Summen-Zeilenobjekts die CSS-Klasse "totals" zu. Sie ist in der HTML-Seite wie folgt definiert:
HTML<style>
.totals {
color: #0854a0;
font-weight: bold;
}
</style>

Das HTML-Coding für die einzelnen Teile:
Ausgabe der Kundenadresse
HTML<div class="tabpageactive" id="tabaddr.area" style="padding: 10px">
<div class='output' style='font-size: 16px;' name="mykna1.name1"></div>
<div class='output' style='font-size: 16px;' name="mykna1.name2"></div>
<div class='output' style='font-size: 16px;' name="mykna1.stras"></div>
<div>
<span class='output' style='font-size: 16px;' name="mykna1.pstlz"></span>
<span class='output' style='font-size: 16px;' name="mykna1.ort01"></span>
</div>
<div class='output' style='font-size: 16px;' name='mykna1.land1@text'></div>
</div>
Ausgabe der Partnertabelle<div class="colheaders">
<div name="parvw"
class='colhead colheadup output'
style='width: 60px;
--landscape-width: 60px;'>
</div>
<div name="parvw@text"
class='colhead output landscape'
style='width: 100px;
--landscape-width: 160px;'>
</div>
<div name="partnerkey"
class='colhead landscape'
style='width: 70px;
--landscape-width: 100px;'>
Nummer
</div>
<div name="partnername"
class='colhead'
style='max-width: 300px;
--portrait-width: calc(100% - 180px);
--landscape-width: calc(100% - 460px);'>
Name
</div>
<div name="city"
class='colhead'
style='width: 120px;'>
Ort
</div>
</div>
<form class='table'
name='mykna1.partners'>
<div class="tablerow">
<div name="parvw"
class="outputcelldiv"
style='width: 60px;
--landscape-width: 60px;'>
</div>
<div name="parvw@text"
class="outputcelldiv landscape"
style='width: 100px;
--landscape-width: 160px;'>
</div>
<div name="partnerkey"
class="outputcelldiv landscape"
style='width: 70px;
--landscape-width: 100px;'>
</div>
<div name="partnername"
class="outputcelldiv"
style='max-width: 300px;
--portrait-width: calc(100% - 180px);
--landscape-width: calc(100% - 460px);'>
</div>
<div name="city"
class="outputcelldiv"
style='width: 120px;'>
</div>
</div>
</form>
</div>
Ausgabe der Umsatztabelle<div class="tabpage" id="tabsales.area">
<div class="colheaders">
<div class='colhead colheadup'
style='width: 50px;'
name="prodh">
Nr.
</div>
<div class='colhead'
style='max-width: 240px;
width: calc(100% - 280px);
--portrait-width: calc(100% - 230px);'
name="prodh@text">
Produkthierarchie
</div>
<div class='colhead'
style='width: 90px;
text-align: right'
name="netwr1">
Vorjahr
</div>
<div class='colhead'
style='width: 90px;
text-align: right'
name="netwr2">
Aktuell
</div>
<div class='colhead landscape'
style='width: 50px;
text-align: right'
name="percentage">
%
</div>
</div>
<form class='table'
name='mykna1.sales'>
<div class="tablerow">
<div class='outputcelldiv'
style='width: 50px;'
name="prodh">
</div>
<div class='outputcelldiv'
style='max-width: 240px;
width: calc(100% - 280px);
--portrait-width: calc(100% - 230px);'
name="prodh@text">
</div>
<div class='outputcelldiv'
style='width: 90px;
text-align: right'
name="netwr1">
</div>
<div class='outputcelldiv'
style='width: 90px;
text-align: right'
name="netwr2">
</div>
<div class='outputcelldiv landscape'
style='width: 50px;
text-align: right'
name="percentage">
</div>
</div>
</form>
</div>