We all work agile and scrum now. This leads to new humoristic situations.
Author: saptechnicalguru
Data archiving: handling units
This blog will explain how to archive handling units via object LE_HU. Generic technical setup must have been executed already, and is explained in this blog.
Object LE_HU
Go to transaction SARA and select object LE_HU.
Dependency schedule:
In case you use production planning backflush, you must archive those first. Then material documents, shipment costs (if in use), SD transport (if in use) and deliveries.
Main tables that are archived:
- VEKP (Handling unit header table)
- VEPO (Handling unit item)
Technical programs and OSS notes
Preprocessing program: RHU_AR_ARCHIVABILITY_CHECK
Write program: RHU_AR_WRITE_TO_ARCHIVE
Delete program: RHU_AR_DELETE_FROM_DATABASE
Read from archive: RHU_AR_READ_FROM_ARCHIVE
Reload program: RHU_AR_RELOAD_ARCHIVE
Relevant OSS notes:
Application specific customizing
Archiving object LE_HU has no specific customizing. Retention period is set on the write program screen.
Execution the preprocessing run
In transaction SARA, LE_HU select the preprocessing run:
The run will show you how many can be archived and how many cannot be archived (mainly due to status and preceding documents):
Executing the write run and delete run
In transaction SARA, LE_HU select the write run:
Select your data, save the variant and start the archiving write run.
After the write run is done, check the logs. LE_HU archiving has average speed, but not so high percentage of archiving (about 40 to 90%).
Unfortunately the LE_HU object does not have a Note field to give the archive file a correct name. If you still want to do so, you have to do this in SARA via the management of archiving sessions: select the session and change the description there:
Deletion run is standard by selecting the archive file and starting the deletion run.
Data retrieval
Data retrieval is via program RHU_AR_READ_FROM_ARCHIVE.
Program RSMEMORY
Program RSMEMORY can be used to check current ABAP memory settings.
Start transaction SE38 and key program RSMEMORY and press execute. In higher ABAP versions transaction SMEMORY is available.
Result:
If a user faces a TSV_TNEW_PAGE_ALLOC_FAILED and really needs to process a lot of data only once, you can use program RSMEMORY to temporarily increase the memory. Keep screen shot of old settings. Increase the memory class value in quota dialog settings for Step 1. Also increase abap/head area dia (and the total accordingly). Now press the Copy button to activate. This is per application server. Settings are lost after restart. But it is best to already change back to old settings after the user issue is fixed (by using the screen shot you made before the settings changes).
SAP background
OSS note 177226 – Documentation rsmemory.
SAP help file link.
Data archiving: profit center accounting documents
This blog will explain how to archive profit center accounting documents transports via object EC_PCA_ITM. Generic technical setup must have been executed already, and is explained in this blog.
Object EC_PCA_ITM
Go to transaction SARA and select object EC_PCA_ITM.
Dependency schedule:

