Connector für SAP Business Suite - Entwicklerhandbuch - Mustercodings

1. Mustercodings

1.1. Austausch von Lösungen – der Community-Gedanke

Jeder, der mit IT-Lösungen zu tun hat, ist dankbar über Hinweise, Musterlösungen oder fertig einsetzbare Applikationen. Dieses Geben und Nehmen von Informationen ist nicht für jedermann selbstverständlich, da damit oft auch viel Know-how öffentlich wird. Letzteres war aber kein Hindernis, diese Dokumentation zu veröffentlichen. Für uns steht der Austausch von Ideen im Vordergrund. Alltägliche Herausforderungen müssen keine sein, wenn immer wiederkehrende Probleme gut dokumentiert sind. Damit wird wieder Zeit für das kreative Gestalten von IT-Lösungen frei. Der Austausch von Ideen und Lösungen ist im Intrexx-Umfeld sehr einfach. Über den Export und Import von Applikationen können komplexe Portalentwicklungen sehr einfach ausgetauscht werden. Besuchen Sie unseren Application Store! Hier finden Sie eine große Auswahl von fertigen Applikationen und Layouts für Ihr Portal. Im Intrexx Forum finden Sie unter anderem auch die Kategorie "Connectoren", in dem Sie sich mit Anderen zum Thema SAP Business Suite austauschen können.

Im SAP-Umfeld ist es leider nicht ganz so einfach, Anwendungen mit anderen auszutauschen. Hier sind es mehr organisatorische Hürden (z.B. Berechtigungen, unternehmensinterne Restriktionen), die den Community-Gedanken behindern. Es gibt Bestrebungen, dies zu ändern. So ist z.B. das Software Developer Network http://sdn.sap.com eine sehr gute Adresse, um Gleichgesinnte zu finden. Außerdem ist auch die SAP-Welt komplexer geworden. Es sind nicht mehr nur SAP-Reports, die man mit einfachen Textdateien weitergeben kann. Für aktuelle Technologien wie ABAP-Objects, WebDynpro usw. muss meistens ein SAP-Transport verwendet werden, um Implementierungen in andere SAP-Systeme zu übertragen. Aus diesem Grund hat sich das Open Source Projekt SAPlink organisiert. Ziel des Projektes ist vor allem, komplexe SAP-Anwendungen über einen alternativen Mechanismus auszutauschen. SAP-Objekte werden hier nicht über SAP-Transporte weiter gegeben. SAPLink verpackt die wichtigsten SAP-Objekte in XML-Strukturen, den sogenannten "Nuggets". Dies erlaubt eine frühe Einsichtnahme in die Inhalte eines Pakets, bevor es in ein SAP-System eingespielt wird. Außerdem kann damit eine systemübergreifende Versionierung, wie es z.B. im Nicht-SAP-Bereich über Versionierungstools wie CVS und Subversion üblich ist, eingesetzt werden.

Intrexx-Erweiterungen sind in den meisten Fällen Erweiterungen über ABAP-Objects-Klassen (Datengruppen-Handler), Funktionsgruppen oder einfache Reports. Rein technisch würde der Austausch solcher Erweiterungen über die SAPlink-Tools gelingen. Hier sind wir aber auf Ihre Mitarbeit angewiesen und freuen uns über jedes neue "Nugget" im Internet.

Handler für SAP-Fremddatengruppen

Handler für SAP-Fremddatengruppen basieren auf dem Erweiterungskonzept des SAP-Portal-Plugins SAPPOPI. Das Grundprinzip dieses Erweiterungskonzeptes ist das Vererben einer ABAP-Objects-Klasse von einer Vorlage bzw. von einem anderen Handler. Danach werden je nach Anforderung die API-Methoden des Handler redefiniert. Die Handler müssen als Klasse im SAP-Portal-Plugin registriert werden. Danach erfolgt die Registrierung eines Mappings von der im Intrexx-Portal verwendeten Datengruppen-ID auf den tatsächlichen ABAP-Objects-Handler. Bei kundenindividuellen Anpassungen ist es üblich, eine ABAP-Struktur zu definieren, die alle extern verfügbaren Felder enthält und nicht unbedingt als physische Tabelle vorhanden sein muss. Diese Struktur (z.B. "Z_INTREXX_F4_KNA1") wird dann extern als Tabellenname in den Datengruppen verwendet. Durch das Mapping im SAP wird der richtige Handler ermittelt. Weitere Informationen finden Sie im API Entwicklerhandbuch.

2.1. Mustercoding: F4 Hilfe auf SAP-Kundenstamm

Voraussetzung für dieses Coding ist eine Struktur (hier "ZITIX_IXA_F4_KNA1"), die die gewünschten Felder für die Suchhilfe und ein spezielles Suchfeld (hier "SEARCH") enthält. Diese Struktur wurde als Transferstruktur für den Handler verwendet und registriert. Der Zugriff aus dem Portal erfolgt über den Namen der Transferstruktur.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* ---- local data
  DATA: ls_data TYPE zitix_ixa_f4_kna1.
  DATA: lt_data LIKE TABLE OF ls_data.
  DATA: ls_filter LIKE LINE OF it_filter.
  DATA: lv_search TYPE string.
  DATA: lt_kna1 TYPE TABLE OF kna1.
  DATA: ls_kna1 LIKE LINE OF lt_kna1.
  DATA: lv_tabix TYPE sytabix.

* ---- init
  cv_processed = 'X'.


* ---- get search
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'SEARCH'.
  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

  lv_search = ls_filter-value_low.

  IF lv_search EQ '' OR lv_search EQ '*'.
    EXIT.
  ENDIF.

  REPLACE ALL OCCURRENCES OF '*' IN lv_search WITH '%'.

* ----- search postcode
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE pstlz LIKE lv_search.

* ----- search name1
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE name1 LIKE lv_search.

* ----- search name2
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE name2 LIKE lv_search.

* ----- search ort01
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE ort01 LIKE lv_search.

* ----- search kunnr
  SELECT * FROM kna1 APPENDING TABLE lt_kna1
    WHERE kunnr LIKE lv_search.

* ----- sort and delete duplicates
  SORT lt_kna1.
  DELETE ADJACENT DUPLICATES FROM lt_kna1.


* ----- build transfer table
  LOOP AT lt_kna1 INTO ls_kna1.
    MOVE-CORRESPONDING ls_kna1 TO ls_data.
    ls_data-search = lv_search.
    APPEND ls_data TO lt_data.
  ENDLOOP.

* ------ sort

* ------ final build export
  LOOP AT lt_data INTO ls_data.
    lv_tabix = sy-tabix.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
*    IT_REQUESTED    =
        iv_data_struc   = 'ZITIX_IXA_F4_KNA1'
        iv_key_value    = ls_data-kunnr
        iv_record       = lv_tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
        iv_convert      = 'X'
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2
            .
    IF sy-subrc EQ 0.
      ADD 1 TO ev_count.
    ENDIF.

  ENDLOOP.

ENDMETHOD.

2.2. Mustercoding: Interne Tabelle übertragen

Die ausführliche Dokumentation zu diesem Beispiel finden Sie hier. dokumentiert. Es werden die Ansprechpartner zu einem SAP-Geschäftspartner ermittelt und sortiert ausgegeben. Die API-Methode "GET_DETAIL" wird dafür verwendet, die Details aufzubereiten.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* -------------- local data
  DATA: lt_data TYPE TABLE OF yixapi_demo_bapi_conr.
  DATA: lt_data_int TYPE TABLE OF yixapi_demo_bapi_conr.
  DATA: ls_data TYPE yixapi_demo_bapi_conr.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: ls_filter TYPE LINE OF zia_ixa_api_intrexx_filter_t.
  DATA: lv_org TYPE bu_partner.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lv_error.
  DATA: lv_processed TYPE xfeld.
  DATA: lv_lin TYPE i.
  DATA: lt_rel TYPE TABLE OF bapibus1006_relations.
  DATA: ls_rel TYPE bapibus1006_relations.
  DATA: ls_orderby TYPE LINE OF zia_ixa_api_intrexx_orderby_t.
  DATA: lv_rows TYPE i.


* -------------- init
  cv_processed = 'X'.
  ev_error     = 'X'.


* -------------- get inbound parameters
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'ORG_ID'.
  IF sy-subrc NE 0.
    ev_error     = ' '.
    EXIT.
  ENDIF.
  lv_org = ls_filter-value_low.


* -------------- initial check routines
  IF lv_org IS INITIAL.
    ev_error     = ' '.
    EXIT.
  ENDIF.


* -------------- process
* 1. Search
  CALL FUNCTION 'BAPI_BUPA_RELATIONSHIPS_GET'
    EXPORTING
      businesspartner = lv_org
    TABLES
      relationships   = lt_rel
      return          = lt_return.
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.

* 2. check relations
  DESCRIBE TABLE lt_rel LINES lv_lin.
  CHECK lv_lin GT 0.

* 3. build data table
  LOOP AT lt_rel INTO ls_rel
    WHERE relationshipcategory  = 'BUR001'
      AND validfromdate         LE sy-datum
      AND validuntildate        GE sy-datum.
*   build key
    CONCATENATE ls_rel-partner1
                ls_rel-partner2
                INTO lv_key
                SEPARATED BY '~'.
*   clear working var
    CLEAR me->current_data.

*   build detail information; transfer via working var
    CALL METHOD me->z_if_ia_ixa_intrexx_api~get_detail
      EXPORTING
        iv_key           = lv_key
*    IT_REQUESTED     =
*  IMPORTING
*    EV_ERROR         =
*    ET_MESSAGES      =
*    ET_RESULT_VALUES =
      CHANGING
        cv_processed     = lv_processed
      EXCEPTIONS
        failed           = 1
        OTHERS           = 2
            .
    IF sy-subrc EQ 0
      AND lv_processed EQ 'X'
      AND NOT me->current_data IS INITIAL.
*     append working var to table
      APPEND me->current_data TO lt_data.
    ENDIF.
  ENDLOOP.


* -------------- fill outbound parameters
* 1. ev_count
  DESCRIBE TABLE lt_data LINES ev_count.
* 2. sort internal table
  DESCRIBE TABLE it_orderby LINES lv_lin.
  IF lv_lin EQ 1.
    READ TABLE it_orderby INTO ls_orderby INDEX 1.
    IF ls_orderby-ordertype EQ 'A'.
      SORT lt_data BY (ls_orderby-fieldname) ASCENDING.
    ELSE.
      SORT lt_data BY (ls_orderby-fieldname) DESCENDING.
    ENDIF.
  ELSE.
    SORT lt_data BY per_id.
  ENDIF.

* 3. check offset access
  IF iv_max_rows GT 0 OR iv_start_row GT 0.
*   move to a working tab
    lt_data_int[] = lt_data.
    REFRESH lt_data.

*   loop working tab
    LOOP AT lt_data_int INTO ls_data.

*     check offset access
      IF iv_start_row GT 0
        AND sy-tabix LE iv_start_row.
        CONTINUE.
      ENDIF.

*     append to exporting tab
      APPEND ls_data TO lt_data.

*     check max rows
      IF iv_max_rows GT 0.
        ADD 1 TO lv_rows.
        IF lv_rows GE iv_max_rows.
          EXIT.
        ENDIF.
      ENDIF.

    ENDLOOP.
  ENDIF.

* 4. loop and fill export
  LOOP AT lt_data INTO ls_data.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
        it_requested    = it_requested
        iv_data_struc   = 'YIXAPI_DEMO_BAPI_CONR'
        iv_key_value    = ls_data-lid
        iv_record       = sy-tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2.
    IF sy-subrc EQ 0.
*     ignore
    ENDIF.
  ENDLOOP.


* -------------- finally set no error
  ev_error    = ' '.


ENDMETHOD.
METHOD z_if_ia_ixa_intrexx_api~get_detail.

* ------ local data
  DATA: lv_org  TYPE bu_partner.
  DATA: lv_per  TYPE bu_partner.
  DATA: ls_data TYPE yixapi_demo_bapi_conr.
  DATA: ls_relation TYPE bapibus1006002_central.
  DATA: ls_central TYPE bapibus1006_central.
  DATA: ls_person TYPE bapibus1006_central_person.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: lv_error.
  DATA: lv_language TYPE spras.


