Quantcast
Channel: Programmierung – Tricktresor
Viewing all 166 articles
Browse latest View live

ALV-Grid und Dropdown

$
0
0

Es gibt einige Verhaltensweise in SAP-Objekten, bei denen ich einfach nicht verstehe, warum diese nicht schon seit langer Zeit behoben wurden. Eine dieser Missstände ist, dass im Eingabebereiten ALV-Grid Felder nicht leer gelassen werden können, wenn an der Domäne Festwerte definiert sind und zu den Festwerten kein SPACE gehört. Dann sieht es so aus:

Ein anderes Phänomen sind für mich die Drop-Down-Listen, oder auch Listboxen oder Auswahllisten. Hier gibt es zwei Varianten:

  • Variante A: nur mit dem internen Feldwert
  • Variante B: Alias, die einen internen Feldwert und eine Bezeichnung erlaubt

Variante A ist fast immer nutzlos, denn in den seltensten Fällen möchte man nur den internen Wert in der Auswahlhilfe sehen. Hier ein Beispiel im Feld “Status”:

Variante B mit dem Alias ist bereits hilfreicher, denn der Anwender kann bei der Auswahl der Werte erkennen, was der Wert bedeutet. Hier ein Beispiel im Feld “Fruit”:

Hier ist für mich jedoch das Manko, dass nach Auswahl der Bezeichner nicht mehr zu sehen ist. Zudem wird der interne Wert in der Drop-Down-Liste nicht angezeigt, wenn man ihn nicht explizit mit einprogrammiert.

Beide Varianten unterscheiden sich somit von den Listboxen, die man vom Dynpro kennt. Hier kann man den beschreibenden Text nicht nur bei der Eingabe sehen:

Sondern auch nach der Auswahl:

Im SAPGUI kannst du noch einstellen, ob du den Schlüsselwert sehen möchtest oder nicht:

Das ist eine sinnvolle Darstellung von Listboxen.

Drop-Down-Liste und Festwerte

Für das ALV-Grid gibt es meines Wissens keine einfache Alternative um ein Feld als Listbox im Feldkatalog zu definieren, so dass vorhandene Festwerte direkt und ohne weiteres Zutun in der Drop-Down-Liste angezeigt werden.

Alternativen

Jedes Mal auf’s Neue kann ich nicht glaube, dass es im ALV-Grid keine andere Möglichkeit gibt, also habe ich mir folgende Alternativen überlegt. Beide Alternativen arbeiten mit einem zusätzlichen Feld.

  1. Auswahl Schlüsselfeld und Beschreibung in separates Feld
  2. Auswahl Textfeld und Ermittlung der ID

Beide Varianten bedeuten mehr Aufwand, denn du musst das Ereignis DATA_CHANGED registrieren und ausprogrammieren. Sie bedeuten jedoch für den Anwender auch einen größeren Bedienkomfort.

Leider habe ich noch keine Möglichkeit gefunden, dass der Text sofort nach Auswahl aktualisiert wird. Der Anwender muss in jedem Fall eine Taste drücken oder in ein anderes Feld klicken.

Auswahl Schlüsselfeld

Ich definiere für die Ausgabe ein separates Feld, das den Bezeichner des zugehörigen Feldes aufnimmt. In diesem Beispiel das Feld “Hardware-ID”:

Ich verwende die Drop-Down-Alias-Variante. Zusätzlich wird im Ereignis CL_GUI_ALV_GRID-DATA_CHANGED der Feldwert ausgelesen und mittels MODIFY_CELL in das zugehöriger Bezeichnerfeld geschrieben.

Auswahl Textfeld

In dieser Variante definiere ich die Drop-Drown-Liste für das Beschreibungsfeld und ermittle aus der Beschreibung den internen Schlüssel:

Fazit

Welche Variante du verwendest, musst du selbst entscheiden. Meiner Meinung nach ist die erste Variante einen Tick einfacher, da hier bei dem internen Feldwert der richtige interne Wert direkt mitgegeben werden kann und so der Text zur ID ermittelt wird. Bei der zweiten Variante wird die ID zum Text ermittelt, was eher ungewöhnlich ist.

Vorteil der zweiten Variante ist, dass das Schlüsselfeld mit dem internen Wert einfach versteckt werden kann und so für den Benutzer gar nicht sichtbar ist. Der Benutzer sieht also nur den Wert, der in der Regel auch sprechend und sinnvoll für ihn ist.

