BSP Tutorial

Posten Sie hier Tutorials & Cookbooks.
3 Beiträge • Seite 1 von 1
3 Beiträge Seite 1 von 1

BSP Tutorial

Beitrag von Steff (Site Admin / 386 / 0 / 1 ) » 30.09.2004 17:59
Dieses Cookbook beschäftigt sich mit dem Erstellen einer einfachen BSP-Applikationen. Es wird kein Anspruch auf Vollständigkeit erhoben, daher sind Ergänzungen, Hinweise, Verbesserungen jederzeit willkommen und erwünscht.

Ziel mit unserer BSP-Applikation ist es, einen Benutzer anzulegen und anzuzeigen. Dafür werden entsprechende Bausteine (BAPIs) der Benutzerverwaltung verwendet (BAPI_USER_CREATE, BAPI_USER_GETDETAIL, ?)

Eine einfach BSP-Applikation läßt sich über die Transaktion SE80 erstellen. Man wählt dort über die Dropdownliste ?BSP-Applikation? und trägt in das Feld darunter den Namen der BSP-Applikation ein, z.B. Z_USERTEST.
Nach Drücken der Eingabetaste erfolgt die Abfrage, ob die BSP-Applikation angelegt werden soll (sofern sie noch nicht verhanden ist), was bestätigt werden muss.

Mit einem ?Rechtsklick? auf unsere ?neue BSP-Applikation? kann man nun weitere Seiten anlegen, z.B. unsere erste Seite, die auch die Einstiegsseite sein soll. Diese können wir z.B. usercreate.htm nennen. Als Seitentyp, nehmen wir in unserem Beispiel ?Seiten mit Ablauflogik?.

Eine Seite mit Ablauflogik ist im Gegensatz zu einer MVC (Model, View, Controller)-Applikation eine Seite, die zusätzlich bestimmte Events besitzt, die zu bestimmten Zeitpunkten ausgelöst werden.

Die Events werden dabei in folgender Reihenfolge ausgelöst:

OnCreate
OnRequest
OnInitialization
OnInputProcessing
OnManipulation
OnDestroy

Am häufigsten benötigt man OnCreate, OnInitialization und OnInputProcessing.

OnCreate wird dann durchlaufen, wenn die Seite das erste mal erzeugt wird. Hier kann man Daten initialisieren oder Objekte erzeugen.

On Initialization benutzt man i.d.R. zur Datenbeschaffung, also um bestimmte Daten (z.B. mittels Funktionsbaustein) von der Datenbank zu lesen. Die Daten, die man hier beschafft, werden in den Seitenattributen abgelegt.

OnInputProcessing wird immer dann durchlaufen, wenn eine Benutzeraktion erfolgt ist, z.B. der Benutzer drückt einen Button (submit). Ein oft und gern gemachter Fehler ist, daß hier Daten beschafft werden. Das ist bei diesem Event i.d.R. unnötig. Stattdessen sollte man hier die Daten (die der Benutzer eingegeben hat), validieren (evtl. eine Fehlermeldung ausgeben) und bei korrekten Daten abspeichern.
Von diesem Event aus, verzweigt man meistens auf andere Seiten (d.h. es findet eine Navigation statt). Man kann hier zwar Daten an die nächste Seite übergeben, allerdings sollte man darauf achten, daß die Daten, die man übergibt, so ?schlank? wie möglich ausfallen. Meistens ist es absolut ausreichend, bestimmte Schlüsselfelder zu übergeben, und dann im OnInitialization (oder ggf. OnCreate) eine erneute Datenbeschaffung durchzuführen.

Zur Lebensdauer von Seitenattributen siehe SAP Dokumentation zu BSP-Applikationen.

Nach diesen Vorüberlegungen, und dem Anlegen unserer Startseite, treffen wir vorerst noch ein paar weitere Einstellungen. Nach einem Doppelklick auf unsere BSP-Applikation, können wir auf der rechten Seite auf dem Reiter ?Eigenschaften? folgende Parameter setzen:

Einstiegs-BSP: Hier tragen wir z.B. default.htm ein.

Die default.htm ist eine BSP-Seite, die wir uns aus der BSP-Basisapplikation SYSTEM kopieren. Es handelt sich dabei quasi um einen ?Wrapper? um unsere BSP-Applikation, die dafür sorgt, daß beim Beender der Applikation die Benutzer-Session wieder ?zerstört? wird und damit einerseits eine korrekte Abmeldung erfolgt und zum anderen der für die Session allokierte Speicher auf dem Applikationsserver wieder freigegeben wird.

