SELECT @if_fsbp_const_range=>sign_include AS sign,
@if_fsbp_const_range=>option_equal AS option,
bukrs AS low,
CAST( @space AS CHAR( 4 ) ) AS high
FROM t001
INTO TABLE @DATA(range_of_comp_codes).
cl_demo_output=>display( range_of_comp_codes ).
Got this snippet from George Drakos talk from the ABAPConf 2024. Check his Github.
Die Datenerfassung der Antragsdaten erfolgt im Infotyp: 0700 (Elektronischer Datenaustausch) Subtypen:
DXA1 (A1: Antrag Entsendebescheinigung)
DXAV (A1: Antrag Ausnahmevereinbarung)
Reports zur Erstellung der Meldungen und der Meldedateien:
Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Abrechnungszusatz → A1-Meldeverfahren → Ausgangsmeldungen
Reports zur Verarbeitung der Eingangsmeldungen:
Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Abrechnungszusatz → A1-Meldeverfahren → Eingangsmeldungen
Behördenkommunikation (B2A): Transaktion PB2A
Personal → Personalabrechnung → Europa → Deutschland → Folgeaktivitäten → Periodenunabhängig → Behördenkommunikation (B2A) → B2A-Manager
Hilfreiche Entwicklungsobjekte
Paket: P01S
Reports:
Klassen:
Für mich hilfreich waren folgenden Klassen:
CL_HRPAYDE_A1_NOTIF (Klasse für A1-Meldungen)
CL_HRPAYDE_A1_NOTIF_DISPLAYER (ALV-Ausgabe für A1-Meldungen)
CL_HRPAYDE_A1_ALV_EVNT_HANDLER (Ereignisbehandler für A1-spezifische Ereignisse)
PDFs der A1-Meldungen von Datenbank lesen
*&---------------------------------------------------------------------*
*& Tabellen A1-Meldeverfahren:
*& P01A1_STAT - A1-Verfahren: Verwaltungstabelle
*& P01A1_RAWDATA - A1-Verfahren: Rohdaten einer Meldung
*&---------------------------------------------------------------------*
GET peras.
SELECT * INTO TABLE @DATA(lt_p01a1_stat) FROM p01a1_stat
WHERE pernr = @pernr-pernr
AND mdtyp = '2'
AND status = '23'
AND mzbeg <= @pn-endda
AND mzbeg >= @pn-begda.
LOOP AT lt_p01a1_stat INTO DATA(ls_p01a1_stat).
SELECT SINGLE * INTO @DATA(ls_p01a1_rawdata) FROM p01a1_rawdata
WHERE guid = @ls_p01a1_stat-guid
AND lfdnr = ( SELECT MAX( lfdnr ) FROM p01a1_rawdata WHERE guid = @ls_p01a1_stat-guid ). "höchste lfdnr nehmen
DATA(pdf_xstring) = ls_p01a1_rawdata-rawdata.
ENDLOOP.
By using line_exists you can check if a line exists or not exists, but it is not possible to use other comparison operators. A workaround can be REDUCE in that case.
In the following snippet, we want to check if there is a flight that costs more than $1000,
SELECT * FROM sflight INTO TABLE @DATA(flights).
* Check if flight with price > 1000 exist
IF REDUCE abap_bool( INIT price_gt_1000 = abap_false
FOR line IN flights WHERE ( price > 1000 )
NEXT price_gt_1000 = abap_true ) EQ abap_true.
" flight with price > 1000 exists
ENDIF.
I had to calculate the difference between two times, even if the end time goes beyond the 0 o’clock day limit, e.g. 20:00 to 02:00 should be 6h. I found the following two function modules doing the job:
* Option 1
CALL FUNCTION 'CATS_COMPUTE_HOURS'
EXPORTING
pernr = pernr
date = date
* NO_BREAK_DEDUCTION = ' '
row = row
TABLES
return = return
CHANGING
catshours = catshours
beguz = beguz
enduz = enduz
vtken = vtken.
* Option 2 (I think it's only available on S/4 HANA)
CALL FUNCTION 'CATS_DETERMINE_HOURS'
CHANGING
catshours = catshours
beguz = beguz
enduz = enduz.
This report can be handy, especially since S/4HANA 2023 seems to have restricted the “classic” import way by using TCode CG3Y and CG3Z. See note 1949906, where it is recommended to create a custom report.
*&---------------------------------------------------------------------*
*& Report Z_IMPORT_TRANSPORT_FROM_ZIP
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT z_import_transport_from_zip.
SELECTION-SCREEN BEGIN OF BLOCK bl02 WITH FRAME TITLE TEXT-t02.
PARAMETERS p_lcldir TYPE string LOWER CASE OBLIGATORY DEFAULT 'C:\temp\'.
PARAMETERS p_sapdir TYPE char255 LOWER CASE OBLIGATORY.
SELECTION-SCREEN END OF BLOCK bl02.
SELECTION-SCREEN BEGIN OF BLOCK bl03 WITH FRAME.
PARAMETERS p_import TYPE boolean DEFAULT 'X' AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK bl03.
AT SELECTION-SCREEN OUTPUT.
CALL 'C_SAPGPARAM' ID 'NAME' FIELD 'DIR_TRANS' ID 'VALUE' FIELD p_sapdir.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_lcldir.
DATA lt_files TYPE filetable.
DATA lv_rc TYPE i.
DATA lv_action TYPE i.
TRY.
cl_gui_frontend_services=>file_open_dialog( EXPORTING window_title = 'Import'
default_extension = '.zip'
initial_directory = 'C:\temp\'
multiselection = abap_false
CHANGING file_table = lt_files
rc = lv_rc
user_action = lv_action ).
IF lv_action = cl_gui_frontend_services=>action_ok AND lines( lt_files ) > 0.
p_lcldir = lt_files[ 1 ]-filename.
ENDIF.
CATCH cx_root INTO DATA(e_text).
MESSAGE e_text->get_text( ) TYPE 'I'.
ENDTRY.
START-OF-SELECTION.
DATA lv_zip_size TYPE i.
DATA lt_zip_data TYPE solix_tab.
DATA lv_xstring TYPE xstring.
cl_gui_frontend_services=>gui_upload( EXPORTING filename = p_lcldir
filetype = 'BIN'
IMPORTING filelength = lv_zip_size
CHANGING data_tab = lt_zip_data ).
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = lv_zip_size
IMPORTING
buffer = lv_xstring
TABLES
binary_tab = lt_zip_data.
" write zip content to filesystem
DATA(lo_zipper) = NEW cl_abap_zip( ).
DATA(lt_zip_entries) = lo_zipper->splice( lv_xstring ).
lo_zipper->load( lv_xstring ).
LOOP AT lt_zip_entries INTO DATA(ls_zip_entry).
lo_zipper->get( EXPORTING name = ls_zip_entry-name
IMPORTING content = DATA(lv_data) ).
DATA(lv_file) = COND #( WHEN ls_zip_entry-name(1) = 'K' THEN p_sapdir && '/cofiles/' && ls_zip_entry-name
ELSE p_sapdir && '/data/' && ls_zip_entry-name ).
TRY.
OPEN DATASET lv_file FOR OUTPUT IN BINARY MODE.
TRANSFER lv_data TO lv_file.
CLOSE DATASET lv_file.
CATCH cx_root INTO DATA(e_text).
MESSAGE e_text->get_text( ) TYPE 'E'.
ENDTRY.
ENDLOOP.
" now add transport to stms
DATA lv_ret_code TYPE trretcode.
DATA ls_exception TYPE stmscalert.
DATA lt_logptr TYPE TABLE OF tplogptr.
DATA lt_stdout TYPE TABLE OF tpstdout.
DATA(lv_trkorr) = CONV trkorr( lt_zip_entries[ 1 ]-name+8(3) && 'K' && lt_zip_entries[ 1 ]-name+1(6) ).
DATA(lv_system) = CONV tmssysnam( sy-sysid ).
SELECT SINGLE domnam FROM tmscsys INTO @DATA(lv_transport_domain).
" add transport to queue
CALL FUNCTION 'TMS_MGR_FORWARD_TR_REQUEST'
EXPORTING
iv_request = lv_trkorr
iv_tarcli = sy-mandt
iv_target = lv_system
iv_source = lv_system
iv_tardom = lv_transport_domain
iv_srcdom = lv_transport_domain
IMPORTING
ev_tp_ret_code = lv_ret_code
es_exception = ls_exception
TABLES
tt_stdout = lt_stdout
EXCEPTIONS
OTHERS = 99.
IF sy-subrc <> 0 OR lv_ret_code <> 0.
cl_demo_output=>display( lt_stdout ).
MESSAGE 'Could not add transport to queue' TYPE 'E'.
ENDIF.
" also directly import if checked
IF p_import = abap_true.
CALL FUNCTION 'TMS_MGR_IMPORT_TR_REQUEST'
EXPORTING
iv_system = lv_system
iv_request = lv_trkorr
iv_client = sy-mandt
iv_ignore_cvers = abap_true "ignore invalid component version vector (CVERS)
IMPORTING
ev_tp_ret_code = lv_ret_code
es_exception = ls_exception
TABLES
tt_logptr = lt_logptr
tt_stdout = lt_stdout
EXCEPTIONS
read_config_failed = 1
table_of_requests_is_empty = 2
OTHERS = 3.
IF sy-subrc <> 0 OR lv_ret_code <> 0.
cl_demo_output=>display( lt_stdout ).
MESSAGE 'Could not import transport' TYPE 'E'.
ENDIF.
ENDIF.
MESSAGE 'Transport successfully imported' TYPE 'S'.
If you have connected any workflows to a pernr via BUS1065 (like it is described here), you can receive all related workflows/workitems related to this pernr via the following code:
NEW cl_def_im_com_bsp_workflow( )->if_ex_com_bsp_workflow~read_workitems_for_object( EXPORTING iv_swo_objtype = 'BUS1065'
iv_swo_objkey = CONV #( lv_pernr )
IMPORTING et_workitems = DATA(lt_workitems) ).
LOOP AT lt_workitems ASSIGNING FIELD-SYMBOL(<workitems>).
"If you are only interested in specific workflows, you could filter here
"WHERE wi_rh_task = 'WSxxxxxxxx'
"AND wi_stat = 'STARTED'.
NEW /iwwrk/cl_wf_read_workitem( <workitems>-wi_id )->get_wi_container( IMPORTING et_wi_container = DATA(lt_wi_container) ).
" access container items via lt_wi_container[ element = 'IV_PERNR' ]-value
ENDLOOP.
To attach your own workflow in this overview, you have to add the Task TS51900010 to your workflow and pass over the employee number to the Business Object “Employee” (BUS1065)