In beiden Fällen muss sichergestellt werden, dass interner Wert und externe Beschreibung immer zueinander passen und korrekt ermittelt werden.

Code

REPORT.

PARAMETERS p_hwid TYPE c LENGTH 1 AS LISTBOX VISIBLE LENGTH 20.


CLASS main DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF _line,
             id   TYPE c LENGTH 1,
             text TYPE c LENGTH 20,
           END OF _line,
           _tab TYPE SORTED TABLE OF _line WITH UNIQUE KEY id.

    TYPES: BEGIN OF _data_line,
             key         TYPE c LENGTH 2,
             status      TYPE c LENGTH 1, "Dropdown
             fruit       TYPE c LENGTH 1, "Dropdown Alias
             hardware    TYPE c LENGTH 1, "Dropdown Alias + separate text field
             hw_text     TYPE c LENGTH 20,
             weekday_id  TYPE c LENGTH 1,
             weekday_txt TYPE c LENGTH 20,
           END OF _data_line,
           _data_table TYPE STANDARD TABLE OF _data_line WITH EMPTY KEY.

    CLASS-DATA hw_ids TYPE _tab.
    CLASS-DATA weekday_ids TYPE _tab.

    METHODS constructor.
    CLASS-METHODS class_constructor.

    METHODS display
      IMPORTING
        container TYPE REF TO cl_gui_container.

  PRIVATE SECTION.
    DATA datatable TYPE _data_table.
    DATA grid TYPE REF TO cl_gui_alv_grid.

    DATA dropdown       TYPE lvc_t_drop.
    DATA dropdown_alias TYPE lvc_t_dral.

    CONSTANTS dd_handle_status  TYPE i VALUE 1.
    CONSTANTS dd_handle_fruit   TYPE i VALUE 2.
    CONSTANTS dd_handle_hw      TYPE i VALUE 3.
    CONSTANTS dd_handle_weekday TYPE i VALUE 4.

    METHODS on_data_changed FOR EVENT data_changed
      OF cl_gui_alv_grid
      IMPORTING
        e_onf4
        e_onf4_after
        e_onf4_before
        e_ucomm
        er_data_changed.

    METHODS get_fcat
      RETURNING VALUE(result) TYPE lvc_t_fcat.
ENDCLASS.

CLASS main IMPLEMENTATION.
  METHOD class_constructor.

    hw_ids = VALUE #(
      ( id = 'X' text = 'Tablet' )
      ( id = 'Y' text = 'Personal Computer' )
      ( id = 'Z' text = 'Laptop' ) ).

    weekday_ids = VALUE #(
      ( id = '1' text = 'Monday' )
      ( id = '2' text = 'Tuesday' )
      ( id = '3' text = 'Wednesday' )
      ( id = '4' text = 'Thursday' )
      ( id = '5' text = 'Friday' )
      ( id = '6' text = 'Saturday' )
      ( id = '7' text = 'Sunday' ) ).

  ENDMETHOD.

  METHOD constructor.

    "Simple Dropdown: STATUS
    dropdown = VALUE #( handle = dd_handle_status
      ( value = '1' )
      ( value = '2' )
      ( value = '3' ) ).

    "Dropdown-Alias: FRUITS
    dropdown_alias = VALUE #( handle = dd_handle_fruit
      ( int_value = 'A' value = 'Apple' )
      ( int_value = 'B' value = 'Banana' )
      ( int_value = 'C' value = 'Coconut' ) ).

    "Dropdown-Alias with description field: HARDWARE
    APPEND LINES OF VALUE lvc_t_dral(
      FOR l_hw IN hw_ids (
        handle = dd_handle_hw
        int_value = l_hw-id
        value = l_hw-text ) )
          TO dropdown_alias.

    "Dropdown-Alias with description selection: WEEKDAY
    APPEND LINES OF VALUE lvc_t_dral(
      FOR l_wd IN weekday_ids (
        handle = dd_handle_weekday
        int_value = l_wd-text
        value = l_wd-text ) )
          TO dropdown_alias.

    "fill demo data in internal table
    datatable = VALUE #(
       ( key = '10' status = '1' fruit = 'A' hardware = 'X' weekday_id = '3' )
       ( key = '20' )
       ( key = '30' ) ).

  ENDMETHOD.

  METHOD display.

    grid = NEW #( i_parent = container ).

    DATA(fcat) = get_fcat( ).

    LOOP AT datatable ASSIGNING FIELD-SYMBOL(<data>).
      IF <data>-hardware IS NOT INITIAL.
        <data>-hw_text = dropdown_alias[ handle = dd_handle_hw int_value = <data>-hardware ]-value.
        <data>-weekday_txt = weekday_ids[ id = <data>-weekday_id ]-text.
      ENDIF.
    ENDLOOP.

    grid->set_drop_down_table(
      it_drop_down       = dropdown
      it_drop_down_alias = dropdown_alias ).

    grid->set_table_for_first_display(
      CHANGING
        it_outtab                     = datatable
        it_fieldcatalog               = fcat
      EXCEPTIONS
        OTHERS                        = 4 ).
    IF sy-subrc > 0.
      RETURN.
    ENDIF.

    SET HANDLER on_data_changed FOR grid.
    grid->register_edit_event( cl_gui_alv_grid=>mc_evt_modified ).

  ENDMETHOD.

  METHOD get_fcat.

      result = VALUE #( tabname = '1' datatype = 'CHAR'
      ( fieldname = 'KEY'         outputlen = 10 intlen =  2 drdn_hndl = 0                 drdn_alias = ' ' reptext = 'Key'             edit = ' ' )
      ( fieldname = 'STATUS'      outputlen = 10 intlen =  1 drdn_hndl = dd_handle_status  drdn_alias = ' ' reptext = 'Status'          edit = 'X' )
      ( fieldname = 'FRUIT'       outputlen = 10 intlen =  1 drdn_hndl = dd_handle_fruit   drdn_alias = 'X' reptext = 'Fruit'           edit = 'X' )
      ( fieldname = 'HARDWARE'    outputlen = 10 intlen =  1 drdn_hndl = dd_handle_hw      drdn_alias = 'X' reptext = 'Hardware-ID'     edit = 'X' )
      ( fieldname = 'HW_TEXT'     outputlen = 30 intlen = 20 drdn_hndl = 0                 drdn_alias = ' ' reptext = 'Hardware descr.' edit = ' ' )
      ( fieldname = 'WEEKDAY_ID'  outputlen = 10 intlen =  1 drdn_hndl = 0                 drdn_alias = ' ' reptext = 'Weekday ID'      edit = ' ' )
      ( fieldname = 'WEEKDAY_TXT' outputlen = 20 intlen = 20 drdn_hndl = dd_handle_weekday drdn_alias = 'X' reptext = 'Weekday'         edit = 'X' lowercase = 'X')
        ).

  ENDMETHOD.

  METHOD on_data_changed.
    DATA text TYPE string.

    LOOP AT er_data_changed->mt_good_cells INTO DATA(cell).
      CASE cell-fieldname.
        WHEN 'HARDWARE'.
          text = COND #( WHEN cell-value IS INITIAL THEN `` ELSE dropdown_alias[ handle = dd_handle_hw int_value = cell-value ]-value ).
          er_data_changed->modify_cell(
            i_row_id    = cell-row_id
            i_tabix     = cell-tabix
            i_fieldname = 'HW_TEXT'
            i_value     = text ).
        WHEN 'WEEKDAY_TXT'.
          text = COND #( WHEN cell-value IS INITIAL THEN `` ELSE weekday_ids[ text = cell-value ]-id ).
          er_data_changed->modify_cell(
            i_row_id    = cell-row_id
            i_tabix     = cell-tabix
            i_fieldname = 'WEEKDAY_ID'
            i_value     = text ).
      ENDCASE.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.


INITIALIZATION.
  DATA(docker) = NEW cl_gui_docking_container( side = cl_gui_docking_container=>dock_at_bottom ratio = 80 ).
  DATA(app) = NEW main( ).
  app->display( docker ).

  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'P_HWID'
      values = CORRESPONDING vrm_values( main=>hw_ids MAPPING key = id text = text ).

Der Beitrag ALV-Grid und Dropdown erschien zuerst auf Tricktresor.


IMG-Struktur anzeigen

$
0
0

Für den ein oder anderen Fall kann es sinnvoll sein, eine Unternehmensstruktur (IMG) direkt anzeigen oder sogar editieren zu können.

Hintergrundinfo

Die IMG-Struktur wird hauptsächlich in den Tabellen TTREE und TTREET verwaltet. Eine IMG-Struktur hat eine GUID und kann über den Kurztext in Tabelle TTREET ermittelt werden. IMG steht übrigens für Implementation Guide (Einführungsleitfaden).