This means for profit center accounting archiving that there are no dependent objects.
Main tables that are archived:
- GLPCA (profit center actual line items)
- GLPCP (profit center plan line items)
Technical programs and OSS notes
Write program: EC_PCA_ITM_WRI
Delete program: EC_PCA_ITM_DEL
Read program: RGUGLPCA
Relevant OSS notes:
- 3146990 – EC_PCA_ITM: Error while determining the BOR key when archiving plan data
- 3239597 – PCA Archving: MESSAGE_TYPE_X when executing delete program
Application specific customizing
EC_PCA_ITM has no application specific customization for setting retention periods.
Executing the write run and delete run
In transaction SARA, EC_PCA_ITM select the write run:
Select your data, save the variant and start the archiving write run.
Give the archive session a good name that describes controlling area, company code and year. This is needed for data retrieval later on.
After the write run is done, check the logs. EC_PCA_ITM archiving has high speed, and high percentage of archiving (up to 99%).
Deletion run is standard by selecting the archive file and starting the deletion run.
Data retrieval
Data retrieval is via program RGUGLPCA:
Put in the correct input values and select the right archive files.
The output is a fairly simple list.
Data archiving: SD transport
This blog will explain how to archive SD transports via object SD_VTTK. Generic technical setup must have been executed already, and is explained in this blog.
Object SD_VTTK
Go to transaction SARA and select object SD_VTTK.
Dependency schedule:
In case you use production planning backflush, you must archive those first. Then material documents and shipment costs (if in use).
Main tables that are archived:
- VTTK (shipment header)
- VTTP (shipment item)
Technical programs and OSS notes
Write program: SDVTTKWRS
Delete program: SDVTTKDLS
Reload program: SDVTTKRL
Relevant OSS notes:
Application specific customizing
In the application specific customizing for SD_VTTK you can maintain the document retention time settings:
Executing the write run and delete run
In transaction SARA, SD_VTTK select the write run:
Select your data, save the variant and start the archiving write run.
Give the archive session a good name that describes sales organization/shipment point and year. This is needed for data retrieval later on.
After the write run is done, check the logs. SD_VTTK archiving has average speed, but not so high percentage of archiving (up to 40 to 90%).
Deletion run is standard by selecting the archive file and starting the deletion run.
Data retrieval
Data retrieval is not possible. Only reload via program SDVTTKRL.
Write system log entries from custom ABAP
For some specific requirements (like system monitoring) you might need to write entries into the ABAP system log (transaction SM21).
Preparation
In SE92 (see this blog) create a new message for the system log. It is best to create your own Z message code in stead of re-using standard SAP.
Writing to system log
OSS note 5462 – Writing SysLog entries from within ABAP/4 programs explains 2 methods, for which using function module RSLG_WRITE_SYSLOG_ENTRY is the preferred one.
Program RSLG0014 can be used to test the writing and basis for code re-use:
DWDM: Enjoy demo center
The enjoy controls are old, but still much in use.
If you need to re-use and idea and code, you can use transaction DWDM: the Enjoy Demo Center.
Double clicking program name will show the ABAP code on the right.
Double clicking on the title will give you the output of the example code.
The HTML control as WWW browser can be used to test the internet connectivity from your SAP server to internet.
Some developers might have restrictions on their laptop and use this program to browse....
Reading content data from batch job variants
In quite some cases the basis team is asked: in which batch job variant is this company code XXXX used? Or we need to add another sales organization to all the batch jobs, can you provide us a list with jobs using sales organization YYYY?
Some hints are given in this blog.
But no real solution.
Continue reading for a custom code solution!
Custom program to scan batch job variant content
If you load the program in the next section, create texts so that the start screen looks like this:
First test program on small batch of programs with know variants.
Example search all programs starting with ZA for the variant text US:
Result is list of program and variants with the key word:
Custom program coding
*&---------------------------------------------------------------------*
*& Report ZVARSEARCH
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZVARSEARCH.
* _____________________________________________________________________
*| T A B L E S |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
TABLES: trdir, tadir.
* _____________________________________________________________________
*| T Y P E S |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
TYPES: BEGIN OF ty_source,
line(255) TYPE c,
END OF ty_source.
TYPES: BEGIN OF ty_objname,
obj_name TYPE sobj_name,
END OF ty_objname.
TYPES: BEGIN OF ty_variant,
variant TYPE variant,
END OF ty_variant.
* _____________________________________________________________________
*| I T A B S & W O R K A R E A S |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
DATA: gt_selop TYPE STANDARD TABLE OF vanz,
gt_params TYPE STANDARD TABLE OF vanz,
gt_params_nonv TYPE STANDARD TABLE OF vanz,
gt_selop_nonv TYPE STANDARD TABLE OF vanz,
gs_vanz TYPE vanz,
lv_text TYPE string,
gv_report TYPE vari_reprt,
mv_report TYPE vari_reprt,
gt_variant TYPE STANDARD TABLE OF ty_variant,
gs_variant TYPE ty_variant,
gv_program TYPE syrepid,
gv_subrc TYPE sysubrc,
gt_reports TYPE STANDARD TABLE OF trdir,
gs_reports TYPE trdir,
gt_valuetab TYPE STANDARD TABLE OF rsparams,
gt_objname TYPE STANDARD TABLE OF ty_objname.
FIELD-SYMBOLS:
<fs_vanz> TYPE vanz.
* _____________________________________________________________________
*| S E L E C T I O N - S C R E E N |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
SELECTION-SCREEN BEGIN OF BLOCK aa WITH FRAME.
SELECTION-SCREEN BEGIN OF BLOCK bb WITH FRAME TITLE text-t01.
PARAMETERS: ra_srch RADIOBUTTON GROUP a1
USER-COMMAND tab1 DEFAULT 'X',
ra_srch2 RADIOBUTTON GROUP a1,
ra_wday RADIOBUTTON GROUP a1,
ra_synt RADIOBUTTON GROUP a1,
ch_all AS CHECKBOX MODIF ID a2.
SELECTION-SCREEN END OF BLOCK bb.
SELECT-OPTIONS: so_prog FOR trdir-name.
PARAMETERS: p_string TYPE s_text MODIF ID a1.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN BEGIN OF BLOCK cc WITH FRAME.
PARAMETERS: pa_prog TYPE program,
pa_local AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK cc.
SELECTION-SCREEN END OF BLOCK aa.
* _____________________________________________________________________
*| A T S E L E C T I O N - S C R E E N O U T P U T |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
CASE screen-group1.
WHEN 'A1'.
IF ra_srch IS INITIAL
AND ra_srch2 IS INITIAL.
CLEAR p_string.
screen-input = '0'.
ELSE.
screen-input = '1'.
ENDIF.
WHEN 'A2'.
IF ra_synt = 'X'.
screen-input = '1'.
ELSE.
CLEAR ch_all.
screen-input = '0'.
ENDIF.
ENDCASE.
MODIFY SCREEN.
ENDLOOP.
* _____________________________________________________________________
*| S T A R T - O F - S E L E C T I O N |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
START-OF-SELECTION.
IF ( NOT ra_srch IS INITIAL OR NOT ra_srch2 IS INITIAL )
AND p_string IS INITIAL.
MESSAGE e001(00) WITH 'No string entered'.
ENDIF.
PERFORM select_programs.
PERFORM select_variants.
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*& Form SELECT_PROGRAMS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM select_programs.
DATA: lv_tabix TYPE sytabix,
lv_lines TYPE i.
*-Only executable programs are taken into account
IF ch_all IS INITIAL.
SELECT * FROM trdir
INTO TABLE gt_reports
WHERE name IN so_prog
AND subc = '1'.
*-For syntax checking you can also include other program types
ELSE.
SELECT * FROM trdir
INTO TABLE gt_reports
WHERE name IN so_prog.
ENDIF.
SORT gt_reports BY name.
DESCRIBE TABLE gt_reports LINES lv_lines.
*-check if the user wants to start from a certain program
*-(so skip all preceding programs)
IF NOT pa_prog IS INITIAL.
READ TABLE gt_reports WITH KEY name = pa_prog
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
lv_tabix = sy-tabix + 1.
IF lv_tabix < lv_lines.
*- Delete all preceding reports including the start from report
DELETE gt_reports FROM 1 TO lv_tabix.
ENDIF.
ENDIF.
ENDIF.
IF gt_reports[] IS INITIAL.
MESSAGE s001(00) WITH 'No reports selected'.
WRITE:/ 'No reports selected'.
ENDIF.
ENDFORM. " SELECT_PROGRAMS
*&---------------------------------------------------------------------*
*& Form SELECT_VARIANTS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM select_variants .
DATA: lt_results TYPE STANDARD TABLE OF rsvobs,
lv_found TYPE flag.
REFRESH gt_objname.
CHECK NOT gt_reports[] IS INITIAL.
*-retrieve already all details for quicker reading
IF pa_local = 'X'. "Exclude local programs
SELECT obj_name INTO TABLE gt_objname
FROM tadir
FOR ALL ENTRIES IN gt_reports
WHERE pgmid = 'R3TR'
AND object = 'PROG'
AND obj_name = gt_reports-name.
ELSE. "Include local programs
SELECT obj_name INTO TABLE gt_objname
FROM tadir
FOR ALL ENTRIES IN gt_reports
WHERE pgmid = 'R3TR'
AND object = 'PROG'
AND obj_name = gt_reports-name
AND devclass <> '$TMP'.
ENDIF.
LOOP AT gt_reports INTO gs_reports.
READ TABLE gt_objname
WITH KEY obj_name = gs_reports-name
TRANSPORTING NO FIELDS.
CHECK sy-subrc = 0.
gv_program = gv_report = gs_reports-name.
*=====================================================================*
*- PERFORM A SYNTAX CHECK FOR PROGRAM
*=====================================================================*
*- Get the source code of the report for syntax checking
PERFORM program_syntax_check USING gv_program
CHANGING gv_subrc.
*- Skip programs with syntax errors for further variant checking
IF gv_subrc <> 0.
IF ra_synt = 'X'.
MESSAGE s000(3w) WITH 'SYNTAX ERROR==>' gv_report.
WRITE:/ gv_report,
50 'CONTAINS SYNTAX ERROR'.
ELSE.
CONTINUE.
ENDIF.
ENDIF.
*---------------------------------------------------------------------*
*- Only process variants for select-options search and working days
*---------------------------------------------------------------------*
CHECK ra_srch = 'X' OR ra_srch2 = 'X' OR ra_wday = 'X'.
*- Select variants for a program
*- (exclude the very old ones and also the standard SAP ones)
SELECT variant INTO TABLE gt_variant
FROM varid
WHERE report = gv_report
AND ( edat > 20100101 OR aedat > 20100101 )
AND ( ename <> 'SAP' AND aename <> 'SAP' ).
CHECK NOT gt_variant[] IS INITIAL.
REFRESH lt_results.
*- Process all variants
LOOP AT gt_variant INTO gs_variant.
CLEAR lv_found.
*- Give a message to indicate which program/variant is being checked
*- (comes in handy in case the program cancels during the check as
*- you can then restart this program starting from the object that
*- dumped)
MESSAGE s000(3w) WITH 'Checking' gv_report '-' gs_variant-variant.
CALL FUNCTION 'RS_VARIANT_CONTENTS'
EXPORTING
report = gv_report
variant = gs_variant-variant
no_import = ' '
execute_direct = ''
TABLES
l_params = gt_params
l_params_nonv = gt_params_nonv
l_selop = gt_selop
l_selop_nonv = gt_selop_nonv
valutab = gt_valuetab
EXCEPTIONS
variant_non_existent = 1
variant_obsolete = 2
OTHERS = 3.
CHECK sy-subrc = 0.
*=====================================================================*
*- SEARCH VARIANTS FOR A CERTAIN FIELD VALUE
IF ra_srch = 'X'.
*=====================================================================*
FIND FIRST OCCURRENCE OF p_string
IN TABLE gt_valuetab
IN CHARACTER MODE.
IF sy-subrc = 0.
CONCATENATE 'String' p_string 'found'
INTO lv_text SEPARATED BY space.
MESSAGE s000(3w) WITH 'FOUND:' gv_report
gs_variant-variant lv_text.
WRITE:/ 'FOUND:',
7 gv_report,
50 gs_variant-variant,
80 lv_text.
ENDIF.
*=====================================================================*
*- SEARCH VARIANTS FOR A CERTAIN FIELD NAME OR FIELD DESCRIPTION
ELSEIF ra_srch2 = 'X'.
*=====================================================================*
*- Check select-options field names and descriptions for a
*- certain string
LOOP AT gt_selop ASSIGNING <fs_vanz>.
FIND FIRST OCCURRENCE OF p_string
IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
IF lv_found IS INITIAL.
LOOP AT gt_selop_nonv ASSIGNING <fs_vanz>.
FIND FIRST OCCURRENCE OF p_string
IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found IS INITIAL.
LOOP AT gt_params ASSIGNING <fs_vanz>.
FIND FIRST OCCURRENCE OF p_string
IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found IS INITIAL.
LOOP AT gt_params_nonv ASSIGNING <fs_vanz>.
FIND FIRST OCCURRENCE OF p_string
IN <fs_vanz>-name IN CHARACTER MODE.
IF sy-subrc = 0.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found = 'X'.
CONCATENATE 'String' p_string 'found'
INTO lv_text SEPARATED BY space.
MESSAGE s000(3w) WITH 'FOUND:' gv_report
gs_variant-variant lv_text.
WRITE:/ 'FOUND:',
7 gv_report,
50 gs_variant-variant,
80 lv_text.
ENDIF.
*=====================================================================*
*- SEARCH VARIANTS FOR VARIABLES THAT REQUIRE CALENDAR ENTRY
ELSEIF ra_wday = 'X'.
*=====================================================================*
LOOP AT gt_selop INTO gs_vanz
WHERE vname <> ''.
IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
IF lv_found IS INITIAL.
LOOP AT gt_selop_nonv INTO gs_vanz
WHERE vname <> ''.
IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found IS INITIAL.
LOOP AT gt_params INTO gs_vanz
WHERE vname <> ''.
IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found IS INITIAL.
LOOP AT gt_params_nonv INTO gs_vanz
WHERE vname <> ''.
IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
lv_found ='X'.
EXIT.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_found = 'X'.
MESSAGE s000(3w) WITH 'FOUND:' gv_report gs_variant-variant
'Calendar logic present'.
WRITE:/ 'FOUND:',
8 gv_report,
50 gs_variant-variant,
80 'Calendar logic present'.
ENDIF.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDFORM. " SELECT_VARIANTS
*&---------------------------------------------------------------------*
*& Form PROGRAM_SYNTAX_CHECK
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_LV_SUBRC text
*----------------------------------------------------------------------*
FORM program_syntax_check USING p_program
CHANGING p_subrc.
DATA: lt_source TYPE STANDARD TABLE OF ty_source.
CLEAR p_subrc.
REFRESH lt_source.
READ REPORT gv_program INTO lt_source.
CALL FUNCTION 'RS_SYNTAX_CHECK'
EXPORTING
i_program = p_program
IMPORTING
o_error_subrc = p_subrc
TABLES
i_source = lt_source.
ENDFORM. " PROGRAM_SYNTAX_CHECK
ABAP escape functions
The escape function is used in IT systems to indicate a real value of a character in stead of the control function of the character. Example is the < character which means smaller than, but in HTML is also a control character. For more background read wikipedia.
In ABAP code you sometimes need to set a URL with these characters, or build a HTML text. Then you really need to use these rules.
Documentation of the Esacpe function in ABAP can be found in this URL.
Example is the following code:
cl_demo_output=>display(
escape( val = 'IF a < b.'
format = cl_abap_format=>e_xml_text ) ).
The result will be IF a < b. < is in xml replaced by escape character <.
Demo program
A full list can be found in ABAP program DEMO_ESCAPE. Start the program and select the type you want to check (do select the Show Differences tick box):
Output is now show for the diverse characters:
Find batch jobs with deleted or locked step users
If a batch job step user is locked or deleted, that step will fail. To find batch jobs with deleted or locked step users, start program BTCAUX09:
This will give a full list of jobs that you might want to start analyzing for deletion:
Why clean up? You will most likely find a lot of jobs in Scheduled status that never ran and are planned very long time ago. All batch job related transactions will have to plough through this irrelevant data.
OSS notes
Notes: