*&---------------------------------------------------------------------*
*& Report Z_REPORT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT Z_REPORT.
*-----------------------------------------------------------------------
* SELEKTIONSBILD
*-----------------------------------------------------------------------
*-----------------------------------------------------------------------
* Zeitpunkt INITIALIZATION.
*-----------------------------------------------------------------------
INITIALIZATION.
*----------------------------------------------------------------------
* Zeitpunkt AT SELECTION-SCREEN
*----------------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT. "PBO
*-----------------------------------------------------------------------
* Zeitpunkt START-OF-SELECTION.
*-----------------------------------------------------------------------
START-OF-SELECTION.
*----------------------------------------------------------------------
* Zeitpunkt END-OF-SELECTION
*----------------------------------------------------------------------
END-OF-SELECTION.
Tag: SAP
[SAP] Systemzugehörigkeit von Objekten ändern
Die Systemzugehörigkeit eines Objektes kann man in der Tabelle TADIR einsehen.
Tabelle: TADIR
Feld: SRCSYSTEM
Einfache Änderung via SE03: https://l3consulting.de/systemzugehoerigkeit-von-objekten-ueber-se03-aendern-massenaenderung/
Danach ggf. noch die Transportschicht im Paket anpassen. Beim Speichern muss man dafür einen lokalen Transportauftrag anlegen. Dieser kann nach der Änderung wieder gelöscht werden.
Alternativ die Objekte erstmal in einen lokalen Transportauftrag aufnehmen und anschließend einen Transport von Kopien anlegen, die Objekte aus dem lokalen Auftrag aufnehmen und transportieren. Auf diesem Weg kann trotz “falscher” Transportschicht transportiert werden.
[ABAP] OM – Lese Personen auf und unterhalb einer OE
Auswertungsweg O-O-S-P liefert unter einer gegebenen Org. Einheit alle Personen, auch aus tieferen OE.
T-Code: OOAW

DATA(lt_actor) = VALUE tswhactor( ).
CALL FUNCTION 'RH_STRUC_GET'
EXPORTING
act_otype = 'O'
act_objid = lv_oe " die Org. Einheit, von der gestartet werden soll
act_wegid = 'O-O-S-P'
act_plvar = '01'
act_begda = sy-datum
act_endda = sy-datum
act_tflag = space
act_vflag = space
authority_check = space
TABLES
result_tab = lt_actor
EXCEPTIONS
no_plvar_found = 1
no_entry_found = 2
OTHERS = 3.
IF sy-subrc <> 0.
" do error handling
ENDIF.
" Nur Pernr's relevant
DELETE lt_actor WHERE otype <> 'P'.
" Doppelte Pernr's entfernen
DELETE ADJACENT DUPLICATES FROM lt_actor.
Zum Testen des Auswertungsweges kann man den Report RHSTRU00 verwenden. Einfach Planvariante, Objekttyp und eine ObjektId einer Org. Einheit eingeben, sowie den Auswertungsweg und Statusvektor 1 (aktiv).

[SAPUI5] MyInbox: Integration of Detail View – EmbedIntoDetail
https://launchpad.support.sap.com/#/notes/2305401 (App to App Navigation CookBook.pdf)
https://blogs.sap.com/2020/07/31/fiori-my-inbox-integration-of-custom-detail-page/
Target:
Go to /n/ui2/fpld_cust and define a second target for your App, i.e. approve.

The approve target needs the “emdedIntoDetails” parameter:

SWFVISU:
Add the new target for your WF Task. Here you have access to all attributes of your Workitem-Container. Pass all your mandatory fields you’ve defined in your oData Entity.
Some examples: https://blogs.sap.com/2016/05/31/my-inbox-open-task-swfvisu-configuration/

If your missing some parameters, just add them in your Workitem Task and pass the values directly into it right from your Workflow Container. This looks much better.

Manifest:
Add a route to navigate via Inbox. The pattern has to match your inbox url.