Die Knoten einer Unternehmensstruktur kannst du im SAP-Customizing über Transaktion SPRO einsehen und aufrufen.

Einzelne Knoten werden mit Transaktion SIMGH angezeigt. Erweiterungen zur Unternehmensstruktur kannst du mit Transaktion S_IMG_EXTENSION verwalten.

Code

Das folgende Programm bietet die Möglichkeit, eine IMG-Struktur direkt anzuzeigen oder zu bearbeiten.

PARAMETERS: 
  p_struct TYPE ttree-id OBLIGATORY,
  p_edit   TYPE xfeld.

START-OF-SELECTION.
  IF NOT p_struct IS INITIAL.
    CALL FUNCTION 'STREE_EXTERNAL_EDIT'
      EXPORTING
        structure_id   = p_struct
        language       = sy-langu
        edit_structure = 'X' 
        activity       = COND char1( WHEN p_edit = 'X' THEN 'E' ELSE 'D' ).
  ENDIF.

Der Beitrag IMG-Struktur anzeigen erschien zuerst auf Tricktresor.

Veralteten Baustein WWW_GET_MIME_OBJECT ersetzen

$
0
0

In einer alten Programmierung habe ich den folgenden Code verwendet, um ein Bild aus dem MIME-Repository (Transaktion SMW0) zu laden und anzuzeigen:

CLASS pic DEFINITION.

  PUBLIC SECTION.

    DATA mo_picture TYPE REF TO cl_gui_picture .

    METHODS display
      IMPORTING
        name      TYPE clike
        container TYPE REF TO cl_gui_container
        disp_mode TYPE i DEFAULT cl_gui_picture=>display_mode_fit_center .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS pic IMPLEMENTATION.


  METHOD display.

    DATA query_table    TYPE STANDARD TABLE OF w3query.
    DATA query_line     TYPE w3query.
    DATA html_table     TYPE STANDARD TABLE OF w3html .
    DATA html_line      TYPE w3html .
    DATA return_code    TYPE w3param-ret_code.
    DATA content_type   TYPE w3param-cont_type.
    DATA content_length TYPE w3param-cont_len.
    DATA pic_data       TYPE STANDARD TABLE OF w3mime .
    DATA url            TYPE c LENGTH 1000.

    query_line-name  = '_OBJECT_ID'.
    query_line-value = name.
    APPEND query_line TO query_table.

    CALL FUNCTION 'WWW_GET_MIME_OBJECT'
      TABLES
        query_string        = query_table
        html                = html_table
        mime                = pic_data
      CHANGING
        return_code         = return_code
        content_type        = content_type
        content_length      = content_length
      EXCEPTIONS
        object_not_found    = 1
        parameter_not_found = 2
        OTHERS              = 3.

    CALL FUNCTION 'DP_CREATE_URL'
      EXPORTING
        type     = 'image'
        subtype  = cndp_sap_tab_unknown
        size     = content_length
        lifetime = cndp_lifetime_transaction
      TABLES
        data     = pic_data
      CHANGING
        url      = url
      EXCEPTIONS
        OTHERS   = 1.

    mo_picture = NEW #( container ).
    mo_picture->load_picture_from_url( url ).
    mo_picture->set_display_mode( disp_mode ).

  ENDMETHOD.

ENDCLASS.

PARAMETERS dummy.

INITIALIZATION.
  DATA(docker) = NEW cl_gui_docking_container( ratio = 50 side = cl_gui_docking_container=>dock_at_bottom ).
  NEW pic( )->display(
    name      = 'ENJOYSAP_LOGO'
    container = docker
    disp_mode = cl_gui_picture=>display_mode_fit_center ).   

Leider hat sich der ATC-Check darüber beschwert, dass der Funktionsbaustein WWW_GET_MIME_OBJECT obsolet ist und nicht mehr verwendet werden soll.

Lösung

Der Funktionsbaustein WWW_GET_MIME_OBJECT muss ersetzt werden durch Baustein DP_PUBLISH_WWW_URL. Dadurch wird der Code auch deutlich schlanker:

  METHOD display.

    DATA url   TYPE cndp_url.
    DATA objid TYPE w3objid.

    objid = name.

    CALL FUNCTION 'DP_PUBLISH_WWW_URL'
      EXPORTING
        objid    = objid
        lifetime = cndp_lifetime_transaction
      IMPORTING
        url      = url
      EXCEPTIONS
        OTHERS   = 1.
    IF sy-subrc = 0.
      mo_picture = NEW #( parent = container ).
      mo_picture->load_picture_from_url( url ).
      mo_picture->set_display_mode( disp_mode ).
    ENDIF.

  ENDMETHOD