* ------ set default
  ev_error = 'X'.
  cv_processed = 'X'.


* ------ check for new record
  IF iv_key EQ space OR iv_key EQ '-1'.
* ------ optional: set a default data structure and leave without errors
    EXIT.
  ELSE.
* ------ split key
    SPLIT iv_key AT '~' INTO lv_org lv_per.
* ------ check key
    CHECK lv_org NE space AND lv_per NE space.
  ENDIF.

* ------ get data relation
  CALL FUNCTION 'BAPI_BUPR_CONTP_GETDETAIL'
    EXPORTING
      businesspartner           = lv_org
      contactperson             = lv_per
   IMPORTING
*     VALIDFROMDATE             =
*     VALIDUNTILDATE            =
*     DEFAULTRELATIONSHIP       =
      centraldata               = ls_relation
   TABLES
     return                    = lt_return
            .
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.


* ------- get data BP
  CALL FUNCTION 'BAPI_BUPA_CENTRAL_GETDETAIL'
    EXPORTING
      businesspartner   = lv_per
      valid_date        = sy-datum
    IMPORTING
      centraldata       = ls_central
      centraldataperson = ls_person
    TABLES
      return            = lt_return.
  LOOP AT lt_return TRANSPORTING NO FIELDS
    WHERE type CA 'EAX'.
    lv_error = 'X'.
    EXIT.
  ENDLOOP.
  CHECK lv_error NE 'X'.



* -------- build transfer record
* 1. BAPI Info
  MOVE-CORRESPONDING ls_relation TO ls_data.
  MOVE-CORRESPONDING ls_central  TO ls_data.
  MOVE-CORRESPONDING ls_person   TO ls_data.

* 2. ID Info
  ls_data-org_id  = lv_org.
  ls_data-per_id  = lv_per.

* 3. Key Info
  CONCATENATE lv_org lv_per
    INTO ls_data-lid
    SEPARATED BY '~'.

* 4. generate additional text fields with type converting
*    get portal language
  CALL METHOD me->map_intrexx_language_to_sap
    EXPORTING
      iv_language = me->ix_control-ix_language
    IMPORTING
      ev_language = lv_language
    EXCEPTIONS
      not_found   = 1
      OTHERS      = 2.
  IF sy-subrc <> 0.
    lv_language = sy-langu.
  ENDIF.
*  get department
  IF ls_data-department NE space.
    SELECT SINGLE bez20 FROM tb911 INTO ls_data-text_abtnr
      WHERE spras EQ lv_language
        AND abtnr EQ ls_data-department.
  ENDIF.

*  get function
  IF ls_data-function NE space.
    SELECT SINGLE bez30 FROM tb913 INTO ls_data-text_pafkt
      WHERE spras EQ lv_language
        AND pafkt EQ ls_data-function.
  ENDIF.


* -------- save for other API Methods
  me->current_data = ls_data.


* -------- build export
  CALL METHOD me->set_results_from_struc
    EXPORTING
      is_data         = ls_data
*    IT_REQUESTED    =
      iv_data_struc   = 'YIXAPI_DEMO_BAPI_CONR'
      iv_key_value    = ls_data-lid
      iv_record       = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
*    CT_KEYS         =
      ct_results      = et_result_values
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.


* ------- finally OK result
  ev_error = ' '.

ENDMETHOD.

2.3 Mustercoding: Dokumente aus dem Archivsystem über URL

Dieses Mustercoding ermittelt zu einer Kundennummer (aus dem Benutzerkontext) alle verfügbaren Vertriebsdokumente des Archivs (z.B. Auftragsbestätigungen). An das Portal wird die URL auf die externen Dokumente zurückgeliefert. Diese kann hier ggf. noch angepasst werden.
METHOD z_if_ia_ixa_intrexx_api~get_list.

* ---------- local data
  DATA: ls_filter LIKE LINE OF it_filter.
  DATA: lv_kunnr TYPE kunnr.
  DATA: ls_data TYPE Z_IXAPI_ARCHIV_DOC_VBAK.
  DATA: lt_data LIKE TABLE OF ls_data.
  DATA: lv_url TYPE string.

* --------- init
  ev_error = ' '.
  cv_processed = 'X'.

* --------- check inbound parameter - get kunnr from context
  READ TABLE it_filter INTO ls_filter
    WITH KEY fieldname = 'KUNNR'
             operand   = 'EQ'.
  IF sy-subrc NE 0.
    EXIT.
  ELSE.
* --------- add leading 0
    lv_kunnr = ls_filter-value_low.
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = lv_kunnr
      IMPORTING
        output = lv_kunnr
  ENDIF.

* ---------- get all orders (from table VBAK)
  DATA: lt_vbak TYPE TABLE OF vbak.
  DATA: ls_vbak TYPE vbak.


* ---------- get depending vbak record
  SELECT * FROM vbak
      INTO TABLE lt_vbak
      WHERE kunnr = lv_kunnr.
  CHECK NOT lt_vbak[] IS INITIAL.


* ---------- loop VBAK and fill export table with archive URL 
  DATA: lv_objid TYPE saeobjid.
  DATA: lt_url TYPE TABLE OF toauri.
  DATA: ls_url LIKE LINE OF lt_url.
  DATA: lv_lin TYPE i.
  DATA: lv_tabix TYPE sytabix.

  LOOP AT lt_vbak INTO ls_vbak.
    lv_tabix = sy-tabix.

*   prepare export table
    CLEAR ls_data.
    MOVE-CORRESPONDING ls_vbak TO ls_data.
    ls_data-kunnr = lv_kunnr.

*   get archive info
    lv_objid = ls_vbak-vbeln.
    REFRESH lt_url.
    CALL FUNCTION 'ARCHIVOBJECT_GET_URI'
      EXPORTING
        objecttype               = 'VBAK'
        object_id                = lv_objid
        location                 = 'B'
        http_url_only            = 'X'
      TABLES
        uri_table                = lt_url
      EXCEPTIONS
        error_archiv             = 1
        error_communicationtable = 2
        error_kernel             = 3
        error_http               = 4
        error_dp                 = 5
        OTHERS                   = 6.
    IF sy-subrc EQ 0.
      DESCRIBE TABLE lt_url LINES lv_lin.
      IF lv_lin GE 1.
        READ TABLE lt_url INTO ls_url INDEX lv_lin.
        IF sy-subrc EQ 0.
          ls_data-url = ls_url-uri.
        ENDIF.
      ENDIF.
    ENDIF.

*   optional replace the sap like URL with a extern available prefix
*   …

*   append record to export
    APPEND ls_data TO lt_data.

    sy-tabix = lv_tabix.
  ENDLOOP.


* ----------- sort
  DELETE lt_data WHERE url EQ space.
  SORT lt_data BY vbeln DESCENDING.


* ----------- loop and fill to final export parameter
  LOOP AT lt_data INTO ls_data.
    CALL METHOD me->set_results_from_struc
      EXPORTING
        is_data         = ls_data
*    it_requested    =
        iv_data_struc   = 'Z_IXAPI_ARCHIV_DOC_VBAK'
        iv_key_value    = ls_data-vbeln
        iv_record       = sy-tabix
        iv_struc_name   = 'DEFAULT'
        iv_struc_record = 0
        iv_convert      = 'X'
      CHANGING
        ct_keys         = et_result_keys
        ct_results      = et_result_values
      EXCEPTIONS
        failed          = 1
        OTHERS          = 2
            .
    IF sy-subrc EQ 0.
      ADD 1 TO ev_count.
    ENDIF.
  ENDLOOP.

* ----------- set final
  ev_error     = ' '.

ENDMETHOD.

2.4 Mustercoding: Generischer Handler Read & Write

Die Beschreibung der Verwendung des Datahandlers finden Sie hier.
METHOD z_if_ia_ixa_intrexx_api~initialize.
  CALL METHOD super->z_if_ia_ixa_intrexx_api~initialize
    EXPORTING
      is_control = is_control
    EXCEPTIONS
      failed     = 1
      OTHERS     = 2.
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.
  me->cfgtag = 'ixapida'.
ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~prepare_usage_after_creation.

* --------- check object type GENERIC_WRITE
  IF me->cust_mapping-ix_objecttype EQ 'GENERIC_WRITE'.
* ---- set defaults to object customzing
    IF me->cust_object-struc_transfer IS INITIAL.
      me->cust_object-struc_transfer = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-struc_data IS INITIAL.
      me->cust_object-struc_data = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-master_tab IS INITIAL.
      me->cust_object-master_tab = me->ix_control-ix_datagroup.
    ENDIF.
    IF me->cust_object-field_key IS INITIAL.
      me->cust_object-field_key = 'GUID'.
    ENDIF.
* ---- create transfer
    CALL METHOD z_cl_ia_ixa_object=>create_data_and_build_ddic
      EXPORTING
        iv_tabname = me->cust_object-struc_transfer
      IMPORTING
        er_data    = me->transfer
        et_ddic    = me->ddic_transfer[]
      EXCEPTIONS
        failed     = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      RAISE failed.
    ENDIF.

* ---- create data
    CALL METHOD z_cl_ia_ixa_object=>create_data_and_build_ddic
      EXPORTING
        iv_tabname = me->cust_object-struc_data
      IMPORTING
        er_data    = me->data
        et_ddic    = me->ddic_data[]
      EXCEPTIONS
        failed     = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
      RAISE failed.
    ENDIF.

  ENDIF.

* --------- call super
CALL METHOD super->z_if_ia_ixa_intrexx_api~prepare_usage_after_creation
    EXCEPTIONS
      failed = 1
      OTHERS = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.


ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~modify.

* --------- local data
  DATA: lv_new.
  FIELD-SYMBOLS: <data> TYPE data.
  FIELD-SYMBOLS: <transfer> TYPE data.
  FIELD-SYMBOLS: <key> TYPE data.
  DATA: lv_guid TYPE zia_ixa_guid.
  DATA: lv_fkey(40) VALUE '<data>-guid'.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lt_sql TYPE zia_ixa_api_intrexx_sql_t.
  DATA: ls_sql TYPE LINE OF zia_ixa_api_intrexx_sql_t.



* ---------- prepare data
  ASSIGN me->data->* TO <data>.
  ASSIGN me->transfer->* TO <transfer>.
  CHECK <data> IS ASSIGNED.
  CHECK <transfer> IS ASSIGNED.

* ---------- prepare key access
  ASSIGN (lv_fkey) TO <key>.
  CHECK <key> IS ASSIGNED.


* ---------- check given key
  lv_new = 'X'.
  IF NOT iv_key IS INITIAL.
    lv_key = iv_key.

* ---------- prepare sql
    CHECK me->cust_object-field_key NE space.
    CONCATENATE ''''
                lv_key
                ''''
                INTO ls_sql-line.
    CONCATENATE me->cust_object-field_key
                'EQ'
                ls_sql-line
                INTO ls_sql-line
                SEPARATED BY ' '.
    APPEND ls_sql TO lt_sql.


    SELECT SINGLE * FROM (me->cust_object-master_tab) INTO <data>
      WHERE (lt_sql).
    IF sy-subrc EQ 0.
      CLEAR lv_new.
    ENDIF.
  ENDIF.

* ---------- create key
  IF lv_new EQ 'X'.
    IF iv_key IS INITIAL.
      CALL FUNCTION 'GUID_CREATE'
        IMPORTING
          ev_guid_16 = lv_guid.
      lv_key = lv_guid.
    ELSE.
      lv_key = iv_key.
    ENDIF.
  ENDIF.


* ---------- get inbound
  MOVE-CORRESPONDING <data> TO <transfer>.
  CALL METHOD me->map_inbound_fields
    EXPORTING
      iv_delete = ' '
      it_fields = it_fields.

* ---------- set key
  <key> = lv_key.


* ---------- modify database
  SET UPDATE TASK LOCAL.
  MODIFY (me->cust_object-master_tab) FROM <data>.
  IF sy-subrc NE 0.
    ROLLBACK WORK.
    EXIT.
  ELSE.
    COMMIT WORK.
  ENDIF.

* ----------- map modified data to outbound
  CALL METHOD me->map_outbound_fields
    EXPORTING
      iv_index        = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
      ct_fields       = et_fields
*    ct_keys         =
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.