Wir erzeugen einen neuen Modus und öffnen wiederum über Aufruf der Transaktion SE80 die BSP-Applikation ?SYSTEM?. Dort kopieren wir die Seite ?session_single_frame.htm? in unsere BSP-Applikation. Die Seite benennen wir für unsere BSP-Applikation um in default.htm.

Damit nun aber unsere usercreate.htm aufgerufen wird, wenn unsere BSP-Applikation gestartet wird, muss in unserer kopierten default.htm an folgender Stelle das Coding geändert werden:

Code: Alles auswählen.

<% " Copy this page into your BSP application, and change line below.
   " This page should always used be as entry point into application.

   DATA: target_page               TYPE STRING VALUE 'session_test.htm'.
wird abgeändert (für unser Beispiel) in:

Code: Alles auswählen.

<% " Copy this page into your BSP application, and change line below.
   " This page should always used be as entry point into application.

   DATA: target_page               TYPE STRING VALUE 'usercreate.htm'.

Damit kommen wir wieder zurück zu den weiteren Parametern unter ?Eigenschaften? unserer BSP-Applikation.
Der nächste Parameter ist Applikationsklasse.
Dort tragen wir eine Klasse für unsere Applikation ein, die wir über die SE24 anlegen. Die Klasse kann dabei beliebig aussehen. Einzige Einschränkung ist die, daß die Klasse einen Default-Konstruktor besitzen muß. Der Name der Applikationsklasse ist in das betreffende Feld einzutragen, wie die Klasse benannt wird, spielt dabei keine Rolle, z.B.: Z_MY_APPLCLASS.

Warum Applikationsklasse? Mithilfe einer Applikationsklasse lassen sich sehr leicht Daten von einer Seite zur nächsten (Navigation) transportieren. Der Mechanismus ist dabei folgender: Wenn die BSP-Applikation aufgerufen wird, wird eine Instanz unserer Applikationsklasse erzeugt (deshalb der Default-Konstruktor). In den Events kann man nun über die Instanz ?application? auf die eigene Klasse zugreifen.

z.B. im Event ?OnInputProcessing?:

application->set_userid( myuserid );

auf der Folgeseite wieder aus der Applikationsklasse lesen (OnInputProcessing):

myuserid = application->get_userid( ).

Dafür benötigt unsere Applikationsklasse zumindest die obigen Methoden. In der Regel stellt man für jedes Datenobjekt (Parameter, Struktur, Tabelle) jeweils eine set-Methode zum ?Speichern? der Werte und eine get-Methode zum ?Lesen? der Werte.
Wer beispielsweise schon Webanwendungen mit Java (JSP) entwickelt hat, dem dürfte die Architektur solcher Klassen als ?Beans? geläufig sein.

Diese Klasse kann nun über die gesamte Lebensdauer unserer BSP-Applikation (bzw. einer Benutzer-Session) ?erhalten bleiben?, womit wir zum nächsten Parameter unserer BSP-Applikation kommen:

Das Flag ?Zustandsbehaftet?. Dieses Flag schalten wir an, dadurch wird erreicht, daß die Applikationsklasse wie erwähnt über die Dauer der Benutzer-Session erhalten bleibt.

Damit haben wir soweit alles vorbereitet und können mit dem ?Design? unserer Page Usercreate.htm fortfahren.

Unsere Startpage soll, wie anfangs erwähnt, die Daten aufnehmen, um einen Benutzer anzulegen. Der Baustein, um einen Benutzer anzulegen heißt BAPI_USER_CREATE.

Um einen Benutzer anzulegen, werden folgende Daten benötigt:
- Benuterzname
- Passwort
- Adressdaten (z.B.: Vorname, Nachname, Abteilung, e-mail, Telefon, ?)
- Rollen (um entsprechende Berechtigungen zuweisen zu können)

Das repräsentiert quasi die Schnittstellendaten des BAPI_USER_CREATE.
Diese Schnittstellendaten werden nun als Seitenattribute definiert. Dafür können nun eigene Felder definiert werden vom Typ String.

z.B. userid type String,
pw type String,
forename type String,
lastname type String, etc.