Der Beitrag Veralteten Baustein WWW_GET_MIME_OBJECT ersetzen erschien zuerst auf Tricktresor.

Daten aus ALV ermitteln

$
0
0

Vor einem Jahrzehnt habe ich den Post Exporting ALV to Memory2 veröffentlicht, in dem ich bei meinen Recherchen zu Mendocino darauf gestoßen bin, wie man Daten aus einem Report zurück bekommen kann, der die diese per ALV anzeigt.

Heute brauchte ich diesen Trick, um im SD-Bonusmanagement die Daten abzugreifen, die der Baustein WB2R_PRINT_BUSINESS_VOLUME ermittelt. Der Baustein liest alle Daten, die ich benötige. Leider ruft er am Ende einen ALV auf, so dass ich den Baustein nicht ohne weiteres verwenden kann.

Nachdem ich sichergestellt habe, dass ich die Daten wie gewünscht lesen kann, ist mir aufgefallen, dass die Daten so zurückkommen, wie sie im verwendeten Layout definiert waren. Um auf Layoutänderungen gefasst zu sein, begab ich mich auf die Suche danach, wie ich es umgehen kann, dass das Default-Layout verwendet wird. Hier bin ich leider nicht fündig geworden. Allerdings habe ich etwas viel besseres gefunden: Den Community-Blog-Post Get ALV data in background ( cl_salv_bs_runtime_info ) von jorg_vdst.

In diesem Post beschreibt jorg_vdst einen simplen Weg, wie man an alle Daten des ALV herankommt:

" prepare
cl_salv_bs_runtime_info=>set(
  display  = abap_false
  metadata = abap_false
  data     = abap_true ).

" Call program or function mondule that calls ALV
CALL FUNCTION 'WB2R_PRINT_BUSINESS_VOLUME'
  EXPORTING
    iv_output_level               = p_level
    iv_bvb_data_type              = p_bvb
    iv_maxout                     = p_maxout
    iv_without_db_authority_check = abap_true
    it_contracts                  = contracts.

" Get ALV data
FIELD-SYMBOLS <DATA> TYPE ANY TABLE.
TRY.
    cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lr_data ).
    ASSIGN lr_data->* TO <data>.
  CATCH cx_salv_bs_sc_runtime_info.
    MESSAGE 'Unable to retrieve ALV data' TYPE 'E'.
ENDTRY.
 
cl_salv_bs_runtime_info=>clear_all( ).

Das Schöne hier bei ist, dass man wirklich alle Daten bekommt, die dem ALV übergeben wurden. Zusätzlich kann man der Methode CL_SALV_BS_RUNTIME_INFO=>SET auf mitgeben, dass die Daten vorher trotzdem angezeigt werden sollen. Der Parameter METADATA muss gesetzt werden, wenn man später mit CL_SALV_BS_RUNTIME_INFO=>GET_METADATA die Metadaten des ALV ermitteln möchte. In den Metadaten ist der Feldkatalog enthalten.

Was leider nicht funktionierte: Als ich den Parameter DISPLAY auf TRUE gesetzt habe, um die Daten anzeigen zulassen, habe ich die Sortierung, Filter und Feldkatalog geändert. Meine Erwartung war, dass ich diese Änderung in den Metadaten sehe. Leider war das nicht der Fall.

Auf jeden Fall ist die Lösung mit CL_SALV_BS_RUNTIME_INFO eine saubere Variante, um an die Daten eines ALV heranzukommen. Das aufgerufene Programm oder Funktionsbaustein darf natürlich keine anderen Dynpros aufrufen. Diese werden nicht unterdrückt.

Interview mit Björn Schulz (Software-Heroes.com)

$
0
0

Den Tricktresor gibt es nun seit mehr als 21 Jahren. Während dieser Zeit habe ich viele Blogs kommen und gehen gesehen. Einige hatten nur drei bis zehn Beiträge, bevor nichts mehr passierte, andere hielten länger durch, aber nach ein paar Jahren ist bei den meisten die Luft raus. Inzwischen gibt es einige Blogs, die sich mehr oder weniger regelmäßig mit SAP und speziell mit der ABAP-Programmierung beschäftigen. Die meisten sind jedoch in Englisch geschrieben. Zu den deutschsprachigen Webseiten, die bezüglich ABAP immer noch im Rennen sind, gehören:

Seit sechs Jahren gibt es die Seite Software-Heroes.com von Björn Schulz, der richtig Gas gibt. Björn veröffentlicht wöchentlich neue umfangreiche Artikel (jeweils in Deutsch und Englisch!) zu zumeist aktuellen Themen. Die Artikel sind ausführlich geschrieben und decken fast alles ab, was man zu dem Thema wissen sollte. Er geht dabei sehr konsequent und methodisch vor, wovor ich nur den Hut ziehen kann. Aus seiner Arbeit sind auch die ABAP-Feature Matrix und die ABAP-Learning Matrix entstanden, in denen Informationen aufbereitet werden, die anderweitig so nicht verfügbar sind.

Da ich weiß, wie viel Arbeit und Herzblut in so einem Blog steckt, wollte ich mehr über Björn erfahren. Hier sind die Fragen, die ich im stellte und seine Antworten:

Interview

Du arbeitest bei der rewe-group. Was ist deine Aufgabe dort?

Angefangen hatte ich bei der REWE Systems mit der Einarbeitung in das Thema Workflow und dem Fachmodul Treasury, also erst einmal als normaler ABAP Entwickler. Da ich schon immer auch an technischen Themen interessiert war, hatte ich schnell das Thema Entwicklerrichtlinie und Aufbau ABAP Test Cockpit (ATC) übernommen. Wichtig war mir das Thema moderne Entwicklung und ABAP der Zukunft, woraufhin wir eine interne Schulungsserie gestartet haben, für die ich viel von dem Schulungsinhalten vorbereitet und auch die Schulungen durchgeführt hatte. Zu dieser Zeit war mein Blog seit knapp 1,5 Jahren am Bestehen. Nach der internen Umstrukturierung auf eine agile Produktlandschaft und die REWE digital, bin seit dem vor allem als Techniker unterwegs und kümmere mich um den Aufbau unserer Entwicklungslandschaft. Dazu gehören Themen wie: Aufbau und Betrieb ABAP Environment, Code-Reviews, Beratung und Schulung der Entwickler, Einführung ABAP Cloud, interne SAP Community und sich die neuen Dinge anschauen.

Welche Hobbies hast du?

Ich würde sagen ich habe mein Hobby zum Beruf gemacht, da ich bereits sehr früh mit der Entwicklung angefangen habe. Ich habe mir im Laufe der Zeit einiges an Programmiersprachen und Frameworks angeschaut (Visual Basic, Pascal, PHP, JavaScript, Dart, ABAP, Python, etc.) und kleinere/größere Projekte damit privat umgesetzt. Dazu kommt noch der tägliche Sport, um trotz Beruf und Freizeittätigkeiten einigermaßen fit zu bleiben und Gaming um den Kopf mal runter zu bekommen.

Wie bist du auf die Idee zu Software-heroes gekommen? Was hat dich motiviert, einen eigenen Blog zu betreiben?

Angefangen hatte es mit einem kleinen Projekt, welches ich für meine Frau umgesetzt hatte. Ein kleines Framework zur Erstellung von Content nach ihren speziellen Anforderungen. Dieses wollte ich weiterentwickeln, da ich Ideen für kleine Apps hatte, die man einfach nutzen kann. Aber auch weil ich kein Fan von zu vielen Apps auf dem Smartphone bin und einen einfachen Weg der Nutzung bevorzuge. Da es bereits erste Blogging Elemente gab, nutzte ich sie, um über meine Erfahrungen und meinen Lernweg zu schreiben, den ich mit ABAP auch gerade betrat.

Betreibst du den Blog privat oder geschäftlich?

Der Blog wird rein privat betrieben, ich übernehme alle Kosten die mit dem Betrieb, der Wartung und Weiterentwicklung zu tun haben. Deshalb steckt auch viel Liebe und viele Details darin.

Mit welchem CMS arbeitest du?

Ich setze aktuell auf mein eigenes CMS, welches ich nach meinen Wünschen und Ideen weiterentwickeln kann. Damit liegt zwar die volle Verantwortung wieder beim Entwickler, also mir, aber auch die Entwicklung so eines CMS erweitert den eigenen Horizont und das Wissen noch einmal gewaltig. Deshalb würde ich aktuell auch kein anderes CMS einsetzen wollen. Einen Namen hat es allerdings noch nicht bekommen, da es auch nicht öffentlich zur Verfügung steht.

Was war für dich die größte Herausforderung beim Bloggen?