* ---------- finally set processed flag
  ev_key = lv_key.
  cv_processed = 'X'.


ENDMETHOD. 

METHOD z_if_ia_ixa_intrexx_api~delete.
* --------- local data
  DATA: lv_new.
  FIELD-SYMBOLS: <data> TYPE data.
  FIELD-SYMBOLS: <transfer> TYPE data.
  FIELD-SYMBOLS: <key> TYPE data.
  DATA: lv_guid TYPE zia_ixa_guid.
  DATA: lv_fkey(40) VALUE '<data>-guid'.
  DATA: lv_key TYPE zia_ixa_fieldvalue.
  DATA: lt_sql TYPE zia_ixa_api_intrexx_sql_t.
  DATA: ls_sql TYPE LINE OF zia_ixa_api_intrexx_sql_t.
  DATA: lv_field_key TYPE string.


* ---------- check key
  CHECK iv_key NE space.

* ---------- prepare data
  ASSIGN me->data->* TO <data>.
  ASSIGN me->transfer->* TO <transfer>.
  CHECK <data> IS ASSIGNED.
  CHECK <transfer> IS ASSIGNED.

* ---------- prepare key access
  lv_field_key = me->cust_object-field_key.
  IF lv_field_key IS INITIAL.
    lv_field_key = 'guid'.
  ENDIF.
  CONCATENATE '<data>-' lv_field_key INTO lv_fkey.
  ASSIGN (lv_fkey) TO <key>.
  CHECK <key> IS ASSIGNED.


* ---------- check given key
  lv_key = iv_key.

* ---------- prepare sql
  CONCATENATE ''''
              lv_key
              ''''
              INTO ls_sql-line.
  CONCATENATE lv_field_key
              'EQ'
              ls_sql-line
              INTO ls_sql-line
              SEPARATED BY ' '.
  APPEND ls_sql TO lt_sql.


  SELECT SINGLE * FROM (me->cust_object-master_tab) INTO <data>
    WHERE (lt_sql).
  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

* ---------- get inbound
  MOVE-CORRESPONDING <data> TO <transfer>.


* ---------- modify database
  SET UPDATE TASK LOCAL.
  DELETE FROM (me->cust_object-master_tab) WHERE (lt_sql).
  IF sy-subrc NE 0.
    ROLLBACK WORK.
    EXIT.
  ELSE.
    COMMIT WORK.
  ENDIF.

* ----------- map modified data to outbound
  CALL METHOD me->map_outbound_fields
    EXPORTING
      iv_index        = 1
      iv_struc_name   = 'DEFAULT'
      iv_struc_record = 0
    CHANGING
      ct_fields       = et_fields
*    ct_keys         =
    EXCEPTIONS
      failed          = 1
      OTHERS          = 2
          .
  IF sy-subrc <> 0.
    RAISE failed.
  ENDIF.

* ---------- finally set processed flag
  cv_processed = 'X'.

ENDMETHOD.

2.5. Mustercoding: Datahandler Generic Report

Der folgende Handler übernimmt das Starten von einfachen Reports und die Übergabe der Ergebnisse an Intrexx. Für ältere Systeme kann dieser Handler auch selbst angelegt werden. Die Klasse muss von einer Generic-View-Klasse vererbt (z.B. "Z_CL_IA_IXA_GENERIC_VIEW") und als Data-Handler für "GENERIC_REPORT" registriert werden. Die folgenden Methoden sind weiterhin anzulegen bzw. zu redefinieren.
method z_if_ia_ixa_intrexx_api~get_data_objects.

* ------- local data
  data: ls_do type line of zia_ixa_api_intrexx_dataobj_t.
  data: lv_wildcard type zia_ixa_fieldvalue.
  data: lv_max_rows type i.
  data: begin of ls_prog,
          progname type progname,
        end of ls_prog.
  data: lt_prog like table of ls_prog.
  data: ls_report type rstionamex.
  data: lv_text type rsti_title.
  data: lv_langu type sylangu.

* ------- init
  refresh et_data_objects.
  cv_processed = 'X'.
  lv_wildcard  = iv_wildcard.
  while sy-subrc eq 0.
    replace '*' with '%' into lv_wildcard.
  endwhile.
  lv_max_rows = iv_max_rows.
  if lv_max_rows le 0.
    lv_max_rows = 200.
  endif.

* ------- check
  check not lv_wildcard is initial.


* ------- GENERIC REPORT
  select progname from reposrc
    into table lt_prog
    up to lv_max_rows rows
    where progname like lv_wildcard
      and r3state eq 'A'
      and subc    eq '1'.


* -------- map external language
  call method z_cl_ia_ixa_generic_report=>map_intrexx_language_to_sap
    exporting
      iv_language = me->ix_control-ix_language
    importing
      ev_language = lv_langu
    exceptions
      not_found   = 1
      others      = 2.
  if sy-subrc <> 0.
    lv_langu = sy-langu.
  endif.



* -------- map selected reports
  loop at lt_prog into ls_prog.
    ls_do-dataobject  = ls_prog-progname.
    ls_report-onam = ls_prog-progname.

    call function 'RRI_RT_REPORT_TEXT'
      exporting
        e_s_onamext = ls_report
        e_langu     = lv_langu
      importing
        i_text      = lv_text
      exceptions
        not_found   = 1
        others      = 2.
    if sy-subrc <> 0.
      ls_do-description = ls_prog-progname.
    else.
      ls_do-description = lv_text.
    endif.

    append ls_do to et_data_objects.
  endloop.

endmethod.
method z_if_ia_ixa_intrexx_api~get_list.

  data: ls_filter type line of zia_ixa_api_intrexx_filter_t.
  data: ls_par type rsparams.
  data: lt_par type table of rsparams.
  data: lt_requested type zia_ixa_api_intrexx_rq_flds_t.
  data: ls_requested type line of zia_ixa_api_intrexx_rq_flds_t.

  data: lv_report type progname.
  data: lt_list  type tedrtext.
  data: ls_list  type line of tedrtext.
  data: lv_text type string.
  data: ls_ddic type dfies.

  data: lt_html  type w3htmltab.
  data: ls_html  type line of w3htmltab.
  data: lv_html      type string.

  field-symbols: <transfer> type data.
  field-symbols: <data> type data.
  field-symbols: <lid> type data.
  field-symbols: <line> type data.
  data: lv_error type xfeld.

  data: begin of ls_line,
          line(255),
        end of ls_line.
  data: lt_line like table of ls_line.
  data: lv_tabix type sytabix.
  data: lv_value type zia_ixa_fieldvalue.

  data: lt_scr type table of rsscr.
  data: ls_scr type rsscr.
  data: lv_subrc type sysubrc.
  data: lv_rows type i.


* --------------------- MACRO
  define map_ix_to_sap.
    lv_value = &1.
    if lv_value ne space.

      call method me->map_fieldvalue_ix_to_sap
        exporting
          is_control  = me->ix_control
          iv_function = me->current_api_function
          is_ddic     = ls_ddic
        changing
          cv_value    = lv_value.
      &1 = lv_value.
    endif.
  end-of-definition.


* ------------ prepare
  assign me->transfer->* to <transfer>.
  assign me->data->* to <data>.
  check <transfer> is assigned.

  assign ('<transfer>-lid') to <lid>.
  assign ('<transfer>-line') to <line>.
  check <line> is assigned and <lid> is assigned.

* ----------- build requested
  ls_requested-fieldname = 'LID'.
  append ls_requested to lt_requested.
  ls_requested-fieldname = 'LINE'.
  append ls_requested to lt_requested.


* ---------- prepare report
  lv_report = me->ix_control-ix_datagroup.


* --------- get infos from sel screen
  perform load_sscr in program rsdbrunt
    tables    lt_scr
    using     lv_report
    changing  lv_subrc.

  call method me->map_filter_to_report_params
    exporting
      it_filter          = it_filter
      it_ddic            = me->ddic_transfer
      iv_flag_map_to_sap = 'X'
      it_selscreen       = lt_scr
    importing
      et_params          = lt_par
    exceptions
      failed             = 1
      others             = 2.
  if sy-subrc <> 0.
    raise failed.
  endif.

* ------------ call report in background
  call method z_cl_ia_ixa_generic_report=>start_report_in_background
    exporting
      iv_progname   = lv_report
      it_parameters = lt_par
    importing
      et_list       = lt_list
      et_html       = lt_html.

  if me->cust_mapping-parameter_1 eq 'hmtl'
    or me->cust_mapping-parameter_1 eq 'HTML'.

*----------------------------------------- TEXT MAPPING
* ----------- map list to lines
    loop at lt_html into ls_html.
      concatenate lv_html ls_html-line
        into lv_html.
    endloop.

* ----------- split
    split lv_html at '<br>' into table lt_line.

* ----------- build export
    lv_rows = 0.
    describe table lt_line lines ev_count.
    loop at lt_line into ls_line.

      lv_tabix = sy-tabix.

      if iv_start_row gt 0 and lv_tabix lt iv_start_row.
        continue.
      endif.

      if lv_rows ge iv_max_rows.
        exit.
      endif.

      <lid>   = lv_tabix.
      "concatenate ls_line-line '>' into <line>.
      <line> = ls_line-line.

      move-corresponding <transfer> to <data>.

      call method me->map_outbound_fields
        exporting
          iv_index           = lv_tabix
          iv_struc_name      = 'DEFAULT'
          iv_struc_record    = 0
          it_requested       = lt_requested
*        IV_IGNORE_LANGUAGE = ' '
        changing
          ct_fields          = et_result_values
          ct_keys            = et_result_keys
        exceptions
          failed             = 1
          others             = 2
              .
      if sy-subrc <> 0.
        lv_error = 'X'.
        exit.
      endif.

      add 1 to lv_rows.

      sy-tabix = lv_tabix.
    endloop.

    if lv_error ne 'X'.
      cv_processed = 'X'.
    endif.

  else.
* ------------------------------------- HTML Mapping
* ----------- map list to lines
    loop at lt_list into ls_list.
      concatenate lv_text ls_list-tdline
        into lv_text.
    endloop.

* ----------- split
    split lv_text at cl_abap_char_utilities=>newline into table lt_line.

* ----------- build export
    lv_rows = 0.
    describe table lt_line lines ev_count.
    loop at lt_line into ls_line.

      lv_tabix = sy-tabix.

      if iv_start_row gt 0 and lv_tabix lt iv_start_row.
        continue.
      endif.

      if lv_rows ge iv_max_rows.
        exit.
      endif.

      <lid>   = lv_tabix.
      <line>  = ls_line-line.

      move-corresponding <transfer> to <data>.

      call method me->map_outbound_fields
        exporting
          iv_index           = lv_tabix
          iv_struc_name      = 'DEFAULT'
          iv_struc_record    = 0
          it_requested       = lt_requested
*        IV_IGNORE_LANGUAGE = ' '
        changing
          ct_fields          = et_result_values
          ct_keys            = et_result_keys
        exceptions
          failed             = 1
          others             = 2
              .
      if sy-subrc <> 0.
        lv_error = 'X'.
        exit.
      endif.

      add 1 to lv_rows.

      sy-tabix = lv_tabix.
    endloop.

    if lv_error ne 'X'.
      cv_processed = 'X'.
    endif.
  endif.

endmethod.
method z_if_ia_ixa_intrexx_api~prepare_usage_after_creation.

* --------- local data
  data: ls_ddic type dfies.
  data: lv_lin type i.
  data: lv_report type progname.
*  DATA: lv_report TYPE raldb_repo.
  data: lt_selpar type table of rsparams.
  data: ls_selpar type rsparams.
  data: c_type(40) value 'ZIA_IXA_API_GR_REPORT_DDIC_TMP'.
  data: lt_ddic type ddfields.

* ---------- get fields from selection screen
  lv_report = me->ix_control-ix_datagroup.
  call method z_cl_ia_ixa_generic_report=>get_ddic_for_report
    exporting
      iv_report = lv_report
    importing
      et_ddic   = lt_ddic
    exceptions
      failed    = 1
      others    = 2.
  if sy-subrc <> 0.
    raise failed.
  endif.

*---------- get template
  call function 'DDIF_NAMETAB_GET'
    exporting
      tabname           = 'ZIA_IXA_API_GR_REPORT_DDIC_TMP'