"routes": [
{
"pattern": "",
"name": "master",
"target": "master"
},
{
"pattern": "DataSet/{Pernr},{Datum},{Infty}",
"name": "object",
"target": [
"master",
"object"
]
},
{
"pattern": "detail/LOCAL_INBOX/{wfInstanceId}/{taskPath}",
"name": "wfobject",
"target": "object"
}
Detail.Controller:
onInit: function () {
// Model used to manipulate control states. The chosen values make sure,
// detail page is busy indication immediately so there is no break in
// between the busy indication for loading the view's meta data
var oViewModel = new JSONModel({
busy: false,
delay: 0
});
this.getRouter().getRoute("object").attachPatternMatched(this._onObjectMatched, this);
//My Inbox Integration
this.getRouter().getRoute("wfobject").attachPatternMatched(this._onWFObjectMatched, this);
this.setModel(oViewModel, "detailView");
this.getOwnerComponent().getModel().metadataLoaded().then(this._onMetadataLoaded.bind(this));
},
_onWFObjectMatched: function (oEvent) {
this.getModel("appView").setProperty("/layout", "MidColumnFullScreen");
var compData = this.getOwnerComponent().getComponentData();
if (compData && compData.startupParameters && compData.startupParameters.PERNR && Array.isArray(compData.startupParameters.PERNR) &&
compData.startupParameters.PERNR[0]) {
var sPernr = compData.startupParameters.PERNR[0];
var sDatum = compData.startupParameters.DATUM[0];
var sInfty = compData.startupParameters.INFTY[0];
this.byId("detailPage").addStyleClass("myInboxPage");
this.getModel().metadataLoaded().then(function () {
var sObjectPath = this.getModel().createKey("/DataSet", {
Pernr: sPernr,
Datum: sDatum,
Infty: sInfty
});
this._bindView(sObjectPath);
}.bind(this));
}
},
[Fiori] SWFVISU vs SWFVMD1
Best explanation I found directly in the code:

Update 21.10.2025: This is also mentioned in the note 3101192

[ABAP] ALV column header
DATA: o_salv TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = o_salv
CHANGING t_table = l_lines ).
LOOP AT o_salv->get_columns( )->get( ) REFERENCE INTO DATA(l_column).
DATA(lo_column) = CAST cl_salv_column( l_column->r_column ).
lo_column->set_fixed_header_text( 'L' ).
ENDLOOP.
o_salv->get_columns( )->get_column( 'TEST1' )->set_long_text( 'Test1 Header' ).
o_salv->get_columns( )->get_column( 'TEST2' )->set_long_text( 'Test2 Header' ).
o_salv->get_columns( )->get_column( 'TEST1' )->set_output_length( 30 ). "to increase the column width
Update 27.01.2026: Better use set_optimize
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ausgabe_tab ).
lo_alv->get_columns( )->get_column( 'TEST1' )->set_long_text( 'Test1 Header' ).
lo_alv->get_columns( )->set_optimize( abap_true ).
lo_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.
[Fiori] Debug deployed Fiori App
When opening the Dev-Tools for a deployed Fiori App, it will look like this:

You won’t see any controller.js to debug.
What to do? Close the Debugger-Tools and hit CTRL+ALT+SHIFT+P to open the Technical Information Dialog

Check the Checkbox (or choose a specific controller) and reload the app.


It reloads with a new URL parameter and if you open the Dev-Tools, you will now see the controller.js.

Other options to debug or at least to collect some information about your app are the UI5 Diagnostics (hit CTRL+ALT+SHIFT+S) and the UI5 Inspector which is a Browser Addon.
[HR] Infotype – add PBO or PAI logic
There are many ways to add custom logic when processing an Infotype. Here are just a few:
SMOD
PBAS0001
PBAS0002

ZXPADU01 – when an infotype is called
ZXPADU02 – when an action is performed on an infotype
https://regotz.jimdofree.com/abap/dynpro/infotypen-pai-pbo/
BAdI’s
- HRPAD00INFTY (method IN_UPDATE) is called by the old infotype framework (PA30, SAP50UPR)
- HRPAD00INFTYDB (method UPDATE_DB) is called in the decoupled infotype framework
BAdI: HRPAD00INFTY – Verbucher / Infotyp-Pflege


BAdI: HRPAD00INFTYDB – HR: Stammdaten, Infotype DB Update Logik
“The BAdI is called, after the decoupled infotype framework writes the infotype data to the database. This is done during method FLUSH.”
Note: The Infotypes 2000-2999 are not decoupled yet! More here and here.