Es ist sogar immer noch die größte Herausforderung beim Bloggen, regelmäßig Inhalte zu liefern. Ich denke aber auch das liegt an mir als Person, da ich seit Jahren den Freitag für meine Releases wähle und dort immer einen aktuellen ABAP Artikel veröffentlichen möchte. Da aktuell das Backlog mit den neuen Themen sehr voll ist, veröffentliche teilweise zweimal die Woche.

Woher nimmst du die Zeit zum Bloggen?

Das gute an meiner aktuellen Stelle ist, dass ich fortlaufend Schulungsinhalte erstelle und damit genug „relativ“ fertiges Material habe. Die Aufbereitung der meisten Inhalte passiert dann am Abend in unregelmäßigen Abständen. So habe ich manchmal schon 5 Artikel die auf einen Release warten und manchmal 5 Wochen keine Zeit oder keine Lust, wodurch der Puffer dann wieder weg ist. Es ist ein Geben und Nehmen, aber ich versuche dann schon regelmäßig zu liefern.

Du haust ja in kurzen Abständen einen Artikel nach dem anderen raus. Hast du eine Agenda für die Themen und einen Planung für die Veröffentlichungen oder entscheidest du spontan, was als nächstes kommt?

Grundsätzlich habe ich ein oder zwei Backlogs voll mit Themen, die mir im Alltag vor die Füße fallen oder aus Kommunikationen mit Kollegen und der Community entstehen. Daraus bastle ich mir eine Art Roadmap, um einen roten Faden zu bekommen und eine „Hauptstory“ zu erzählen, so wie mit dem ABAP RESTful Programming Model (RAP) oder aktuell ABAP Cloud. Dazwischen kommen immer wieder mal kleinere Themen, damit für jeden was dabei ist. Ich hatte es im letzten Jahr mit einer konkreten Planung versucht, aber dort sehr oft auch Items geschoben, sodass ich es wieder verworfen habe und das Adhoc plane.

Welches sind für dich persönlich die größten Herausforderungen beim Lernen/ Wissensaufbau? Und welche für ein Team?

Für mich persönlich stellt Zeit die größte Herausforderung dar, ich habe mich schon daran gewöhnt, das die meisten Beispiele recht oberflächlich sind und die Dokumentationen nie tief genug gehen. Daher nehme ich mir die Zeit eine Funktion intensiv zu testen und damit zu probieren, was geht und was vielleicht nicht so gut geht.

Bei einem Team sehe ich die Herausforderung bei den unterschiedlichen Menschen und Typen. Damit ist man schnell bei unterschiedlichen Ständen an Wissen, Niveau bei der Entwicklung und Lerngeschwindigkeit. Aus meiner Erfahrung heraus gibt man dann das Tempo vor und muss die „langsamsten“ am Ende immer noch einmal extra mitnehmen.

Welche Vorbehalte gegenüber neuen Themen begegnen dir am häufigsten bzw. welche sind am hartnäckigsten?

Im Bereich ABAP habe ich oft das Gefühl, die Menschen möchten ihren aktuellen Technologie-Stack nicht verlassen oder sich all zu schnell auf neue Dinge einlassen. Am Thema „Modern ABAP“ bin ich schon sehr lange dran, die neuen Statements sind einfach, schnell und machen Quellcode „teilweise“ weniger lang und kompliziert. Als ein zweites Thema sehe ich Eclipse, ich arbeite nun seit knapp 5 Jahren Eclipse-Only und teilweise fehlt mir die Orientierung in der SE80. Klar, am Anfang dauerte es etwas mit den Funktionen und dem Umgang, aber mittlerweile bin ich damit höchst Effizient und genieße die Vorteile (Refactoring, Informationen und ABAP Cleaner). Hier findet man noch sehr oft das SE80 Lager und mit Reports war alles besser.

Welche Tipps kannst du jemandem geben, der auf der Suche nach einer Lösung zu einem ABAP-Problem ist?

Ich würde sagen, kommt immer auf das Problem an. Die meisten Themen mit den ich mich herumschlage sind kaum bis gar nicht dokumentiert und es gibt keine guten Tutorial, die auch in die Tiefe gehen. Für mich heißt das dann, probieren, debuggen und zur Not SAP fragen, den außer dem Hersteller wird es wohl kaum einer wissen. Für alle allgemeinen Themen gehe ich meist über die Suchmaschine meiner Wahl und schaue, was andere darüber schreiben. Bei ABAP Statements finde ich die SAP Help schon sehr gut.