*   ALL_TYPES         = ' '
*   LFIELDNAME        = ' '
*   GROUP_NAMES       = ' '
*   UCLEN             =
* IMPORTING
*   X030L_WA          =
*   DTELINFO_WA       =
*   TTYPINFO_WA       =
*   DDOBJTYPE         =
*   DFIES_WA          =
*   LINES_DESCR       =
   tables
*   X031L_TAB         =
      dfies_tab         = me->ddic_transfer
   exceptions
     not_found         = 1
     others            = 2
            .
  if sy-subrc <> 0.
    raise failed.
  endif.

* ---------- set lid to key field
  read table me->ddic_transfer into ls_ddic index 1.
  ls_ddic-keyflag = 'X'.
  modify me->ddic_transfer from ls_ddic index 1.

* ---------- get parameter dummy
  describe table me->ddic_transfer lines lv_lin.
  read table me->ddic_transfer into ls_ddic index lv_lin.
  if sy-subrc ne 0.
    raise failed.
  endif.

* ---------- delete dummy
  delete me->ddic_transfer where fieldname = ls_ddic-fieldname.

  loop at lt_ddic into ls_ddic.
    add 1 to ls_ddic-position.
    append ls_ddic to me->ddic_transfer.
  endloop.

* ------------ set the same to ddic
  me->ddic_data[] = me->ddic_transfer[].

  create data me->data type (c_type).
  create data me->transfer type (c_type).

endmethod.
method get_ddic_for_report.

* ------- local data
  data: lt_scr type table of rsscr.
  data: ls_scr type rsscr.
  data: lv_subrc type sysubrc.
  data: ls_ddic type dfies.

* --------- get infos from sel screen
  perform load_sscr in program rsdbrunt
    tables    lt_scr
    using     iv_report
    changing  lv_subrc.

  if lv_subrc ne 0.
    raise failed.
  endif.

* --------- mapping
  loop at lt_scr into ls_scr.

    clear ls_ddic.

    ls_ddic-tabname       = iv_report.
    ls_ddic-fieldname     = ls_scr-name.
    ls_ddic-position      = sy-tabix + 1.
    ls_ddic-leng          = ls_scr-length.
    ls_ddic-offset        = ls_scr-offset.
    ls_ddic-intlen        = ls_scr-length.
    ls_ddic-outputlen     = ls_scr-olength.
    ls_ddic-datatype      = ls_scr-dtyp.
    ls_ddic-inttype       = ls_scr-type.

    append ls_ddic to et_ddic.

  endloop.

endmethod.
method start_report_in_background.

* ------- local data
  data: lt_list type table of abaplist.
  data: lt_text type table of rtfline.
  data: ls_text type rtfline.
  data: lv_text type string.
  data: ls_par type rsparams.
  data: lv_url(132) type c.
  data: lt_html type table of w3html.
  field-symbols: <fs> type swww_t_merge_item.

* --------- start programm
  submit (iv_progname)
      with selection-table it_parameters
      exporting list to memory
      and return.

* -------- get list from memory
  call function 'LIST_FROM_MEMORY'
    tables
      listobject = lt_list
    exceptions
      not_found  = 1
      others     = 2.
  if sy-subrc <> 0.
    exit.
  endif.

* ------- convert list 0: Textedit
  call function 'LIST_TO_TXT'
* EXPORTING
*   LIST_INDEX               = -1
    tables
      listtxt                  = lt_text
      listobject               = lt_list
   exceptions
     empty_list               = 1
     list_index_invalid       = 2
     others                   = 3
            .
  if sy-subrc <> 0.
    exit.
  endif.

* ---------- convert list: html
  call function 'GET_REPORT_LISTS'
    exporting
      callback_form    = 'LIST_TO_HTML'
      callback_program = 'SAPLSURL'
    tables
      listobject       = lt_list
    exceptions
      empty_list       = 1
      others           = 2.
  if sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  endif.

  assign ('(SAPLSURL)G_MERGE_ITEM') to <fs>.
  if <fs> is assigned.
    lt_html[] = <fs>-html[].
  endif.

* ------------ fill export
  et_list[] = lt_text[].
  et_html[] = lt_html[].

endmethod.

2.6. Beispiele für Generic Report Integration

2.6.1. Einkaufsinformationen zum Material

*&---------------------------------------------------------------------*
*& Report  ZZ_DEMO_IXAPI_REPORT
*&
*&---------------------------------------------------------------------*
*& Der Report sucht über die Materialnummer, den Lieferanten + Preis.
*& Die Darstellung der Ergebnisse wird über Intrexx-html Klassen
*& beeinflußt.
*&---------------------------------------------------------------------*

report  zz_demo_ixapi_report no standard page heading line-size 256.


* ------- interface
parameters matnr type matnr.


start-of-selection.
* ------- local data + constants
  data: ls_mara like mara,
        lv_matnr type matnr,
        ls_eina like eina,
        ls_eine like eine.

  constants:
    c_h1_open type string
      value '<h1 style="margin:0px;" class="SCUP_Text_H1_normal">',
    c_h1_close type string
      value '</h1>',
    c_h2_open type string
      value '<h2 style="margin:0px;" class="SCUP_Text_H2_normal">',
    c_h2_close type string
      value '</h2>',
    c_skip type string
      value '<br>'.


* ------- convert to internal
  call function 'CONVERSION_EXIT_ALPHA_INPUT'
    exporting
      input  = matnr
    importing
      output = lv_matnr.


* ------ get data
  clear ls_mara.
* ------ select materialdata
  select single * from mara
    into corresponding fields of ls_mara
    where matnr = lv_matnr.
* ------ select vendor (recordinfo)
  select single * from eina
    into corresponding fields of ls_eina
    where matnr = ls_mara-matnr.
* ------ select priceinfo
  select single * from eine
    into corresponding fields of ls_eine
    where infnr = ls_eina-infnr.


* ------- check input
  if ls_mara is initial.
* ------ error message
    write: / c_h1_open, 'Fehler! Material nicht gefunden.', c_h1_close.
  else.
* ------ display data
    write: / c_h1_open, 'Materialdaten', c_h1_close.
    write: / c_skip.
    write: / c_h2_open, 'Materialnummer',c_h2_close.
    write:  ls_mara-matnr.
    write: / c_h2_open, 'Materialart',c_h2_close.
    write:  ls_mara-mtart.
    write: / c_skip.
    write: / c_h2_open, 'Lieferant',c_h2_close.
    write: ls_eina-lifnr.
    write: / c_h2_open, 'Preis',c_h2_close.
    write: ls_eine-netpr.
  endif.

3. Groovy-Skript

3.1 Musterskript: Konvertieren von SAP-Feldern

# SAP Datum
def l_sdfDatum = new java.text.SimpleDateFormat("yyyyMMdd")
l_sdfDatum.setTimeZone(g_session.user.timeZone)

String l_sap_date = l_sdfDatum.format(g_record["15853B4A180BB11A1B55AC1668AA065764C3A537"].value);

# SAP Zeit
def l_sdfZeit = new java.text.SimpleDateFormat("HHmmss")
l_sdfZeit.setTimeZone(g_session.user.timeZone)
String l_sap_time = l_sdfZeit.format(g_record["F11324BB5A892F1BC5DB68E0521E27BC02F7227E"].value);


# SAP ID mit führenden Nullen
String zeroes = '0000000000000000000000000000000000000000'
def l_strNumber = g_record["731ED21599DB3C90B2103202F6834F1FBD12A3B8"].value
if (l_strNumber.length() < 10)
{
	l_strNumber = zeroes.substring(0,10-l_strNumber.length()) + l_strNumber
}

3.2. Musterskript: SAP Kundenauftrag

/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"			// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- get fields from ix application
def l_auart = g_record["B2E580EB9A14390F897CD06FE33E536EB9D67229"].getValue() //datafield Auftragsart
def l_vkorg = g_record["8A3F82307B9D1173FE1B9BE4EF90EC27C6A88731"].getValue() //datafield Verkaufsorganisation
def l_vtweg = g_record["36C6B21F7C8C54F5761CDA117A2D3C799295F2BC"].getValue() //datafield Vertriebsweg
def l_spart = g_record["9C65868FAB1B8F7FF317954FE05A03A2F0A0FBA5"].getValue() //datafield Sparte
def l_kunnr = g_record["BF43DAD1B151C08D751B2221176C57F0CA588525"].getValue() //datafield Kundennummer
def l_bstnk = g_record["5B16C6BA37377218C685E23271D740736B2F8AEC"].getValue() //datafield Bestellnummer
def l_bstdt = g_record["406930D3BE19D5CE79E3E84DF438EC424E58CBF0"].getValue() //datafield Bestelldatum
def l_matnr = g_record["CBC25B6B716AC1F50DC5C2D40359AFA2BA365C6D"].getValue() //datafield Artikel Nr.
def l_qunty = g_record["55CE9B34ED4BC0C017DA43052C00F2A526BF5F1F"].getValue() //datafield Menge

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("BAPI_SALESORDER_CREATEFROMDAT2")
	if(l_function == null)
		return null

//==========> IMPORTING PARAMETERS
// ORDER_HEADER_IN (ABAP Structure: BAPISDHD1) - Auftragskopf
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DOC_TYPE", l_auart) //ABAP Type C: 4,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","SALES_ORG", l_vkorg) //ABAP Type C: 4,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DISTR_CHAN", l_vtweg) //ABAP Type C: 2,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","DIVISION", l_spart) //ABAP Type C: 2,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","PURCH_DATE", "20080820") // ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "ORDER_HEADER_IN","PURCH_NO_C", l_bstnk) //ABAP Type C: 35,0
	//==========> IMPORTING TABLES
	// Imported Table ORDER_ITEMS_IN (ABAP Structure: BAPISDITM) - Positionsdaten
	def l_posnr = "1"
	l_table = g_sap.getTable(l_function,"ORDER_ITEMS_IN")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "ITM_NUMBER", l_posnr) // ABAP Type N: 6,0
		g_sap.setTableField(l_table, "MATERIAL", l_matnr) // ABAP Type C: 18,0
	} // Table ORDER_ITEMS_IN end
	// Imported Table ORDER_SCHEDULES_IN (ABAP Structure: BAPISCHDL) - Einteilungsdaten
	l_table = g_sap.getTable(l_function,"ORDER_SCHEDULES_IN")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "ITM_NUMBER", l_posnr) // ABAP Type N: 6,0
		g_sap.setTableField(l_table, "REQ_QTY", l_qunty) // ABAP Type P: 7,3
	} // Table ORDER_SCHEDULES_IN end
	// Imported Table ORDER_PARTNERS (ABAP Structure: BAPIPARNR) - Belegpartner
	l_table = g_sap.getTable(l_function,"ORDER_PARTNERS")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "PARTN_ROLE", "AG") // ABAP Type C: 2,0
		g_sap.setTableField(l_table, "PARTN_NUMB", l_kunnr) // ABAP Type C: 10,0
	} // Table ORDER_PARTNERS end
	//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
	
		// SALESDOCUMENT (ABAP Type: C 10,0) - Nummer des erzeugten Beleges
		def l_vbeln = g_sap.getExpPar(l_function,"SALESDOCUMENT")
		if(l_vbeln.equals("")){
			g_sap.BapiRollback(l_client)
			return null
		}

		// save vbeln to datagroup
		l_conn = g_dbConnections.systemConnection
		l_lid = g_record["66B1F38BA125C4C22444D27AC9108B91A208EE16"].getValue() //	datafield (PK) (S) ID
		l_stmtOrderUpdate = g_dbQuery.prepare(l_conn, "UPDATE XTABLE9EB02DDB SET SAP_VBELN = ? WHERE LID = ?")
		l_stmtOrderUpdate.setString(1, l_vbeln)
		l_stmtOrderUpdate.setInt(2, l_lid)
		l_stmtOrderUpdate.executeUpdate()
		// final commit
		g_sap.BapiCommit(l_client, false) // set to true if commit should wait
	}else{
		g_sap.BapiRollback(l_client)
	}
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

3.3 Musterskript: Warenbewegung, Umlagerung

Das folgende Groovy Skript ist als Vorlage zu verwenden und enthält Konstanten aus einem Kundenszenario.
/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"			// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("BAPI_GOODSMVT_CREATE")
	if(l_function == null)
		return null