[HR] Abrechnungsergebnisse lesen
Reports:
RPCALCD0 – Abrechnungsprogramm Deutschland (Name des HR-Formulars lässt sich über T-Code HRFORMS ermitteln)
RPCLSTRD – Anzeige des Clusters RD (Abrechnungsergebnisse Deutschland), Tcode: PC_PAYRESULT
H99_DISPLAY_PAYRESULT – Anzeigen von Abrechnungsergebnissen
H99CWTR0 – Lohnarten-Reporter, Tcode: PC00_M99_CWTR_NO_OC
Abrechnungsergebnistabelle:
Eine sehr schöne Übersicht über die Tabellen: https://l3consulting.de/die-tabellen-im-abrechnungscluster-des-sap-hcm-verstehen/
Die Tabelle RT enthält die Ergebnislohnarten der ausgewählten Abrechnungsperiode. (RT_ = komprimierte Darstellung)
Funktionsbausteine:
HR_GET_PAYROLL_RESULTS – Lesen von Abrechnungsergebnissen für Monats- und Jahresreports
PYXX_READ_PAYROLL_RESULT – Generischer Import von Abrechnungsergebnissen
HRCM_PAYROLL_RESULTS_GET – Abrechnungsdaten einer Person ermitteln
Hinweise zu Bausteinen: https://blog.hr-manager.de/2011/09/abap-abrechnungsergebnisse-lesen-per.html
Logische Datenbank:
Eine weitere Möglichkeit ist die Nutzung der logischen Datenbank PNP. Die Verwendung logischer Datenbanken ist in den meisten anderen Modulen obsolet, im HR Umfeld aber noch stark verbreitet.
*&---------------------------------------------------------------------*
*& Report ZGETPAYROLL
*& Eigenschaften: Selektionsbildvariante 900, HR-Reportklasse PY_DEF.
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZGETPAYROLL.
TABLES: PERNR, PYORGSCREEN, PYTIMESCREEN.
INFOTYPES: 0002.
NODES: PAYROLL TYPE PAYDE_RESULT.
START-OF-SELECTION.
GET PERNR.
RP_PROVIDE_FROM_LAST P0002 SPACE PN-BEGPS PN-ENDPS.
WRITE:/ PERNR-PERNR, P0002-VORNA, P0002-NACHN.
GET PAYROLL.
LOOP AT PAYROLL-INTER-RT INTO DATA(WA_RT).
WRITE:/ WA_RT-LGART, WA_RT-BETRG.
ENDLOOP.
END-OF-SELECTION.
Oder in Kombination mit einem Fuba:
*&---------------------------------------------------------------------*
*& Report ZGETPAYROLL
*& Eigenschaften: HR-Reportklasse __M00001.
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZGETPAYROLL.
TABLES: pernr. "Necessary for get pernr
INFOTYPES: 0001, "Organisatorische Zuord
0002, "Daten zur Person
0006, "Anschrift
0057. "Mitgliedschaften
DATA: l_payroll_result TYPE payat_result OCCURS 0 WITH HEADER LINE.
START-OF-SELECTION.
GET pernr.
rp_provide_from_last p0001 '' pn-begda pn-endda.
CALL FUNCTION 'HR_GET_PAYROLL_RESULTS'
EXPORTING
pernr = pernr-pernr
permo = pn-permo
pabrj = pn-pabrj
pabrp = pn-pabrp
actual = space "X actual, ' ' retro-differences
waers = 'EUR'
TABLES
result_tab = l_payroll_result
EXCEPTIONS
no_results = 0
wrong_structure_of_result_tab = 2
OTHERS = 4.
IF sy-subrc NE 0.
RETURN. "nächste Pernr
ENDIF.
[ABAP] Download internal table as TXT or CSV
" ty_output and tt_output are just dummy types
DATA: l_output_line TYPE ty_output,
l_output_lines TYPE tt_output,
l_csv_output TYPE truxs_t_text_data,
l_txt_output TYPE TABLE OF string,
PARAMETERS: p_alv RADIOBUTTON GROUP rb1 DEFAULT 'X' USER-COMMAND radio,
p_csv RADIOBUTTON GROUP rb1,
p_flcsv TYPE rlgrap-filename DEFAULT 'c:\temp\file.csv',
p_txt RADIOBUTTON GROUP rb1,
p_fltxt TYPE rlgrap-filename DEFAULT 'c:\temp\file.txt'.
" fill table l_output_lines with your data you want to export as txt or csv
IF p_csv = abap_true.
CALL FUNCTION 'SAP_CONVERT_TO_CSV_FORMAT'
TABLES
i_tab_sap_data = l_output_lines
CHANGING
i_tab_converted_data = l_csv_output.
TRY.
cl_gui_frontend_services=>gui_download( EXPORTING filename = CONV #( p_flcsv )
filetype = 'ASC'
CHANGING data_tab = l_csv_output ).
CATCH cx_root INTO DATA(e_text).
MESSAGE e_text->get_text( ) TYPE 'I'.
ENDTRY.
ELSEIF p_txt = abap_true.
LOOP AT l_output_lines INTO l_output_line.
CALL FUNCTION 'SO_STRUCT_TO_CHAR'
EXPORTING
ip_struct = l_output_line
IMPORTING
ep_string = l_string.
APPEND l_string TO l_txt_output.
ENDLOOP.
TRY.
cl_gui_frontend_services=>gui_download( EXPORTING filename = CONV #( p_fltxt )
filetype = 'ASC'
CHANGING data_tab = l_txt_output ).
CATCH cx_root INTO e_text.
MESSAGE e_text->get_text( ) TYPE 'I'.
ENDTRY.
ENDIF.