Was sind deine Pläne für die Zukunft?

Ich möchte gern das Thema Open Source in der ABAP Community etwas treiben und insgesamt mit der Community mehr in den Austausch kommen. Ich denke in meiner aktuellen Rolle als stellvertretender Sprecher bei der DSAG bin ich schon ein Stück nähergekommen. In meinem Unternehmen gibt es noch einiges zu tun, um die ABAP Entwicklung von Morgen aufzustellen und wer weiß was Übermorgen noch kommt.

Welcher ABAP-Befehl fehlt aus deiner Sicht? Ich hätte zum Beispiel gerne: CALL METHOD … DESTINATION…

Wenn ich immer wieder in PHP Unterwegs bin, freue ich mich danach in ABAP auf die einfache Verarbeitung von Tabellen/Arrays, wenn es um Loops, Filtern und Datenzusammenstellungen geht. ABAP hat eigentlich für fast alles ein Statement, von daher für mich soweit Feature Complete.

Was ist das nervigste ABAP-Konstrukt, das bei der täglichen Arbeit stört? Ich finde die umständliche Angabe der Filterkriterien bei FILTER auf Standardtabellen sehr nervig…

Eigentlich alle Konstrukte mit geschweiften oder eckigen Klammern, wo man sich beim Tippen die Finger brechen muss. Mag auf der englischen Tastatur recht einfach sein, auf der deutschen finde ich es sehr umständlich. Gern Tipps wie es besser oder einfacher geht. Ansonsten finde ich im Moment die neuen EML Statements (Entity Manipulation Language) noch recht sperrig zu benutzen und wirklich hübsch sehen die auch noch nicht aus.

Welche Dinge gibt es, bei denen du nicht verstehen kannst, dass sie so sind, wie sie sind, bzw. dass es keine bessere Lösung gibt? Ich verstehe nicht, warum die SM30 nicht weiterentwickelt wurde und warum Dynpros in Klassen nicht möglich sind.

Bei BOPF dachte ich immer, wieso so einen Riesen-Overhead an Objekten und Quellcode erstellen? Mit RAP kam dann endlich eine kürzere Lösung die einfacher umzusetzen ist. Sonst fällt mir nur das Friends Konzept bei Klassen ein, welches man einem OO Entwickler erst einmal näher bringen muss. Hier sollte man aufpassen, dass man es nicht als Standard verwendet, sondern eigentlich nur in „Notfällen“ oder für Unit-Tests.

Vielen Dank für das Interview, Björn!

7. December: Excel Racing Simulation – Root Vole Race

$
0
0

I am very happy to announce the Matjes Grand Prix 2024 which takes place online in December 14th as Wühlmausrennen.

Marco Matjes, a friend of mine, started the project on August 2017 as a VBA programming learning project.

Marco, a former winemaker, learned how to program Visual Basic this way. By the years, he added uncountable tiny, ironic, humoruos details to his game. Just have a look at the marvelous pixel art graphics!

There were not only horses running, but also pigs. Donkeys and goats were planned but not realised so far. This year the race will be run by camels. All participating animals can be designed online. You can define colurs and racing tactics. In the race all kinds of weather and other conditions will be respected.

In the Corona Cup 2021 it was possible that a horse was tested positive for Corona, so unfortunately it couldn’t start then. When the race starts, it also may happen that a horse refuses to start. Marco even published his own racing newspaper GALOPO.

Matjes Institute For Racing Simulation

Marco also founded the Matjes Institute for Racing Simulation. The institute researches all kinds of racing environments, tactics and side effects of races. Very hilarious is the Total Mudflat Algorithm (Gesamtwattalgorithmus), that describes how the racing simulation works in the Watt of the german North Sea.

This article describes, how the finishing photo will be calculated to grayscale.

Participation

You can design your own Camel and register for the participation in the Race 2022. You will have to pay a starter fee what will be donated to Große Hilfe für kleine Helden. Register here and follow the instructions on the website (Google translate or DeepL will help if you do not speak german).

Live Broadcast

You can follow the race live on TwitchTV on December 11th 2022 14:00 CET.

2 Euro auf Colomano

The latest Coup of Marco is his VBA book 2 Euro auf Colomano. He describes very detailed how everything in the Excel Racing Simulation works. If you ever wanted to have a really fun book about Visual Basic programming, then I can highly recommend you this masterpiece!

All the source code is available on github.

Viewing all 166 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>