//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection("system") // valid: <system|mixed|user>
	if(l_client == null){
		g_log.error("no connection to sap")
		return null
	}
	l_function = g_sap.getSapFunction("BAPI_GOODSMVT_CREATE")
	if(l_function == null){
		g_log.error("function not available")
		return null
	}
//==========> IMPORTING PARAMETERS
// GOODSMVT_CODE (ABAP Structure: BAPI2017_GM_CODE) - Zuordnung Code zu Transaktion für Warenbewegung
	g_sap.setImpStrucParField(l_function, "GOODSMVT_CODE","GM_CODE", "05") // ABAP TypeC: 2,0
// GOODSMVT_HEADER (ABAP Structure: BAPI2017_GM_HEAD_01) - Kopfdaten des Materialbelegs
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","PSTNG_DATE", "20080807") // ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","DOC_DATE", "20080807") //ABAP Type D: 8,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","HEADER_TXT", "BAPICRR") //ABAP Type C: 25,0
	g_sap.setImpStrucParField(l_function, "GOODSMVT_HEADER","VER_GR_GI_SLIP", "1") //ABAP Type C: 1,0
//==========> IMPORTING TABLES
// Imported Table GOODSMVT_ITEM (ABAP Structure: BAPI2017_GM_ITEM_CREATE) - Materialbelegpositionen
	l_table = g_sap.getTable(l_function,"GOODSMVT_ITEM")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "MATERIAL", "BM00009") // ABAP Type C: 18,0
		g_sap.setTableField(l_table, "PLANT", "0001") // ABAP Type C: 4,0
		g_sap.setTableField(l_table, "STGE_LOC", "0001") // ABAP Type C: 4,0
		g_sap.setTableField(l_table, "MOVE_TYPE", "501") // ABAP Type C: 3,0
		g_sap.setTableField(l_table, "ENTRY_QNT", "1") // ABAP Type P: 7,3
		g_sap.setTableField(l_table,"ENTRY_UOM", "ST") // ABAP Type C: 3,0
		g_sap.setTableField(l_table,"ENTRY_UOM_ISO", "PCE") // ABAP Type C: 3,0
		g_sap.setTableField(l_table,"ITEM_TEXT", "CRRBAPI") // ABAP Type C: 50,0
		g_sap.setTableField(l_table,"LINE_ID", "000001") // ABAP Type N: 6,0
	} // Table GOODSMVT_ITEM end
// Imported Table GOODSMVT_SERIALNUMBER (ABAP Structure: BAPI2017_GM_SERIALNUMBER) -Serialnummer
	l_table = g_sap.getTable(l_function,"GOODSMVT_SERIALNUMBER")
	for(int i = 0; i < 1; i++){
		l_table.appendRow()
		g_sap.setTableField(l_table, "MATDOC_ITM", "0001") // ABAP Type N: 4,0
		g_sap.setTableField(l_table, "SERIALNO", "100006000000000501") // ABAP TypeC: 18,0
	} // Table GOODSMVT_SERIALNUMBER end
//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
		// ----> INSERT FURTHER CHECKS HERE
//==========> EXPORTED PARAMETERS
		// GOODSMVT_HEADRET (ABAP Structure: BAPI2017_GM_HEAD_RET) -Materialbelegnummer/Materialbelegjahr
		/*
		l_value = g_sap.getExpStrucParField(l_function, "GOODSMVT_HEADRET","MAT_DOC") // ABAP Type C: 10,0
		l_value = g_sap.getExpStrucParField(l_function, "GOODSMVT_HEADRET","DOC_YEAR") //ABAP Type N: 4,0
		// MATDOCUMENTYEAR (ABAP Type: N 4,0) - Materialbelegjahr
		l_value = g_sap.getExpPar(l_function,"MATDOCUMENTYEAR")
		*/
// Exported Table RETURN (ABAP Structure: BAPIRET2) - Rückmeldungen
		l_table = g_sap.getTable(l_function,"RETURN")
		for(int i = 0; i < l_table.getNumRows(); i++){
			l_value = g_sap.getTableField(l_table, "TYPE") // ABAP Type C: 1,0
			l_value = g_sap.getTableField(l_table, "ID") // ABAP Type C: 20,0
			l_value = g_sap.getTableField(l_table, "NUMBER") // ABAP Type N: 3,0
			l_value = g_sap.getTableField(l_table, "MESSAGE") // ABAP Type C: 220,0
			g_log.info("SAPRETURN: " + l_value)
			l_value = g_sap.getTableField(l_table, "LOG_NO") // ABAP Type C: 20,0
			l_value = g_sap.getTableField(l_table, "LOG_MSG_NO") // ABAP Type N: 6,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V1") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V2") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V3") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "MESSAGE_V4") // ABAP Type C: 50,0
			l_value = g_sap.getTableField(l_table, "PARAMETER") // ABAP Type C: 32,0
			l_value = g_sap.getTableField(l_table, "ROW") // ABAP Type I: 4,0
			l_value = g_sap.getTableField(l_table, "FIELD") // ABAP Type C: 30,0
			l_value = g_sap.getTableField(l_table, "SYSTEM") // ABAP Type C: 10,0
			l_table.nextRow()
		} // Table RETURN end
// MATERIALDOCUMENT (ABAP Type: C 10,0) - Nummer des Materialbelegs
		l_value = g_sap.getExpPar(l_function,"MATERIALDOCUMENT")
		g_log.info("Materialbeleg: " + l_value
		// ...
		g_sap.BapiCommit(l_client, false) // set to true if commit should wait
		// ----> INSERT YOUR CODE HERE
		// ...
	}else{
		g_log.error("error executing sap function")
		g_sap.BapiRollback(l_client)
	}
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

3.4. Musterskript: Verwendung der simpleRFC-API in Velocity

Die Beschreibung dieses Skripts finden Sie hier.
## ============================================================
## Velocity Integration for SAP Business Suite Connectorto SAP
## Use this coding with Intrexx >=7.0 and and JCo >=3.0.10
## minimum requirement is a valid business adapter for SAP module "View & Write"  
## 
## 
##  Some hints for using API:
##  Simple RFC with Parameter INPUT and RESULT:		$GSAP.simpleRfcTrigger(String p_instance, String p_loginmode, String p_function, String p_parameter)
## ============================================================

## define variables
#set( $strInstance  = "saperp" )
#set( $strLoginType = "system" )
#set( $strFunction  = "/IATL/MESSE_IPHONE_GET_STOCK" )
#set( $bTrace		= true )
#set( $bCommit		= false )
#set( $strError		= "" )
#set( $strValue		= "" )
#set( $strLogCon	= "No connection to SAP" )
#set( $strLogFun	= "Unable to get access to SAP function module" )
#set( $strLogExec	= "Errors occured while calling SAP" )
#set( $bStateful    = true)

## ============= connect to SAP
#set( $bOkConnect   = $GSAP.simpleRfcConnect($strInstance,$strLoginType) )
#if(  $bOkConnect ==  true)
	#if( $bStateful == true ) $GSAP.simpleRfcSetContextBegin() #end
## ============= get function
	#set( $bOkFunction = $GSAP.simpleRfcFunctionLoad( $strFunction ) )
	#if(  $bOkFunction == true )

## ============= fill parameter	
	<br>Execute: $GSAP.simpleRfcFunctionExecute(false)

	## loop export table
	<br>Set Focus Table: $GSAP.simpleRfcSetFocusTable("ET_STOCK")
	<br>Records found: $GSAP.simpleRfcTableGetCount()
	#set($strOutput = "<table>")
	#foreach($line in $GSAP.simpleRfcTableGetEntries())
		<br> List Item: $line
		Set Table Line: $GSAP.simpleRfcTableSetLine($line)
		#if($GSAP.simpleRfcSetFocusTableField("MATNR"))
			#set($strMatnr = $GSAP.simpleRfcGetParameterValue())
		#end
		#if($GSAP.simpleRfcSetFocusTableField("MAKTX"))
			#set($strText = $GSAP.simpleRfcGetParameterValue())
		#end
		#if($GSAP.simpleRfcSetFocusTableField("COUNT"))
			#set($strCount = $GSAP.simpleRfcGetParameterValue())
		#end
		#set($strOutput = $strOutput + "<tr><td>" + $strMatnr + "</td><td>" + $strText + "</td><td>" + $strCount + "</td></tr>")
	#end
	#set($strOutput = $strOutput + "</table>")

## ============= close connection
  #if( $bStateful == true ) $GSAP.simpleRfcSetContextEnd() #end	
	#set( $bRC = $GSAP.simpleRfcClose() )
#else
	#set( $strError = $strLogCon )
#end

## ============= Output
#if( $strError == "" )
## -- success
#else
## -- error
	#if( $bTrace )
		$strError
	#end
#end

4. Remote Services ABAP Programme

4.1. Replikation von SAP-Daten

REPORT  /iatl/udc_replicate NO STANDARD PAGE HEADING LINE-SIZE 1023.

* link to external database
PARAMETERS: p_inst LIKE /iatl/c_udcins-udc_instance OBLIGATORY.
PARAMETERS: p_obj  TYPE /iatl/udc_object_id.
SELECTION-SCREEN: SKIP.
* fields in external database
PARAMETERS: p_extkey  TYPE /iatl/udc_fieldname_key DEFAULT 'LID' OBLIGATORY.
PARAMETERS: p_erpkey  TYPE /iatl/udc_fieldname_key DEFAULT 'ERPID' OBLIGATORY.
PARAMETERS: p_erptxt  TYPE /iatl/udc_fieldname_key DEFAULT 'ERPTEXT' OBLIGATORY.
SELECTION-SCREEN: SKIP.
* fields in sap
PARAMETERS: p_saptab LIKE dd03l-tabname DEFAULT 'BUT000' OBLIGATORY.
PARAMETERS: p_sapkey LIKE dd03l-fieldname DEFAULT 'PARTNER' OBLIGATORY.
PARAMETERS: p_saptxt LIKE dd03l-fieldname DEFAULT 'NAME_ORG1' OBLIGATORY.
SELECTION-SCREEN: SKIP.
* where clause
PARAMETERS: p_where TYPE char255 DEFAULT 'type = 2'.

* ================= Include UDC Macros
INCLUDE /iatl/udc_include_report. "some tools for UDC Reports


* ================= Reaction for F4 requests
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_extkey.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_EXTKEY'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_extkey
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_erpkey.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_ERPKEY'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_erpkey
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_erptxt.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_metainfo
    EXPORTING
      iv_instance      = p_inst
      iv_object        = p_obj
      iv_dynpro_field  = 'P_ERPTXT'
      iv_display_popup = 'X'
    CHANGING
      cv_fieldname     = p_erptxt
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_obj.

  CALL METHOD /iatl/cl_udc_handler=>util_popup_f4_table
    EXPORTING
      iv_instance      = p_inst
      iv_dynpro_field  = 'P_OBJ'
      iv_display_popup = 'X'
    CHANGING
      cv_object_id     = p_obj
    EXCEPTIONS
      technical_error  = 1
      cancelled        = 2
      OTHERS           = 3.


* ================= START OF PROGRAM
START-OF-SELECTION.

* ------------ local data
  DATA: lc_dataobject TYPE /iatl/udc_object_id VALUE 'public.xia_replica_demo'.
  DATA: lt_return TYPE TABLE OF bapiret2.
  DATA: lo_connector TYPE REF TO /iatl/cl_udc_handler.
  DATA: lv_count_selected TYPE i.
  DATA: lv_count_insert TYPE i.
  DATA: lv_count_update TYPE i.
  DATA: lv_count_error TYPE i.
  DATA: ls_config	TYPE /iatl/udc_request_config.
  DATA: lt_requested   TYPE /iatl/udc_requested_fields_t.
  DATA: lt_existing TYPE /iatl/udc_result_t.
  DATA: ls_existing LIKE LINE OF lt_existing.
  DATA: lv_count TYPE i.
  DATA: lt_filter TYPE /iatl/udc_filter_t.
  DATA: ls_filter LIKE LINE OF lt_filter.
  DATA: lt_values TYPE /iatl/udc_result_t.
  DATA: ls_values LIKE LINE OF lt_values.
  DATA: lv_fname(80).
  DATA: lv_status(80).

  DATA: lr_erp_t TYPE REF TO data.
  DATA: lr_erp_s TYPE REF TO data.

  FIELD-SYMBOLS: <erpid> TYPE data.
  FIELD-SYMBOLS: <erptxt> TYPE data.
  FIELD-SYMBOLS: <lt_erp> TYPE table.
  FIELD-SYMBOLS: <ls_erp> TYPE data.