Ein mögliche Seite könnte bspw. wie folgt aussehen (Layoutmäßig läßt sich hier noch einiges verbessern, das kann dann jeder für sich selbst tun ;-) )

Code: Alles auswählen.

<%@page language="abap"%>
<%@extension name="htmlb" prefix="htmlb"%>

<htmlb:content design="design2003">
  <htmlb:page title = "Einstiegsseite ">
    <htmlb:form id="createuser">

                    <htmlb:label text = "Benutzer"
                                 for  = "userid" />
                    <htmlb:inputField id            = "userid"
                                      type          = "string"
                                      size          = "8"
                                      value         = "<%=userid%>"
                                      design        = "STANDARD" />
                    </br>

                    <htmlb:label text = "Passwort"
                                 for  = "pw" />
                    <htmlb:inputField id            = "pw"
                                      type          = "string"
                                      size          = "8"
                                      value         = "<%=pw%>"
                                      design        = "STANDARD" />
                    </br>

                    <htmlb:label text = "Vorname"
                                 for  = "forename" />
                    <htmlb:inputField id            = "forename"
                                      type          = "string"
                                      size          = "30"
                                      value         = "<%=forename%>"
                                      design        = "STANDARD" />
                    </br>

                    <htmlb:label text = "Nachname"
                                 for  = "lastname" />
                    <htmlb:inputField id            = "lastname"
                                      type          = "string"
                                      size          = "30"
                                      value         = "<%=lastname%>"
                                      design        = "STANDARD" />

                        </br>


      <htmlb:button       id            = "createbutton"
                          text          = "Submit"
                          onClick       = "createuser" />

    </htmlb:form>
  </htmlb:page>
</htmlb:content>

entgegenzunehmen und auf den Event zu reagieren.
Der Event um auf Benutzereingaben zu reagieren ist i.d.R. ?OnInputProcessing?. In unserer Seite ?usercreate.htm? wecheln wir in den Tabreitern von ?Layout? auf ?Events?. Dort wird über die Dropdownliste der Event ?OnInputProcessing? ausgewählt.
Um auf das Drücken des Buttons reagieren zu können, wird folgendes Coding hinterlegt.

Event: OnInputProcessing:

Code: Alles auswählen.

DATA: event_data  TYPE REF TO cl_htmlb_event,
      var_action TYPE string,
      lv_username    TYPE username,
      lv_password    TYPE bapipwd,
      ls_address     TYPE bapiaddr3,
      lt_return      TYPE  STANDARD TABLE OF bapiret2,
      lt_bapiagr     TYPE  STANDARD TABLE OF bapiagr,
      ls_bapiagr     TYPE  bapiagr,
      ls_logondata   TYPE  bapilogond.


*     Seitenattribute in lokale Variablen
lv_username           = userid.
ls_address-firstname  = forename.
ls_address-lastname   = lastname.
lv_password           = pw.


*   Event auswerten
CLASS cl_htmlb_manager DEFINITION LOAD.
IF cl_htmlb_manager=>event_id EQ 'htmlb'. "equals htmlb
  event_data = cl_htmlb_manager=>get_event( request ).

  IF event_data->event_type EQ 'click'.

    var_action = event_data->server_event.

    IF var_action EQ 'createuser'.
* Anlegen Benutzer (SU01)
      CALL FUNCTION 'BAPI_USER_CREATE'
        EXPORTING
          username  = lv_username
          logondata = ls_logondata
          password  = lv_password
          address   = ls_address
        TABLES
          return    = lt_return.


* Zuordnung Rolle
      ls_bapiagr-agr_name = 'SAP_BC_DWB_ABAPDEVELOPER'.
      append ls_bapiagr to lt_bapiagr.

      CALL FUNCTION 'BAPI_USER_ACTGROUPS_ASSIGN'
        EXPORTING
          username       = lv_username
        TABLES
          activitygroups = lt_bapiagr
          return         = lt_return.

        COMMIT WORK.

    ENDIF.

  ENDIF.
ENDIF.

Damit kann nun ein auf einfache Weise ein Benutzer anlegt werden. In dem Beispiel fehlt natürlich noch einiges, z.B. Fehlerhandling, Abmelden, etc.
Das wird in den nächsten Teilen zu diesem Tutorial sukzessive ausgebaut.

