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:

HTML
<!-- 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
HTML
<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
HTML
<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>