* =============================== create udc handler : Connect
  CALL METHOD /iatl/cl_udc_handler=>object_factory_by_instance
    EXPORTING
      iv_instance       = p_inst
      iv_connect        = 'X'
*    IV_CLASS          =
    IMPORTING
      eo_udc_connection = lo_connector
    EXCEPTIONS
      not_customized    = 1
      wrong_customizing = 2
      connection_error  = 3
      OTHERS            = 4
          .
  IF sy-subrc <> 0 OR lo_connector IS INITIAL.
    WRITE: / 'Fehler'.
    EXIT.
  ENDIF.

* =============================== get existing data from external table
  APPEND p_extkey TO lt_requested.
  APPEND p_erpkey TO lt_requested.


  CALL METHOD lo_connector->api_get_data
    EXPORTING
      i_ds_id             = p_obj
      is_config           = ls_config
      it_requested_fields = lt_requested
    IMPORTING
      e_count             = lv_count
      et_results          = lt_existing
    CHANGING
      ct_return           = lt_return
    EXCEPTIONS
      connection_error    = 1
      errors_occured      = 2
      not_connected       = 3
      OTHERS              = 4.
  IF sy-subrc <> 0.
    WRITE: / 'Fehler get_data.'.
  ENDIF.


* =============================== create mapping between external and internal record
  DATA: BEGIN OF ls_map,
          id_portal TYPE i,
          id_sap TYPE string,
        END OF ls_map.
  DATA: lt_map LIKE TABLE OF ls_map.
  DATA: lv_tabix TYPE sytabix.
  DATA: lv_max_lid TYPE i.

  LOOP AT lt_existing INTO ls_existing.

    AT NEW record.
      IF NOT ls_map IS INITIAL.
        APPEND ls_map TO lt_map.
        CLEAR ls_map.
      ENDIF.
    ENDAT.

    IF ls_existing-fieldname = p_extkey.
      ls_map-id_portal = ls_existing-value.
      IF lv_max_lid LE ls_map-id_portal.
        lv_max_lid = ls_map-id_portal.
      ENDIF.
    ENDIF.
    IF ls_existing-fieldname = p_erpkey.
      ls_map-id_sap = ls_existing-value.
    ENDIF.

  ENDLOOP.
  IF NOT ls_map IS INITIAL.
    APPEND ls_map TO lt_map.
  ENDIF.


* =============================== select sap data
  CREATE DATA lr_erp_t TYPE TABLE OF (p_saptab).
  CREATE DATA lr_erp_s TYPE (p_saptab).

  ASSIGN lr_erp_t->* TO <lt_erp>.
  ASSIGN lr_erp_s->* TO <ls_erp>.

  CONCATENATE '<ls_erp>-' p_sapkey INTO lv_fname.
  ASSIGN (lv_fname) TO <erpid>.

  CONCATENATE '<ls_erp>-' p_saptxt INTO lv_fname.
  ASSIGN (lv_fname) TO <erptxt>.

  SELECT * FROM (p_saptab)
    INTO TABLE <lt_erp>
    WHERE (p_where).


* =============================== make current time
* 2008-08-08 07:20:24.

  DATA: lv_date(20).
  DATA: lv_time(20).
  DATA: lv_current(20).

  CONCATENATE sy-datum(4)
              '-'
              sy-datum+4(2)
              '-'
              sy-datum+6(2)
              INTO lv_date.

  CONCATENATE sy-uzeit(2)
              ':'
              sy-uzeit+2(2)
              ':'
              sy-uzeit+4(2)
              INTO lv_time.

  CONCATENATE lv_date lv_time INTO lv_current SEPARATED BY ' '.



* =============================== loop at sap data : transfer to portal
  LOOP AT <lt_erp> INTO <ls_erp>.
    lv_tabix = sy-tabix.

* ----- sapgui status
    lv_status = lv_tabix.
    CONDENSE lv_status.
    CONCATENATE 'Processing...' lv_status INTO lv_status SEPARATED BY ' '.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = lv_status.

* ----- prepare values insert/update
    REFRESH lt_values.

    ls_values-record = 1.

    ls_values-fieldname = 'LUSERID'.  ls_values-value = '1'.                 APPEND ls_values TO lt_values.
    ls_values-fieldname = 'DTEDIT'.   ls_values-value = lv_current.          APPEND ls_values TO lt_values.

    ls_values-fieldname = p_erptxt.   ls_values-value = <erptxt>.            APPEND ls_values TO lt_values.
    ls_values-fieldname = p_erpkey.   ls_values-value = <erpid>.             APPEND ls_values TO lt_values.


* ----  get existing id
    READ TABLE lt_map INTO ls_map
      WITH KEY id_sap = <erpid>.
    IF sy-subrc EQ 0.
* -----------------> exists
*     build where clause
      REFRESH lt_filter.
      ls_filter-selpos        = 1.
      ls_filter-combine       = 'AND'.
      ls_filter-lparenthesis  = 0.
      ls_filter-fieldname     = p_extkey.
      ls_filter-operand       = 'EQ'.
      ls_filter-value_low     = ls_map-id_portal.
      ls_filter-value_high    = space.
      ls_filter-rparenthesis  = 0.
      CONDENSE ls_filter-value_low.
      APPEND ls_filter TO lt_filter.

*     update
      DATA: lv_sql TYPE /iatl/udc_sql.
      CALL METHOD lo_connector->api_update
        EXPORTING
          i_ds_id          = p_obj
          is_config        = ls_config
          it_filters       = lt_filter
          it_values        = lt_values
        IMPORTING
          e_count          = lv_count
          e_sql            = lv_sql
        CHANGING
          ct_return        = lt_return
        EXCEPTIONS
          connection_error = 1
          errors_occured   = 2
          not_connected    = 3
          OTHERS           = 4.
      IF sy-subrc <> 0.
        WRITE: / 'Error Update : ', <erpid>.
        ADD 1 TO lv_count_error.
      ELSE.
        WRITE: / 'Success Update: ', <erpid>.
        ADD 1 TO lv_count_update.
      ENDIF.

    ELSE.
* -----------------> new
*     prepare additional insert fields
      ls_values-fieldname = 'LUSERIDINSERT'. ls_values-value = 1.          APPEND ls_values TO lt_values.
      ls_values-fieldname = 'DTINSERT'.      ls_values-value = lv_current. APPEND ls_values TO lt_values.

      ADD 1 TO lv_max_lid.
      ls_values-fieldname = p_extkey.        ls_values-value = lv_max_lid. APPEND ls_values TO lt_values.

*     insert
      CALL METHOD lo_connector->api_insert
        EXPORTING
          i_ds_id          = p_obj
          is_config        = ls_config
          it_values        = lt_values
        IMPORTING
          e_count          = lv_count
        CHANGING
          ct_return        = lt_return
        EXCEPTIONS
          connection_error = 1
          errors_occured   = 2
          not_connected    = 3
          OTHERS           = 4.

      IF sy-subrc <> 0.
        WRITE: / 'Error Insert : ', <erpid>.
        ADD 1 TO lv_count_error.
      ELSE.
        WRITE: / 'Success Insert: ', <erpid>.
        ADD 1 TO lv_count_insert.
      ENDIF.

    ENDIF.

    sy-tabix = lv_tabix.
  ENDLOOP.


* ================= final status
  ULINE.
  WRITE: / 'SAP Table               : ', p_saptab.
  WRITE: / 'External DB Instance    : ', p_inst.
  WRITE: / 'External Table          : ', p_obj.
  WRITE: / 'Where Clause            : ', p_where.
  WRITE: / 'Selected SAP record     : ', lv_count_selected.
  WRITE: / 'New external records    : ', lv_count_insert.
  WRITE: / 'Updated external records: ', lv_count_update.
  WRITE: / 'Record with errors      : ', lv_count_error.

4.2. Extern nach SAP: Groovy-Skript für Replikations-API

/****************************************************************************************************
 * Groovy Integration for SAP Business Suite Connector
 * Use this coding with Intrexx >= 7.0 and JCo >= 3.0.10
 * minimum requirement is a valid business adapter for SAP module "View & Write"
 * 
 * 
 *  Some hints for using API:
 *  Convert datetime to SAP date:				g_sap.convertToSapDate(Date p_datetime)
 *  Convert datetime to SAP time:				g_sap.convertToSapTime(Date p_datetime)
 *  Convert SAP date and time time to String:	g_sap.convertSapToIXDateTime(String p_sapdate, String p_saptime)
 *  Convert SAP date and time time to java.util.Date:	convertSapToTimestamp(String p_sapdate, String p_saptime, String p_timezone)
 *  Convert string to numeric:					g_sap.convertToLeadingZero(String p_in, int p_size)
 *  Convert SAP numeric to string:				g_sap.convertFromLeadingZero(String p_in)
 ****************************************************************************************************/

// ---------- imported packages
import net.initall.ixapi.groovy.*

// ---------- definitions
def l_datasource   = "saperp"				// name of the SAP datasource within Intrexx Integration
def l_logintype    = "system"			// login mode to SAP: valid = ||
def l_trace        = true				// trace on/off
def l_stateful     = false    			// use stateful connection (true|false)
def l_logprefix    = "SAP Access: " 	// prefix for log messages
def l_text_noapi   = "Groovy SAP API not available."
def l_text_nocon   = "Connection to SAP is not available."
def l_text_nofunc  = "SAP function module not available."
def l_text_error   = "SAP function module called with errors."
def l_text_except  = "SAP Error: "
def l_saperror     = true      			// helper var for error handling; default error
def l_rows_to_add  = 0         			// number of rows for Table Parameters; set at the appropriate imports

// ---------- variables
def g_sap          = null      // Groovy SAP API Instance
def l_client       = null      // connection to an SAP system
def l_function     = null      // proxy to an SAP function module
def l_funcmod      = null      // name of the function module
def l_table        = null      // sap table object
def l_value        = ""        // dummy var for value mapping