Wobei natürlich jeder der Lust und Interesse hat, hier gerne seine Vorschläge, Verbesserungen, Erweiterungen, etc. posten kann.
Bis bald, zum nächsten Teil des BSP-Tutorials :-)
Zuletzt geändert von Steff am 18.10.2004 17:42, insgesamt 1-mal geändert.

Folgende Benutzer bedankten sich beim Autor Steff für den Beitrag:
lor.anka



Auf zum Teil 2 - Fehlerhandling

Beitrag von Steff (Site Admin / 386 / 0 / 1 ) » 18.10.2004 17:41
Fehlerhandling:

Für das Fehlerhandling kann man wie folgt vorgehen.
Include Anlegen (Rechte Maustaste -> Anlegen Seite -> Seitenfragment). Das Seitenfragment kann man z.B. error.htm nennen.
Aussehen kann das Seitenfragment so:

Code: Alles auswählen.

<%@page language="ABAP"%>
<!-- Start Error Msg-->
<table align="center" cellpadding="0" cellspacing="0" width="99%" border="0">
  <tr>
        <td width="100%" class="TX_ERROR_XSB">
        <img src="layout/error.gif" border="0" /><%=otr(Z_TESTAPP/ERRORS_OCCURED_MSG)%>:
        </td>
  </tr>
<%
    data: condition type string,
    message type string,
    severity type i,
    ind type i.
    ind = page->messages->num_messages( ).
        do ind times.
            call method page->messages->Get_message
            exporting index = sy-index
            importing condition = condition
            message = message
            severity = severity. %>
<tr>
    <td class="TX_ERROR_XSB">- <%= message %> </td>
</tr>
        <% enddo. %>

</table>
<!-- End Error Msg -->

Dieses ?Fehlerseitenfragment? wird in die bestehende Seite inkludiert:

Code: Alles auswählen.

    <% if page->messages->num_messages( ) > 0. %>
    <%@ include file="error.htm"%>
    <% endif.
Nun kann man in unserer Page (siehe coding weiter oben) nach dem BAPI zum Anlegen eines Users, die Rückgabetabelle auswerten (um entsprechende Meldungen auszugeben). Siehe oben, Ergänzung zum Event 'OnInputProcessing' unserer Page. Diess Coding wird unmittelbar nach dem BAPI_USER_CREATE eingefügt.

Code: Alles auswählen.

*       check for messages
        DATA: lv_lines TYPE i.
        DESCRIBE TABLE lt_return LINES lv_lines.

        IF lv_lines > 0.
          READ TABLE lt_return INDEX 1 INTO ls_return.
          IF ls_return-type = 'S' AND ls_return-id     = '01'
                                  AND ls_return-number = '102'.

          ELSE.
            LOOP AT lt_return INTO ls_return.
              CALL METHOD page->messages->add_message_from_t100
                EXPORTING
                  condition = errormessage
                  msgid     = ls_return-id
                  msgno     = ls_return-number
                  msgty     = ls_return-type.
            ENDLOOP.
            EXIT.
          ENDIF.
        ENDIF.

Die Funktionsweise ist folgende: Dem Page-Objekt, kann man Fehlermeldungen mitgeben. Diese Fehlermeldungen werden dann in der Seite dadurch ausgewertet, daß das Include (Seitenfragment) eingeblendet wird, wenn die message-Tabelle des Pageobjektes Einträge enthält.
Im Seitenfragment selbst, wird dann einfach die Tabelle ausgewertet und die entsprechenden Fehlermeldungen werden ausgegeben über das Tag <%= message %>.

Bis zum nächsten Teil dieses Tutorials ? Wie immer gilt: Kommentare und Verbesserungsvorschläge erwünscht.

Super !

Beitrag von Gast ( / / 0 / 3 ) » 19.10.2004 09:09
Echt Klasse Tutorial, ich freue mich schon auf Teil 2

Seite 1 von 1

Über diesen Beitrag


Unterstütze die Community und teile den Beitrag für mehr Leser und besseren Inhalt:

Vergleichbare Themen

OO ALV: Tutorial?
von Gast » 13.05.2005 12:40
Tutorial JCo
von Seneca » 10.09.2003 12:15
HR TUTORIAL
von GAST » 18.01.2005 12:42
LSMW Tutorial
von joe_hd » 04.01.2011 13:15
Tutorial für ALV Grids
von Senshi » 13.08.2007 08:29