// ---------- Connect to sap and execute
try {
// initialize Groovy SAP API
	if(l_trace) g_log.info("Get access to SAP API")

	g_sap = IxSapGroovyAPI.getInstance()
	
	if(g_sap == null) throw new Exception(l_text_noapi)
//==========> INITIALIZE SAP CONNECTION
// get sap connection
	l_client = g_sap.getSapConnection(l_datasource, l_logintype)
	if(l_client == null)
		return null
	  
	l_function = g_sap.getSapFunction("/IATL/UDC_REPL_API_INB_TRIGGER")
	if(l_function == null)
		return null

//===========> get ix values
	def l_lid = g_record["1C914F1AB6E1A38661FDC0BA93789BD1A87C175A"].value // datafield (PK) (S) ID
	def l_str_lid = g_record["1C914F1AB6E1A38661FDC0BA93789BD1A87C175A"].value // datafield (PK) (S) ID
	def l_name = g_record["25B3880A8B1679C413C6BC3504957E1151401F58"].value // datafield Firma
	def l_kunnr = g_record["072D6FF8B9E0BB5AA0A1BEA8A84ABC55E58C0D48"].value // datafield Kundennummer
	def l_ort = g_record["E741B7475651E57DC649D0C66BD9D4AB8D58157D"].value // datafield Ort
	def l_plz = g_record["ECFC786378FD342C602B420C500BE96EA64D2839"].value // datafield PLZ
	def l_strasse = g_record["B9A1D5F80F511D550E8335715F7F4AE94CE21C10"].value // datafield Straße

//==========> IMPORTING PARAMETERS
	// IV_EXTERN_ID (ABAP Type: C 70,0) - UDC: Externer Schlüssel
	g_sap.setImpPar(l_function,"IV_EXTERN_ID", l_str_lid)
	// IV_FLAG_MERGE_MODE (ABAP Type: C 1,0) - Daten mischen
	g_sap.setImpPar(l_function,"IV_FLAG_MERGE_MODE"," ")
	// IV_FLAG_NO_EXCEPTION (ABAP Type: C 1,0) - keine Exception Fehler im Flag/Tabelle
	g_sap.setImpPar(l_function,"IV_FLAG_NO_EXCEPTION","X")
	// IV_FLAG_ONLY_CHECK (ABAP Type: C 1,0) - Nur prüfen, kein schreiben
	g_sap.setImpPar(l_function,"IV_FLAG_ONLY_CHECK"," ")
	// IV_FLAG_PROTOCOL (ABAP Type: C 1,0) - UDC: Flag Protokoll anzeigen
	g_sap.setImpPar(l_function,"IV_FLAG_PROTOCOL"," ")
	// IV_FLAG_READ_EXTERN (ABAP Type: C 1,0) - Daten nachlesen
	g_sap.setImpPar(l_function,"IV_FLAG_READ_EXTERN"," ")
	// IV_FLAG_SAVE_TS (ABAP Type: C 1,0) - Zeitstempel für Delta speichern
	g_sap.setImpPar(l_function,"IV_FLAG_SAVE_TS"," ")
	// IV_REPL_OBJECT (ABAP Type: C 30,0) - UDC: Replikationsobjekt
	g_sap.setImpPar(l_function,"IV_REPL_OBJECT","/IATL/UDCIXCRM_KNA1")
	// IV_SAP_ID (ABAP Type: C 70,0) - UDC: Interner Schlüssel
	g_sap.setImpPar(l_function,"IV_SAP_ID",l_kunnr)
//==========> IMPORTING TABLES

	// Imported Table IT_DATA (ABAP Structure: /IATL/UDC_RESULT) - ESB: Ergebnisse einer Selektion (Raw Information)
	l_table = g_sap.getTable(l_function,"IT_DATA") 
	// STR_COMPANY
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_COMPANY") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_name) // ABAP Type C: 70,0
	// STR_ORT
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_ORT") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_ort) // ABAP Type C: 70,0
	// STR_PLZ
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_PLZ") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_plz) // ABAP Type C: 70,0
	// STR_STRASSE
	l_table.appendRow()
	g_sap.setTableField(l_table, "RECORD", "1") // ABAP Type I: 4,0
	g_sap.setTableField(l_table, "FIELDNAME", "STR_STRASSE") // ABAP Type C: 40,0
	g_sap.setTableField(l_table, "VALUE", l_strasse) // ABAP Type C: 70,0
//==========> EXECUTE SAP FUNCTION
	if(g_sap.executeSapFunction(l_client, l_function)){
//==========> EXPORTED PARAMETERS
		// EV_ERROR (ABAP Type: C 1,0) - Feld zum Ankreuzen
		def l_error = g_sap.getExpPar(l_function,"EV_ERROR")
		g_log.info("SAP Function executed. Error = " + l_error)
		// Exported Table ET_MESSAGES (ABAP Structure: /IATL/UDC_MESSAGES_T) - UDC: Nachrichten
		def l_message = ""
		l_table = g_sap.getTable(l_function,"ET_MESSAGES")
		for(int i = 0 i < l_table.getNumRows() i++){
			def l_type = g_sap.getTableField(l_table, "TYPE") // ABAP Type C: 1,0
			def l_msg = g_sap.getTableField(l_table, "MESSAGE") // ABAP Type C: 220,0
			if(l_type.equals("E") || l_type.equals("A") || l_type.equals("X")){
				if(l_message.equals("")){
					l_message = l_msg
				}else{
					l_message = l_message + "\n" + l_msg
				}
			}
			l_table.nextRow()
		} // Table ET_MESSAGES end
	
		// check error without error message
		if(l_error.equals("X") && l_message.equals("")){
			l_message = "Es ist ein unbekannter Fehler aufgetreten."
		}
		g_log.info("Message created = " + l_message)
		// save info to db
		l_conn = g_dbConnections.systemConnection
		def l_stmtOrderUpdate = g_dbQuery.prepare(l_conn, "UPDATE XCRM_CUSTOMER SET ERROR_MESSAGE = ? WHERE LID = ?")
		l_stmtOrderUpdate.setString(1, l_message)
		l_stmtOrderUpdate.setInt(2, l_lid)
		l_stmtOrderUpdate.executeUpdate()
		if(l_error.equals("X")){
			g_sap.destroy()
			g_log.error("Fehler Update SAP Kunde")
			return false
		}
	}else{
		g_sap.destroy()
		return true
	}
//==========> FINISH SAP CONNECTION
}
catch(e) {
  g_log.error(l_logprefix + l_text_except + " - " + e.getMessage())
}
finally{
  if(l_trace) g_log.info(l_logprefix + "Destroy SAP connection")

  // End Stateful (if configured)
  if(l_stateful && g_sap != null && l_client != null) g_sap.setContextEnd(l_client)

  // Destroy SAP API
  if(g_sap != null) g_sap.destroy()
}

4.3. Extern nach SAP: Batchinput für Debitor ändern

FUNCTION /IATL/UDC_IXCRM_BTCI_XD02.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(CTU) LIKE  APQI-PUTACTIVE DEFAULT 'X'
*"     VALUE(MODE) LIKE  APQI-PUTACTIVE DEFAULT 'N'
*"     VALUE(UPDATE) LIKE  APQI-PUTACTIVE DEFAULT 'L'
*"     VALUE(GROUP) LIKE  APQI-GROUPID OPTIONAL
*"     VALUE(USER) LIKE  APQI-USERID OPTIONAL
*"     VALUE(KEEP) LIKE  APQI-QERASE OPTIONAL
*"     VALUE(HOLDDATE) LIKE  APQI-STARTDATE OPTIONAL
*"     VALUE(NODATA) LIKE  APQI-PUTACTIVE DEFAULT '/'
*"     VALUE(IV_KUNNR) LIKE  BDCDATA-FVAL
*"     VALUE(D0110_002) LIKE  BDCDATA-FVAL DEFAULT 'X'
*"     VALUE(USE_ZAV_003) LIKE  BDCDATA-FVAL DEFAULT 'X'
*"     VALUE(IV_NAME1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_NAME2) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_SORT1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_STREET) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_HOUSE_NUM1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_POST_CODE1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_CITY1) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_COUNTRY) LIKE  BDCDATA-FVAL DEFAULT '/'
*"     VALUE(IV_LANGU) LIKE  BDCDATA-FVAL DEFAULT '/'
*"  EXPORTING
*"     VALUE(SUBRC) LIKE  SYST-SUBRC
*"  TABLES
*"      MESSTAB STRUCTURE  BDCMSGCOLL OPTIONAL
*"----------------------------------------------------------------------

  subrc = 0.

  PERFORM bdc_nodata      USING nodata.

  PERFORM open_group      USING group user keep holddate ctu.

  PERFORM bdc_dynpro      USING 'SAPMF02D' '0101'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'USE_ZAV'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '/00'.
  PERFORM bdc_field       USING 'RF02D-KUNNR'
                                iv_kunnr.
  PERFORM bdc_field       USING 'RF02D-D0110'
                                d0110_002.
  PERFORM bdc_field       USING 'USE_ZAV'
                                use_zav_003.
  PERFORM bdc_dynpro      USING 'SAPMF02D' '0111'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '/00'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'ADDR1_DATA-CITY1'.
  PERFORM bdc_field       USING 'ADDR1_DATA-NAME1'
                                iv_name1.
  PERFORM bdc_field       USING 'ADDR1_DATA-NAME2'
                                iv_name2.
  PERFORM bdc_field       USING 'ADDR1_DATA-SORT1'
                                iv_sort1.
  PERFORM bdc_field       USING 'ADDR1_DATA-STREET'
                                iv_street.
  PERFORM bdc_field       USING 'ADDR1_DATA-HOUSE_NUM1'
                                iv_house_num1.
  PERFORM bdc_field       USING 'ADDR1_DATA-POST_CODE1'
                                iv_post_code1.
  PERFORM bdc_field       USING 'ADDR1_DATA-CITY1'
                                iv_city1.
  PERFORM bdc_field       USING 'ADDR1_DATA-COUNTRY'
                                iv_country.
  PERFORM bdc_field       USING 'ADDR1_DATA-LANGU'
                                iv_langu.
  PERFORM bdc_dynpro      USING 'SAPMF02D' '0900'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'KNA1-J_3GETYP'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=UPDA'.
  PERFORM bdc_transaction TABLES messtab
  USING                         'XD02'
                                ctu
                                mode
                                update.
  IF sy-subrc <> 0.
    subrc = sy-subrc.
    EXIT.
  ENDIF.

  PERFORM close_group USING     ctu.

ENDFUNCTION.
INCLUDE bdcrecxy .

4.4. Extern nach SAP: Methode SAP_RECORD_UPDATE

method sap_record_update.

* ----- local data
  data: ls_kna1 type kna1.
  data: lt_messtab type table of bdcmsgcoll.
  data: lv_subrc type sysubrc.

  data: lv_ort      type bdc_fval.
  data: lv_plz      type bdc_fval.
  data: lv_name     type bdc_fval.
  data: lv_strasse  type bdc_fval.
  data: lv_hnr      type bdc_fval.
  data: lv_kunnr    type bdc_fval.

  data: begin of ls_split,
          value(40),
        end of ls_split.
  data: lt_split like table of ls_split.
  data: lv_lin type i.



* ----- no new record
  if iv_sap_id eq space.
    raise failed.
  endif.
* ----- move data
  move-corresponding cs_data to ls_kna1.
  lv_name = ls_kna1-name1.
  lv_ort  = ls_kna1-ort01.
  lv_plz  = ls_kna1-pstlz.
  lv_kunnr = ls_kna1-kunnr.

* ----- split strasse --> strasse - hnr
* set to default
  lv_strasse = ls_kna1-stras.
  lv_hnr     = space.
* split to get the last part
  split ls_kna1-stras at ' ' into table lt_split.
  describe table lt_split lines lv_lin.
* check if text contains spaces
  if lv_lin gt 1.
*   get last part
    read table lt_split into ls_split index lv_lin.
    lv_hnr = ls_split-value.
*   check last part contains any numbers
    if lv_hnr ca '0123456789'.
      subtract 1 from lv_lin.
      clear lv_strasse.
      do lv_lin times.
        read table lt_split into ls_split index sy-index.
        if sy-index = 1.
          lv_strasse = ls_split-value.
        else.
          concatenate lv_strasse ls_split-value
           into lv_strasse separated by ' '.
        endif.
      enddo.
    else.
*   last part has no number -> back to default
      clear lv_hnr.
    endif.
  endif.


* ----- call btci module
  call function '/IATL/UDC_IXCRM_BTCI_XD02'
    exporting
*     CTU                 = 'X'
*     MODE                = 'N'
*     UPDATE              = 'L'
*     GROUP               = GROUP
*     USER                = USER
*     KEEP                = KEEP
*     HOLDDATE            = HOLDDATE
*     NODATA              = '/'
      iv_kunnr            = lv_kunnr
*     D0110_002           = 'X'
*     USE_ZAV_003         = 'X'
      iv_name1            = lv_name
*     IV_NAME2            = '/'
*     IV_SORT1            = '/'
      iv_street           = lv_strasse
      iv_house_num1       = lv_hnr
      iv_post_code1       = lv_plz
      iv_city1            = lv_ort
*     IV_COUNTRY          = '/'
*     IV_LANGU            = '/'
   importing
     subrc               = lv_subrc
   tables
     messtab             = lt_messtab
            .

* ------ map bdc messages
  call method /iatl/cl_udc_hndl_replica=>util_convert_bdcmsgcoll
    exporting
      it_bdcmsgcoll = lt_messtab[]
    receiving
      et_messages   = ct_messages.


* ------ check errors in bdc messages
  loop at ct_messages transporting no fields
      where type ca 'EAX'.
    lv_subrc = 1.
    exit.
  endloop.


* ------ check for errors
  if lv_subrc ne 0.
    raise failed.
  endif.

endmethod.

5. SAPGUI Integration

5.1. Einbinden von Portalseiten im SAPGUI

*&---------------------------------------------------------------------*
*& Report  /IATL/IXA_DEMO_IX_FROM_SAPGUI
*&
*&---------------------------------------------------------------------*
*& Demo: Using Intrexx Portal pages within SAPGUI
*& (c) 2008 www.initall.de
*&---------------------------------------------------------------------*

REPORT  /IATL/IXA_DEMO_IX_FROM_SAPGUI no standard page heading.


* ------- interface
PARAMETERS: p_url TYPE char255 lower case.
PARAMETERS: P_URLPOR TYPE CHAR255 lower case default 'http://localhost:8080/bugfix45/?'.
PARAMETERS: p_dock AS CHECKBOX DEFAULT 'X'.

* ------- local data
TABLES: kna1.
DATA: lo_container_sc TYPE REF TO cl_gui_custom_container.
DATA: lo_container_dc TYPE REF TO cl_gui_docking_container.
DATA: lo_container_dg TYPE REF TO cl_gui_dialogbox_container.
DATA: lo_html1 TYPE REF TO cl_gui_html_viewer.
DATA: lo_html2 TYPE REF TO cl_gui_html_viewer.
DATA: lv_url_kunnr TYPE char255.

START-OF-SELECTION.

* ------- set default url if empty
  IF p_url EQ space.
    p_url = 'http://www.unitedplanet.de'.
  ENDIF.

* ------- build url for filtered customer info
  CONCATENATE
    p_urlpor
    'rq_AppId=31313035&rq_TargetId=31303131&rq_RecId=2D31'
    '&rq_Template=696E7465726E616C2F6C61796F75742F766D2F68746D6C2F6C61796F7574342F667261'
    '6D65732F6170706D61696E2E766D'
    INTO lv_url_kunnr.


* ------- call screen
  CALL SCREEN 2000.


*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_2000  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_2000 INPUT.
  CASE sy-ucomm.
    WHEN 'CANC' OR 'EXIT' OR 'BACK'.
      LEAVE TO SCREEN 0.
  ENDCASE.
  IF sy-ucomm EQ space AND kna1-kunnr NE space.
    PERFORM refresh_kunnr USING kna1-kunnr.
  ENDIF.
ENDMODULE.                 " USER_COMMAND_2000  INPUT
*&---------------------------------------------------------------------*
*&      Module  STATUS_2000  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_2000 OUTPUT.
  SET PF-STATUS '2000'.
  SET TITLEBAR '2000'.
  PERFORM init_controls.
ENDMODULE.                 " STATUS_2000  OUTPUT
*&---------------------------------------------------------------------*
*&      Form  init_controls
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM init_controls .
  CHECK lo_container_sc IS INITIAL.


* ------------ DYNPRO
  CREATE OBJECT lo_container_sc
    EXPORTING
      container_name = 'CONTAINER_PORTAL'.

  CREATE OBJECT lo_html1
    EXPORTING
      parent = lo_container_sc.


* ------------ DOCKING OR DIALOG
  IF p_dock EQ 'X'.
    CREATE OBJECT lo_container_dc
      EXPORTING
        repid     = sy-repid
        dynnr     = sy-dynnr
        side      = cl_gui_docking_container=>dock_at_right
        extension = 400.

    CREATE OBJECT lo_html2
      EXPORTING
        parent = lo_container_dc.

  ELSE.
    CREATE OBJECT lo_container_dg
      EXPORTING
        width   = 400
        height  = 200
        top     = 0
        left    = 0
        caption = 'Zusatzinformationen'.

    CREATE OBJECT lo_html2
      EXPORTING
        parent = lo_container_dg.

  ENDIF.

* ------------ SHOW URL
  CALL METHOD lo_html1->show_url
    EXPORTING
      url = lv_url_kunnr.

  CALL METHOD lo_html2->show_url
    EXPORTING
      url = p_url.

ENDFORM.                    " init_controls
*&---------------------------------------------------------------------*
*&      Form  refresh_kunnr
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_KNA1_KUNNR  text
*----------------------------------------------------------------------*
FORM refresh_kunnr  USING    p_kunnr.

  DATA: lv_url TYPE char255.
  DATA: lv_kunnr TYPE string.

  lv_url = lv_url_kunnr.


  lv_kunnr = p_kunnr.

*  clear kna1.
  select single * from kna1 into kna1
    where kunnr = p_kunnr.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = lv_kunnr
    IMPORTING
      output = lv_kunnr.


  CONCATENATE lv_url
              '&rq_kunnr='
              INTO lv_url.


  WHILE lv_kunnr NE space.

    CONCATENATE lv_url
                '3'
                lv_kunnr(1)
                INTO lv_url.

    lv_kunnr = lv_kunnr+1.

  ENDWHILE.


  CALL METHOD lo_html1->show_url
    EXPORTING
      url = lv_url.


ENDFORM.                    " refresh_kunnr
Das Dynpro 2000 sowie der GUI-Status muss zusätzlich implementiert werden. Auf dem Dynpro werden Felder der Struktur KNA1 erwartet (mindestens KNA1-KUNNR). Zur Aufnahme der späteren Webseite wird ein Custom-Container mit dem Namen "CONTAINER_PORTAL" erwartet.

5.2. SAP Business Objekte starten

Aufruf von SAP-Oberflächen über Funktionen der entsprechenden Business-Objekte aus Transaktion "SWO1". Für die Übergabe von Parametern muss dieser Report zusätzlich in einer Transaktion aufgerufen werden.
*&---------------------------------------------------------------------*
*& Report  /IATL/SSO_START_BOR
*&
*&---------------------------------------------------------------------*
*& Starting SAP documents via BOR (transaction SWO1) remote
*& 
*&---------------------------------------------------------------------*

report  /iatl/sso_start_bor.

* --------- interface
parameters: object type swo_objtyp obligatory.
parameters: key    type swo_typeid obligatory.
parameters: method type swo_method obligatory default 'DISPLAY'.
parameters: numlen type i default 0.


start-of-selection.

* ------------ local data
  data: lv_len type i.

* ------------ append zeros
  if numlen gt 0.
    do.
      lv_len = strlen( key ).
      if lv_len ge numlen.
        exit. "from do
      else.
        concatenate '0' key into key.
      endif.
    enddo.
  endif.


* ------------ call sap
  call function 'EWC_OBJ_METHOD_CALL'
    exporting
      x_objtype              = object
      x_objkey               = key
      x_method               = method
*   X_FREE                 = X_FREE
* TABLES
*   X_CONT                 = X_CONT
   exceptions
     object_not_found       = 1
     method_failed          = 2
     others                 = 3
            .
  if sy-subrc <> 0.
    write: 'Es sind Fehler aufgetreten.'.
  endif.

6. JavaScript-Beispiele

6.1. SAP-Shortcut über Schaltfläche starten

/**
 * BIASAP: start a sapgui shortcut with type transaction
 */
function biasap_start_transaction(p_instance, p_loginmode, p_transaction, p_extra, p_skip){
	oShortcut = new upActionControl();
	oShortcut.oHtml = new Object();
	oShortcut.oTarget = new upTarget();
	oShortcut.oTarget.rq_Template = "internal/system/vm/custom/biasap_shortcut.vm";
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_filename", "link.sap", oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_instance", p_instance, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_loginmode", p_loginmode, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_transaction", p_transaction, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_extra", p_extra, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_skipscreen", p_skip, oShortcut.oTarget.addParam);
	oShortcut.processRequest();
	return true;
}

/**
 * BIASAP: start a sapgui shortcut with type report
 */
function biasap_start_report(p_instance, p_loginmode, p_report, p_variant){
	oShortcut = new upActionControl();
	oShortcut.oHtml = new Object();
	oShortcut.oTarget = new upTarget();
	oShortcut.oTarget.rq_Template = "internal/system/vm/custom/biasap_shortcut.vm";
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_filename", "link.sap", oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_instance", p_instance, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_loginmode", p_loginmode, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_report", p_report, oShortcut.oTarget.addParam);
	oShortcut.oTarget.addParam = Helper.setQsValueByParam("rq_sc_variant", p_variant, oShortcut.oTarget.addParam);
	oShortcut.processRequest();
	return true;
}

6.2. Feldwerte im Kontext als Requestwert sichern

Diese Funktion ist universell einsetzbar und kann wie folgt über das onclick-Ereignis einer Schaltfläche aufgerufen werden:
"setRequestValue(´<guid des Textfeldes>´, this, 'rq_<id des request parameters')"
function setRequestValue(p_fieldguid, p_button, p_param){
 var oButton = null;	
 var oTextcontrol = getElement(p_fieldguid); 
 var sValue = "";

 // get access to button	
 if (p_button && p_button.oUp && p_button.oUp.upType == "upButtonControl")
 {
   oButton = p_button;
 }else{
   oButton = getElement(p_button); // try this parameter is GUID
 }
 if (!checkButtonReference(oButton)) return false;

 // get value from field	
 if (oTextcontrol && oTextcontrol.oUp && oTextcontrol.oUp.oHtml && (oTextcontrol.oUp.upType == "upTextControl" || oTextcontrol.oUp.upType == "upDateTimeControl"))
 {
	sValue = oTextcontrol.oUp.oHtml.value;
 } else {
	sValue = getTextValue(oTextcontrol);
 }

 // set request parameter
 if (sValue.length == 0 || sValue == false) {
	return false;
 }else{
	oButton.oUp.oTarget.addParam = Helper.setQsValueByParam(p_param, sValue, oButton.oUp.oTarget.addParam);
	return true;
 }
}

7. VTL-Mustercodings

7.1. Unterstützung für SAP-Shortcuts

##########################################################################
## Creating SAP Shortcuts from Intrexx Requests			 #
## 
##                                                                       #
## last changed 2008/10/08						 #
##                                                                       #
## Place this file as internal/system/vm/custom/biasap_shortcut.vm       #
## Intrexx >=4.5 required                                         #
## Use this Vm with Buttons, see documentation for sap adapter		 #
##########################################################################
##
## ================ get parameters for all moded
#set($instance 		= $Request.get("rq_sc_instance",""))
#set($loginmode 	= $Request.get("rq_sc_loginmode","user"))
##
## ================ get parameters for transaction mode
#set($transaction 	= $Request.get("rq_sc_transaction",""))
#set($extra	 	= $Request.get("rq_sc_extra",""))
#set($skipscreen	= $Request.get("rq_sc_skipscreen","false"))
##
## ================ get parameters for report mode
#set($report 	= $Request.get("rq_sc_report",""))
#set($variant	= $Request.get("rq_sc_variant",""))
##
## ================ create the shortcut
#if( $report == "" )
	#set($guid = $GSAP.shortcutNewTransaction($instance, $loginmode, $transaction, $extra, $skipscreen))
#else
	#set($guid = $GSAP.shortcutNewReport($instance, $loginmode, $report, $variant))	
#end	
##
##
## ================ set html header info
$Response.setIgnoreWrite(true)
$Response.setHeader("Content-Type","application/octet-stream")  
$Response.setHeader("Content-Transfer-Encoding:", "$Request.get('rq_MimeCharset','$charset')")
$Response.setHeader("Content-Disposition","attachment;filename=$Request.get('rq_sc_filename','sap.sap')")
$Response.setIgnoreWrite(false)
##
## ================ output shortcut as text
$Response.setIgnoreWrite(false)
$GSAP.shortcutGetAsText($guid)
$Response.setIgnoreWrite(true)
##
## ================ remove from cache
#$GSAP.shortcut.remove($guid)

7.2. Requestwerte mit AJAX an den Server übergeben

$Response.setIgnoreWrite(true)
## Ermittle CostCenter aus Requestwert und erstelle Session-Parameter

#set( $costCenterId = $Request.get('rq_customCostCenterId') )
#set( $costCenterName = $Request.get('rq_customCostCenterName') )
$Session.put('costCenterId', $!costCenterId)
$Session.put('costCenterName', $!costCenterName)

## Header Schreiben
$Response.setHeader("Cache-Control","no-cache")
$Response.setHeader("Content-Type","text/json; charset=UTF-8")
$Response.setIgnoreWrite(false)
## Erzeugung der JSON-Objekte
#if( 1 == 1 )
{"myobject":{"result":"true"}
#else
{"error":{"title":"ERROR","message":"Session parameter not created"}}
#end

8. Weitere Informationen

Entwicklerhandbuch Anhang
API Entwicklerhandbuch