https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/ABAP-Development-blog-posts.xml SAP Community - ABAP Development 2026-04-11T23:00:03.644150+00:00 python-feedgen ABAP Development blog posts in SAP Community https://community.sap.com/t5/abap-blog-posts/service-catalog-long-text-mass-upload-ml01-ml02-ml03-editor/ba-p/14356819 Service Catalog - Long text mass upload (ML01/ML02/ML03 Editor) 2026-03-24T10:40:00.160000+01:00 Nikhil_Dwivedi1 https://community.sap.com/t5/user/viewprofilepage/user-id/1640101 <H1 id="toc-hId-1663334960">Upload Long Text for Service Catalog (ML01/ML02/ML03) using ABAP – Complete Guide with Working Solution</H1><H2 id="toc-hId-1595904174">&nbsp;Introduction</H2><P>Uploading <STRONG>Long Text (Lg Text)</STRONG> for Service Catalog in SAP (Transactions <STRONG>ML01 / ML02 / ML03</STRONG>) is not straightforward.</P><P>Even if you use <CODE>SAVE_TEXT</CODE>, you may face issues like:</P><UL><LI><P>Only the <STRONG>first line gets updated</STRONG></P></LI><LI><P>Remaining lines are ignored</P></LI><LI><P>Text appears incorrectly in ML03</P></LI><LI><P>No clear error message</P></LI></UL><P><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span> The root cause is <STRONG>not your code</STRONG>, but a <STRONG>hidden SAP design detail</STRONG> that is rarely documented.</P><P>This blog explains everything end-to-end:</P><UL><LI><P>Data model</P></LI><LI><P>Common mistakes</P></LI><LI><P>Root cause analysis</P></LI><LI><P>Fully working ABAP solution</P></LI></UL><HR /><H2 id="toc-hId-1399390669"><span class="lia-unicode-emoji" title=":warning:">⚠️</span> Prerequisite</H2><P>Before uploading Long Text, ensure:</P><P>✔ Service Catalog already exists<BR />✔ Service lines are present in the system<BR />✔ Entries are available in table <STRONG>ESLZ</STRONG></P><HR /><H3 id="toc-hId-1331959883"><span class="lia-unicode-emoji" title=":magnifying_glass_tilted_left:">🔍</span> Why this is mandatory?</H3><P>Long Text is linked with:</P><UL><LI><P>Service Type (<CODE>LBNUM</CODE>)</P></LI><LI><P>Edition (<CODE>AUSGB</CODE>)</P></LI><LI><P>Line (<CODE>ZEILE</CODE>)</P></LI></UL><P><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span> If <CODE>ZEILE</CODE> does not exist in <STRONG>ESLZ</STRONG>, the text:</P><UL><LI><P>Will not be visible in ML03</P></LI><LI><P>May get stored but not linked</P></LI></UL><HR /><H2 id="toc-hId-1006363659">🧠 Understanding the Data Model</H2><H3 id="toc-hId-938932873"><span class="lia-unicode-emoji" title=":keycap_1:">1️⃣</span> ESLZ Table (Structure Only)</H3><UL><LI><P>Stores service lines</P></LI><LI><P>Contains hierarchy (Block, Sub-lines)</P></LI><LI><P>DOES NOT store long text</P></LI></UL><HR /><H3 id="toc-hId-742419368"><span class="lia-unicode-emoji" title=":keycap_2:">2️⃣</span> Long Text Storage</H3><P>Long Text is stored using SAPscript:</P><P>Table Purpose</P><TABLE><TBODY><TR><TD>STXH</TD><TD>Text Header</TD></TR><TR><TD>STXL</TD><TD>Text Lines</TD></TR></TBODY></TABLE><HR /><H3 id="toc-hId-545905863"><span class="lia-unicode-emoji" title=":fire:">🔥</span> Text Key Mapping</H3><P>Field Value</P><TABLE><TBODY><TR><TD>TDOBJECT</TD><TD>ESLZ</TD></TR><TR><TD>TDID</TD><TD>LTXT</TD></TR><TR><TD>TDNAME</TD><TD>LBNUM + AUSGB + ZEILE</TD></TR></TBODY></TABLE><HR /><H2 id="toc-hId-220309639"><span class="lia-unicode-emoji" title=":bar_chart:">📊</span> Example Scenario</H2><H3 id="toc-hId-152878853">Excel Input</H3><P>Service Edition Line Block TDLINE</P><TABLE><TBODY><TR><TD>001</TD><TD>2004</TD><TD>0000000004</TD><TD>0000000004</TD><TD>Test abc 4</TD></TR><TR><TD>001</TD><TD>2004</TD><TD>0000000005</TD><TD>0000000004</TD><TD>Test abc 5</TD></TR><TR><TD>001</TD><TD>2004</TD><TD>0000000006</TD><TD>0000000004</TD><TD>Test abc 6</TD></TR></TBODY></TABLE><HR /><H3 id="toc-hId--118866021">Expected Output in ML03</H3><PRE><CODE>Line 4 → Test abc 4 Line 5 → Test abc 5 Line 6 → Test abc 6 </CODE></PRE><HR /><H2 id="toc-hId--21976519"><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Common Mistake (Root Cause)</H2><P>Many implementations use:</P><PRE><CODE>GROUP BY lbnumm ausgb blknr.</CODE></PRE><H3 id="toc-hId--511893031">Why this fails?</H3><UL><LI><P>BLKNR = Block level</P></LI><LI><P>SAP stores text at <STRONG>LINE level (ZEILE)</STRONG></P></LI></UL><H3 id="toc-hId--708406536">Result:</H3><P><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Only first text visible<BR /><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Remaining lines ignored<BR /><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Incorrect mapping in ML03</P><HR /><H2 id="toc-hId--611517034"><span class="lia-unicode-emoji" title=":collision:">💥</span> Root Cause Explained</H2><BLOCKQUOTE><P>SAP Service Catalog Long Text is maintained <STRONG>per LINE (ZEILE), not per BLOCK (BLKNR)</STRONG></P></BLOCKQUOTE><HR /><H2 id="toc-hId--808030539"><span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span> Correct Approach</H2><P>✔ Process data <STRONG>line-wise (ZEILE)</STRONG><BR />✔ Generate text key using ZEILE<BR />✔ Avoid grouping by BLKNR</P><HR /><H2 id="toc-hId--1004544044"><span class="lia-unicode-emoji" title=":laptop_computer:">💻</span> Complete Working ABAP Code</H2><P>Below is a complete ABAP report which program to upload Service catalog long text, using Excel file upload.</P><PRE><CODE><!-- StartFragment --><SPAN><SPAN class="">*&amp;---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&amp;&nbsp;Report&nbsp;ZPR_SERVICE_CAT_UPLOAD</SPAN><BR /><SPAN class="">*&amp;---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&amp;</SPAN><BR /><SPAN class="">*&amp;---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">REPORT&nbsp;</SPAN>zpr_service_cat_upload<SPAN class="">.</SPAN><BR /><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;TYPES</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">TYPES</SPAN><SPAN class="">:&nbsp;</SPAN><SPAN class="">BEGIN&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_excel<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbnumm&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>lbnum<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ausgb&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>ausgb<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zeile&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>zeile<SPAN class="">,&nbsp;</SPAN><SPAN class="">"added&nbsp;on&nbsp;23rd&nbsp;march</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sortn&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>sortn<SPAN class="">,&nbsp;</SPAN><SPAN class="">"added&nbsp;on&nbsp;23rd&nbsp;march</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blknr&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>blknr<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meins&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>meins<SPAN class="">,&nbsp;</SPAN><SPAN class="">"added&nbsp;on&nbsp;23rd&nbsp;march</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdformat&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>tline<SPAN class="">-</SPAN>tdformat<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdline&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>tline<SPAN class="">-</SPAN>tdline<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seq&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">i</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">END&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_excel<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>gt_excel&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">STANDARD&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_excel<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gs_excel&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ty_excel<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;RESULT&nbsp;STRUCTURE</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">TYPES</SPAN><SPAN class="">:&nbsp;</SPAN><SPAN class="">BEGIN&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_result<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">icon&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">TYPE&nbsp;</SPAN>icon_d<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbnumm&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>eslz<SPAN class="">-</SPAN>lbnum<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>char10<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">message&nbsp;</SPAN><SPAN class="">TYPE&nbsp;</SPAN>string<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">END&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_result<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>gt_result&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">STANDARD&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_result<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gs_result&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ty_result<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">CONSTANTS</SPAN><SPAN class="">:</SPAN><BR />&nbsp;&nbsp;gc_sheet_exclude&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>string&nbsp;<SPAN class="">VALUE&nbsp;</SPAN><SPAN class="">'Sheet1'</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;SELECTION&nbsp;SCREEN</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">PARAMETERS</SPAN><SPAN class="">:&nbsp;</SPAN>p_file&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>string&nbsp;OBLIGATORY<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;F4&nbsp;HELP</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">AT&nbsp;</SPAN><SPAN class="">SELECTION-SCREEN&nbsp;</SPAN><SPAN class="">ON&nbsp;</SPAN><SPAN class="">VALUE-REQUEST&nbsp;</SPAN><SPAN class="">FOR&nbsp;</SPAN>p_file<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lt_filetab&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>filetable<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_rc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">i</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">METHOD&nbsp;</SPAN>cl_gui_frontend_services<SPAN class="">=&gt;</SPAN>file_open_dialog<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CHANGING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_table&nbsp;<SPAN class="">=&nbsp;</SPAN>lt_filetab<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_rc<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>lv_rc&nbsp;&gt;&nbsp;<SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">READ&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN>lt_filetab&nbsp;<SPAN class="">INTO&nbsp;</SPAN><SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>ls_file<SPAN class="">)&nbsp;</SPAN><SPAN class="">INDEX&nbsp;</SPAN><SPAN class="">1</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;p_file&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_file<SPAN class="">-</SPAN>filename<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;START-OF-SELECTION</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">START-OF-SELECTION</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">PERFORM&nbsp;</SPAN>read_excel<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">PERFORM&nbsp;</SPAN>upload_texts<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;READ&nbsp;EXCEL</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">FORM&nbsp;</SPAN>read_excel<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lo_excel&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN>cl_fdt_xl_spreadsheet<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_xstring&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>xstring<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lt_raw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>solix_tab<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_len&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">i</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_worksheetname&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>string<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lt_worksheets&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>string_table<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lo_data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN><SPAN class="">data</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;Upload&nbsp;file</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'GUI_UPLOAD'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>p_file<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filetype&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'BIN'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filelength&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_len<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TABLES</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_tab&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lt_raw<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'SCMS_BINARY_TO_XSTRING'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input_length&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_len<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">buffer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>lv_xstring<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TABLES</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binary_tab&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lt_raw<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;Create&nbsp;Excel&nbsp;object</SPAN><BR />&nbsp;&nbsp;<SPAN class="">TRY</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CREATE&nbsp;</SPAN>OBJECT&nbsp;lo_excel<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document_name&nbsp;<SPAN class="">=&nbsp;</SPAN>p_file<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xdocument&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_xstring<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CATCH&nbsp;</SPAN>cx_fdt_excel_core<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">MESSAGE&nbsp;</SPAN><SPAN class="">'Error&nbsp;reading&nbsp;Excel&nbsp;file'&nbsp;</SPAN><SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">'E'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDTRY</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;lo_excel<SPAN class="">-&gt;</SPAN>if_fdt_doc_spreadsheet<SPAN class="">~</SPAN>get_worksheet_names<SPAN class="">(</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING&nbsp;</SPAN>worksheet_names&nbsp;<SPAN class="">=&nbsp;</SPAN>lt_worksheets&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DELETE&nbsp;</SPAN>lt_worksheets&nbsp;<SPAN class="">WHERE&nbsp;</SPAN>table_line&nbsp;<SPAN class="">=&nbsp;</SPAN>gc_sheet_exclude<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">READ&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN>lt_worksheets&nbsp;<SPAN class="">INTO&nbsp;</SPAN>lv_worksheetname&nbsp;<SPAN class="">INDEX&nbsp;</SPAN><SPAN class="">1</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;&lt;&gt;&nbsp;<SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">MESSAGE&nbsp;</SPAN><SPAN class="">'Worksheet&nbsp;not&nbsp;found'&nbsp;</SPAN><SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">'E'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;lo_data&nbsp;<SPAN class="">=&nbsp;</SPAN>lo_excel<SPAN class="">-&gt;</SPAN>if_fdt_doc_spreadsheet<SPAN class="">~</SPAN>get_itab_from_worksheet<SPAN class="">(</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;worksheet_name&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_worksheetname&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;Convert&nbsp;to&nbsp;internal&nbsp;table</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'Z_XLS_INTO_ITAB'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">header&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'ZTS_SC_EXCEL'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iv_data_ref&nbsp;<SPAN class="">=&nbsp;</SPAN>lo_data<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hdr_len&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'1'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it_xls_data&nbsp;<SPAN class="">=&nbsp;</SPAN>gt_excel<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>gt_excel&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">INITIAL</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">MESSAGE&nbsp;</SPAN><SPAN class="">'No&nbsp;data&nbsp;found&nbsp;in&nbsp;Excel&nbsp;file'&nbsp;</SPAN><SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">'E'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">ENDFORM</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;UPLOAD&nbsp;TEXTS</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">FORM&nbsp;</SPAN>upload_texts<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lt_grouped&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">SORTED&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>ty_excel<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">WITH&nbsp;</SPAN><SPAN class="">UNIQUE&nbsp;</SPAN><SPAN class="">KEY&nbsp;</SPAN>lbnumm&nbsp;ausgb&nbsp;blknr<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_group&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ty_excel<SPAN class="">.</SPAN><BR /><BR /><BR /><SPAN class="">*&nbsp;Sort&nbsp;properly</SPAN><BR />&nbsp;&nbsp;<SPAN class="">SORT&nbsp;</SPAN>gt_excel&nbsp;<SPAN class="">BY&nbsp;</SPAN>lbnumm&nbsp;ausgb&nbsp;blknr&nbsp;seq<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">**&nbsp;Grouping&nbsp;loop&nbsp;(modern&nbsp;syntax)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;SORT&nbsp;gt_excel&nbsp;BY&nbsp;lbnumm&nbsp;ausgb&nbsp;blknr&nbsp;seq.</SPAN><BR /><BR /><SPAN class="">"commented&nbsp;on&nbsp;23.03</SPAN><BR /><BR /><SPAN class="">*&nbsp;&nbsp;LOOP&nbsp;AT&nbsp;gt_excel&nbsp;INTO&nbsp;DATA(ls_excel)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GROUP&nbsp;BY&nbsp;(&nbsp;lbnumm&nbsp;=&nbsp;ls_excel-lbnumm</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ausgb&nbsp;&nbsp;=&nbsp;ls_excel-ausgb</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zeile&nbsp;&nbsp;=&nbsp;ls_excel-zeile</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blknr&nbsp;&nbsp;=&nbsp;ls_excel-blknr&nbsp;)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASCENDING</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSIGNING&nbsp;FIELD-SYMBOL(&lt;group&gt;).</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA:&nbsp;lt_lines&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE&nbsp;STANDARD&nbsp;TABLE&nbsp;OF&nbsp;tline,</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lt_group_lines&nbsp;TYPE&nbsp;STANDARD&nbsp;TABLE&nbsp;OF&nbsp;ty_excel,</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_header&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE&nbsp;thead.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Build&nbsp;NAME&nbsp;(with&nbsp;ALPHA)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA(lv_lbnumm)&nbsp;=&nbsp;|{&nbsp;&lt;group&gt;-lbnumm&nbsp;ALPHA&nbsp;=&nbsp;IN&nbsp;}|.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA(lv_ausgb)&nbsp;&nbsp;=&nbsp;&lt;group&gt;-ausgb.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA(lv_blknr)&nbsp;&nbsp;=&nbsp;|{&nbsp;&lt;group&gt;-blknr&nbsp;ALPHA&nbsp;=&nbsp;IN&nbsp;}|.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;DATA(lv_name)&nbsp;=&nbsp;lv_lbnumm&nbsp;&amp;&amp;&nbsp;lv_ausgb&nbsp;&amp;&amp;&nbsp;lv_blknr.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA&nbsp;lv_name&nbsp;TYPE&nbsp;thead-tdname.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;lv_name&nbsp;=&nbsp;lv_lbnumm&nbsp;&amp;&amp;&nbsp;lv_ausgb&nbsp;&amp;&amp;&nbsp;lv_blknr.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Step&nbsp;1:&nbsp;Move&nbsp;group&nbsp;data&nbsp;into&nbsp;internal&nbsp;table</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;lt_group_lines&nbsp;=&nbsp;VALUE&nbsp;#(&nbsp;FOR&nbsp;wa&nbsp;IN&nbsp;GROUP&nbsp;&lt;group&gt;&nbsp;(&nbsp;wa&nbsp;)&nbsp;).</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Step&nbsp;2:&nbsp;Sort&nbsp;by&nbsp;SEQ&nbsp;(VERY&nbsp;IMPORTANT)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;SORT&nbsp;lt_group_lines&nbsp;BY&nbsp;seq.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Step&nbsp;3:&nbsp;Prepare&nbsp;ALL&nbsp;lines</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;CLEAR&nbsp;lt_lines.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;LOOP&nbsp;AT&nbsp;lt_group_lines&nbsp;INTO&nbsp;DATA(ls_line_data).</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;ls_line_data-tdline&nbsp;IS&nbsp;NOT&nbsp;INITIAL.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APPEND&nbsp;VALUE&nbsp;tline(</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdformat&nbsp;=&nbsp;ls_line_data-tdformat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&lt;--&nbsp;FIX</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdline&nbsp;&nbsp;&nbsp;=&nbsp;ls_line_data-tdline&nbsp;)&nbsp;TO&nbsp;lt_lines.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDIF.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;ENDLOOP.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Header</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;ls_header&nbsp;=&nbsp;VALUE&nbsp;thead(</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdobject&nbsp;=&nbsp;'ESLZ'</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdname&nbsp;&nbsp;&nbsp;=&nbsp;lv_name</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;'LTXT'</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdspras&nbsp;&nbsp;=&nbsp;sy-langu&nbsp;).</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Save&nbsp;text&nbsp;(overwrite&nbsp;mode)</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;CALL&nbsp;FUNCTION&nbsp;'SAVE_TEXT'</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXPORTING</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;header&nbsp;=&nbsp;ls_header</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;=&nbsp;space</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;=&nbsp;space</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;savemode_direct&nbsp;=&nbsp;'X'</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TABLES</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lines&nbsp;&nbsp;=&nbsp;lt_lines</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTIONS</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OTHERS&nbsp;=&nbsp;1.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**---&nbsp;Result&nbsp;handling</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;DATA(ls_result)&nbsp;=&nbsp;VALUE&nbsp;ty_result(</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbnumm&nbsp;=&nbsp;&lt;group&gt;-lbnumm&nbsp;).</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;sy-subrc&nbsp;&lt;&gt;&nbsp;0.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DATA&nbsp;lv_msg&nbsp;TYPE&nbsp;string.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MESSAGE&nbsp;ID&nbsp;sy-msgid&nbsp;TYPE&nbsp;sy-msgty&nbsp;NUMBER&nbsp;sy-msgno</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INTO&nbsp;lv_msg</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WITH&nbsp;sy-msgv1&nbsp;sy-msgv2&nbsp;sy-msgv3&nbsp;sy-msgv4.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-status&nbsp;&nbsp;=&nbsp;'ERROR'.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-message&nbsp;=&nbsp;lv_msg.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-icon&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;'@5C@'.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;ELSE.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CALL&nbsp;FUNCTION&nbsp;'COMMIT_TEXT'</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXPORTING</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;ls_header-tdobject</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;ls_header-tdname</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;ls_header-tdid</SPAN><BR /><SPAN class="">**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;language&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;sy-langu</SPAN><BR /><SPAN class="">***&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;savemode_direct&nbsp;&nbsp;=&nbsp;abap_true.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-status&nbsp;=&nbsp;'SUCCESS'.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-message&nbsp;=&nbsp;'Text&nbsp;Saved&nbsp;Successfully'.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result-icon&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;'@5B@'.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;ENDIF.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;APPEND&nbsp;ls_result&nbsp;TO&nbsp;gt_result.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;ENDLOOP.</SPAN><BR /><SPAN class="">*</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;COMMIT&nbsp;WORK.</SPAN><BR /><BR /><SPAN class="">"commented&nbsp;on&nbsp;23.03</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lt_lines&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">STANDARD&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>tline<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_header&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>thead<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ty_result<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">LOOP&nbsp;</SPAN><SPAN class="">AT&nbsp;</SPAN>gt_excel&nbsp;<SPAN class="">INTO&nbsp;</SPAN><SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>ls_excel<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Build&nbsp;TEXT&nbsp;NAME&nbsp;using&nbsp;ZEILE&nbsp;(IMPORTANT&nbsp;FIX)</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>lv_lbnumm<SPAN class="">)&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>|{&nbsp;ls_excel<SPAN class="">-</SPAN>lbnumm&nbsp;ALPHA&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">IN&nbsp;</SPAN>}|<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>lv_ausgb<SPAN class="">)&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>ls_excel<SPAN class="">-</SPAN>ausgb<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>lv_zeile<SPAN class="">)&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>|{&nbsp;ls_excel<SPAN class="">-</SPAN>zeile&nbsp;ALPHA&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">IN&nbsp;</SPAN>}|<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>lv_name<SPAN class="">)&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>lv_lbnumm&nbsp;&amp;&amp;&nbsp;lv_ausgb&nbsp;&amp;&amp;&nbsp;lv_zeile<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Prepare&nbsp;text&nbsp;lines&nbsp;(single&nbsp;line&nbsp;per&nbsp;ZEILE)</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>lt_lines<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>ls_excel<SPAN class="">-</SPAN>tdline&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">NOT&nbsp;</SPAN><SPAN class="">INITIAL</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN><SPAN class="">VALUE&nbsp;</SPAN>tline<SPAN class="">(</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdformat&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_excel<SPAN class="">-</SPAN>tdformat<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdline&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_excel<SPAN class="">-</SPAN>tdline&nbsp;<SPAN class="">)&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN>lt_lines<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Header</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_header&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">VALUE&nbsp;</SPAN>thead<SPAN class="">(</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdobject&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'ESLZ'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdname&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_name<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'LTXT'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdspras&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>sy<SPAN class="">-</SPAN>langu&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Clear&nbsp;result</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>ls_result<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN>lbnumm&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_excel<SPAN class="">-</SPAN>lbnumm<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;SAVE&nbsp;TEXT</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'SAVE_TEXT'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">header&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>ls_header<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">insert&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>space<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;savemode_direct&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TABLES</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">lines&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>lt_lines<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXCEPTIONS</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">OTHERS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">1</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Handle&nbsp;result</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;&lt;&gt;&nbsp;<SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lv_msg&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>string<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">MESSAGE&nbsp;</SPAN><SPAN class="">ID&nbsp;</SPAN>sy<SPAN class="">-</SPAN>msgid&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>sy<SPAN class="">-</SPAN>msgty&nbsp;<SPAN class="">NUMBER&nbsp;</SPAN>sy<SPAN class="">-</SPAN>msgno<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">INTO&nbsp;</SPAN>lv_msg<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">WITH&nbsp;</SPAN>sy<SPAN class="">-</SPAN>msgv1&nbsp;sy<SPAN class="">-</SPAN>msgv2&nbsp;sy<SPAN class="">-</SPAN>msgv3&nbsp;sy<SPAN class="">-</SPAN>msgv4<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN>status&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'ERROR'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN><SPAN class="">message&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>lv_msg<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN><SPAN class="">icon&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">'@5C@'</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ELSE</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN>status&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'SUCCESS'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN><SPAN class="">message&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>|Text&nbsp;saved&nbsp;<SPAN class="">for&nbsp;</SPAN><SPAN class="">line&nbsp;</SPAN>{&nbsp;ls_excel<SPAN class="">-</SPAN>zeile&nbsp;}|<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_result<SPAN class="">-</SPAN><SPAN class="">icon&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">'@5B@'</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>ls_result&nbsp;<SPAN class="">TO&nbsp;</SPAN>gt_result<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">ENDLOOP</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---&nbsp;Final&nbsp;commit</SPAN><BR />&nbsp;&nbsp;<SPAN class="">COMMIT&nbsp;</SPAN><SPAN class="">WORK</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">PERFORM&nbsp;</SPAN>display_alv<SPAN class="">.</SPAN><BR /><BR /><BR /><SPAN class="">ENDFORM</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">*&nbsp;DISPLAY&nbsp;ALV</SPAN><BR /><SPAN class="">*---------------------------------------------------------------------*</SPAN><BR /><SPAN class="">FORM&nbsp;</SPAN>display_alv<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lt_fieldcat&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>slis_t_fieldcat_alv<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_fieldcat&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>slis_fieldcat_alv<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_layout&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>slis_layout_alv<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;ICON</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>ls_fieldcat<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>fieldname&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'ICON'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN><SPAN class="">icon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>seltext_m&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'Status'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>ls_fieldcat&nbsp;<SPAN class="">TO&nbsp;</SPAN>lt_fieldcat<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;LBNUM</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>ls_fieldcat<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>fieldname&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'LBNUMM'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>seltext_m&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'Package'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>ls_fieldcat&nbsp;<SPAN class="">TO&nbsp;</SPAN>lt_fieldcat<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;STATUS</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>ls_fieldcat<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>fieldname&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'STATUS'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>seltext_m&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'Status'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>ls_fieldcat&nbsp;<SPAN class="">TO&nbsp;</SPAN>lt_fieldcat<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*&nbsp;MESSAGE</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CLEAR&nbsp;</SPAN>ls_fieldcat<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>fieldname&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'MESSAGE'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;ls_fieldcat<SPAN class="">-</SPAN>seltext_m&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'Message'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>ls_fieldcat&nbsp;<SPAN class="">TO&nbsp;</SPAN>lt_fieldcat<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;ls_layout<SPAN class="">-</SPAN>zebra&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'REUSE_ALV_GRID_DISPLAY'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i_callback_program&nbsp;<SPAN class="">=&nbsp;</SPAN>sy<SPAN class="">-</SPAN>repid<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is_layout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_layout<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it_fieldcat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lt_fieldcat<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TABLES</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_outtab&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>gt_result<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">ENDFORM</SPAN><SPAN class="">.</SPAN></SPAN> <BR /><BR /><BR />Function&nbsp;Module&nbsp;to&nbsp;read&nbsp;Excel&nbsp;sheet&nbsp;into&nbsp;internal&nbsp;table&nbsp;-&nbsp;<BR /><!-- StartFragment --><SPAN><SPAN class="">FUNCTION&nbsp;</SPAN>z_xls_into_itab<SPAN class="">.</SPAN><BR /><SPAN class="">*"----------------------------------------------------------------------</SPAN><BR /><SPAN class="">*"*"Local&nbsp;Interface:</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;IMPORTING</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE(P_FILE)&nbsp;TYPE&nbsp;&nbsp;RLGRAP-FILENAME&nbsp;OPTIONAL</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE(HEADER)&nbsp;TYPE&nbsp;&nbsp;CHAR1&nbsp;DEFAULT&nbsp;'X'</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE(STR)&nbsp;TYPE&nbsp;&nbsp;CHAR30&nbsp;OPTIONAL</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE(IV_DATA_REF)&nbsp;TYPE&nbsp;REF&nbsp;TO&nbsp;&nbsp;DATA&nbsp;OPTIONAL</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE(HDR_LEN)&nbsp;TYPE&nbsp;&nbsp;SYST_TABIX&nbsp;OPTIONAL</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;EXPORTING</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFERENCE(IT_XLS_DATA)&nbsp;TYPE&nbsp;&nbsp;STANDARD&nbsp;TABLE</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;TABLES</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T_FILE&nbsp;STRUCTURE&nbsp;&nbsp;ALSMEX_TABLINE&nbsp;OPTIONAL</SPAN><BR /><SPAN class="">*"----------------------------------------------------------------------</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">TYPE-POOLS</SPAN><SPAN class="">:&nbsp;</SPAN>abap<SPAN class="">,</SPAN>slis<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">FIELD-SYMBOLS</SPAN><SPAN class="">:</SPAN>&lt;dy_table&gt;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">STANDARD&nbsp;</SPAN><SPAN class="">TABLE</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&lt;fs_current_field&gt;<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&lt;wa_str&gt;<SPAN class="">,</SPAN>&lt;wa_temp&gt;<BR />&nbsp;&nbsp;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:</SPAN>new_line&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN><SPAN class="">data</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_line2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN><SPAN class="">data</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;li_fieldcat&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>lvc_t_fcat<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy_table&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN><SPAN class="">data</SPAN><SPAN class="">,</SPAN><BR /><SPAN class="">*&nbsp;t_file&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TYPE&nbsp;STANDARD&nbsp;TABLE&nbsp;OF&nbsp;alsmex_tabline,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wa_file&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>alsmex_tabline<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v_col&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">i</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin_row&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">i</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;zls_alsm_data&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>zts_alsmex_tabline<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">********This&nbsp;will&nbsp;provide&nbsp;Fields&nbsp;in&nbsp;Row&nbsp;format&nbsp;of&nbsp;Structure&nbsp;created(which&nbsp;should&nbsp;be&nbsp;similar&nbsp;to&nbsp;Excel&nbsp;Format).</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'LVC_FIELDCATALOG_MERGE'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i_structure_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>str<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CHANGING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ct_fieldcat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>li_fieldcat<BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXCEPTIONS</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inconsistent_interface&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">1</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program_error&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">2</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">OTHERS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">3</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;<SPAN class="">EQ&nbsp;</SPAN><SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">********This&nbsp;will&nbsp;create&nbsp;internal&nbsp;table&nbsp;which&nbsp;will&nbsp;have&nbsp;fields&nbsp;as&nbsp;per&nbsp;the&nbsp;Excel&nbsp;Format.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">METHOD&nbsp;</SPAN>cl_alv_table_create<SPAN class="">=&gt;</SPAN>create_dynamic_table<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it_fieldcatalog&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>li_fieldcat<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i_length_in_byte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ep_table&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>dy_table<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXCEPTIONS</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generate_subpool_dir_full&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">1</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">OTHERS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN><SPAN class="">2</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;<SPAN class="">EQ&nbsp;</SPAN><SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN>dy_table<SPAN class="">-&gt;</SPAN>*&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;dy_table&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">******V_col&nbsp;will&nbsp;hold&nbsp;the&nbsp;number&nbsp;of&nbsp;Columns&nbsp;inside&nbsp;Excel&nbsp;File&nbsp;which&nbsp;is&nbsp;later&nbsp;passed&nbsp;to&nbsp;ALSM_EXCEL_TO_INTERNAL_TABLE’&nbsp;.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DESCRIBE&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN>li_fieldcat&nbsp;<SPAN class="">LINES&nbsp;</SPAN>v_col<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">LOOP&nbsp;</SPAN><SPAN class="">AT&nbsp;</SPAN>t_file&nbsp;<SPAN class="">INTO&nbsp;</SPAN>wa_file<SPAN class="">.</SPAN><BR /><BR /><SPAN class="">******This&nbsp;Block&nbsp;will&nbsp;create&nbsp;new&nbsp;area&nbsp;to&nbsp;store&nbsp;column&nbsp;wise&nbsp;data.&lt;wa_temp&gt;&nbsp;acts&nbsp;as&nbsp;a&nbsp;work&nbsp;area&nbsp;which&nbsp;is&nbsp;completely&nbsp;blank&nbsp;at&nbsp;start&nbsp;of&nbsp;new&nbsp;row</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">AT&nbsp;</SPAN><SPAN class="">NEW&nbsp;</SPAN>row<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CREATE&nbsp;</SPAN><SPAN class="">DATA&nbsp;</SPAN>new_line2&nbsp;<SPAN class="">LIKE&nbsp;</SPAN><SPAN class="">LINE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>&lt;dy_table&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN>new_line2<SPAN class="">-&gt;</SPAN>*&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;wa_temp&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDAT</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*******for&nbsp;every&nbsp;iteration,&nbsp;wa_file-col&nbsp;will&nbsp;have&nbsp;increment&nbsp;till&nbsp;number&nbsp;of&nbsp;columns&nbsp;in&nbsp;Excel&nbsp;file&nbsp;and&nbsp;then&nbsp;reset&nbsp;to&nbsp;1&nbsp;when&nbsp;there’s&nbsp;new&nbsp;row&nbsp;i.e&nbsp;row&nbsp;=&nbsp;1.&nbsp;(Refer&nbsp;example&nbsp;at&nbsp;end&nbsp;of&nbsp;blog)</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN><SPAN class="">COMPONENT&nbsp;</SPAN>wa_file<SPAN class="">-</SPAN>col&nbsp;<SPAN class="">OF&nbsp;</SPAN><SPAN class="">STRUCTURE&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;fs_current_field&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;<SPAN class="">EQ&nbsp;</SPAN><SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_current_field&gt;&nbsp;<SPAN class="">=&nbsp;</SPAN>wa_file<SPAN class="">-</SPAN><SPAN class="">value</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNASSIGN&nbsp;&lt;fs_current_field&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">*****Finally&nbsp;once&nbsp;all&nbsp;Columns&nbsp;are&nbsp;processed&nbsp;and&nbsp;new&nbsp;row&nbsp;is&nbsp;about&nbsp;to&nbsp;start,&nbsp;append&nbsp;the&nbsp;workarea&nbsp;into&nbsp;Internal&nbsp;table</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">AT&nbsp;</SPAN><SPAN class="">END&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>row<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">TO&nbsp;</SPAN>it_xls_data<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNASSIGN&nbsp;&lt;fs_current_field&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNASSIGN&nbsp;&lt;wa_temp&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDAT</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDLOOP</SPAN><SPAN class="">.</SPAN><BR /><SPAN class="">*ENDIF.</SPAN><BR /><BR /><SPAN class="">***Mapping&nbsp;IV_DATA_REF&nbsp;(Excel&nbsp;data)&nbsp;to&nbsp;Fields</SPAN><BR /><BR /><SPAN class="">*-----------------------FIELD&nbsp;SYMBOLS----------------------------------*</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">FIELD-SYMBOLS</SPAN><SPAN class="">:&nbsp;</SPAN>&lt;lfs_data_tab&gt;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">ANY&nbsp;</SPAN><SPAN class="">TABLE</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_1&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">any</SPAN><SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_2&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">any</SPAN><SPAN class="">.</SPAN><BR /><SPAN class="">*----------------------------------------------------------------------*</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;hdr_len&nbsp;<SPAN class="">=&nbsp;</SPAN>COND&nbsp;#<SPAN class="">(&nbsp;</SPAN><SPAN class="">WHEN&nbsp;</SPAN>hdr_len&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">INITIAL&nbsp;</SPAN>THEN&nbsp;<SPAN class="">1&nbsp;</SPAN><SPAN class="">ELSE&nbsp;</SPAN>hdr_len&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN>iv_data_ref<SPAN class="">-&gt;</SPAN>*&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;lfs_data_tab&gt;<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>&lt;lfs_data_tab&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN>&lt;dy_table&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">LOOP&nbsp;</SPAN><SPAN class="">AT&nbsp;</SPAN>&lt;lfs_data_tab&gt;&nbsp;<SPAN class="">ASSIGNING&nbsp;</SPAN><SPAN class="">FIELD</SPAN><SPAN class="">-</SPAN><SPAN class="">SYMBOL</SPAN><SPAN class="">(</SPAN>&lt;lfs_data&gt;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>tabix&nbsp;<SPAN class="">LE&nbsp;</SPAN>hdr_len<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CONTINUE</SPAN><SPAN class="">.&nbsp;&nbsp;</SPAN><SPAN class="">"Skip&nbsp;line&nbsp;1</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CREATE&nbsp;</SPAN><SPAN class="">DATA&nbsp;</SPAN>new_line2&nbsp;<SPAN class="">LIKE&nbsp;</SPAN><SPAN class="">LINE&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN>&lt;dy_table&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN>new_line2<SPAN class="">-&gt;</SPAN>*&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;wa_temp&gt;<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DO&nbsp;</SPAN><SPAN class="">250&nbsp;</SPAN><SPAN class="">TIMES</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN><SPAN class="">COMPONENT&nbsp;</SPAN>sy<SPAN class="">-</SPAN><SPAN class="">index&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN><SPAN class="">STRUCTURE&nbsp;</SPAN>&lt;lfs_data&gt;&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;fs_1&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ASSIGN&nbsp;</SPAN><SPAN class="">COMPONENT&nbsp;</SPAN>sy<SPAN class="">-</SPAN><SPAN class="">index&nbsp;</SPAN><SPAN class="">OF&nbsp;</SPAN><SPAN class="">STRUCTURE&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">TO&nbsp;</SPAN>&lt;fs_2&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">READ&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN>li_fieldcat&nbsp;<SPAN class="">INTO&nbsp;</SPAN><SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>fs_fieldcat<SPAN class="">)&nbsp;</SPAN><SPAN class="">INDEX&nbsp;</SPAN>sy<SPAN class="">-</SPAN><SPAN class="">index&nbsp;</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">INITIAL&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN>fs_fieldcat<SPAN class="">-</SPAN>datatype&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'DATS'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>&lt;fs_1&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN>&lt;fs_2&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN><SPAN class="">strlen</SPAN><SPAN class="">(&nbsp;</SPAN>&lt;fs_1&gt;&nbsp;<SPAN class="">)&nbsp;</SPAN><SPAN class="">EQ&nbsp;</SPAN><SPAN class="">10&nbsp;</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">(</SPAN>lv_date<SPAN class="">)&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>|{&nbsp;&lt;fs_1&gt;<SPAN class="">(</SPAN><SPAN class="">4</SPAN><SPAN class="">)&nbsp;</SPAN>}{&nbsp;&lt;fs_1&gt;+5<SPAN class="">(</SPAN><SPAN class="">2</SPAN><SPAN class="">)&nbsp;</SPAN>}{&nbsp;&lt;fs_1&gt;+8<SPAN class="">(</SPAN><SPAN class="">2</SPAN><SPAN class="">)&nbsp;</SPAN>}|&nbsp;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CONDENSE&nbsp;</SPAN>lv_date<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_2&gt;&nbsp;<SPAN class="">=&nbsp;</SPAN>lv_date<SPAN class="">.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_2&gt;&nbsp;=&nbsp;&lt;fs_1&gt;.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNASSIGN<SPAN class="">:&nbsp;</SPAN>&lt;fs_1&gt;<SPAN class="">,&nbsp;</SPAN>&lt;fs_2&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CLEAR</SPAN><SPAN class="">:&nbsp;</SPAN>lv_date<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ELSE</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>&lt;fs_1&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN>&lt;fs_2&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;fs_2&gt;&nbsp;<SPAN class="">=&nbsp;</SPAN>&lt;fs_1&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNASSIGN<SPAN class="">:&nbsp;</SPAN>&lt;fs_1&gt;<SPAN class="">,&nbsp;</SPAN>&lt;fs_2&gt;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDDO</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">ASSIGNED&nbsp;</SPAN><SPAN class="">AND&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">NOT&nbsp;</SPAN><SPAN class="">INITIAL</SPAN><SPAN class="">.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVE-CORRESPONDING&nbsp;&lt;wa_temp&gt;&nbsp;TO&nbsp;it_xls_data.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">APPEND&nbsp;</SPAN>&lt;wa_temp&gt;&nbsp;<SPAN class="">TO&nbsp;</SPAN>it_xls_data<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDLOOP</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">ENDFUNCTION</SPAN><SPAN class="">.</SPAN></SPAN> </CODE></PRE><HR /><H2 id="toc-hId--1201057549"><span class="lia-unicode-emoji" title=":warning:">⚠️</span> Important Points to Remember</H2><UL><LI><P><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Do NOT use BLKNR for text key</P></LI><LI><P><span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span> Always use ZEILE</P></LI><LI><P><span class="lia-unicode-emoji" title=":cross_mark:">❌</span> Avoid INSERT = 'X'</P></LI><LI><P><span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span> Use INSERT = SPACE for overwrite</P></LI><LI><P><span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span> Ensure ESLZ entries exist</P></LI></UL><HR /><H2 id="toc-hId--1397571054">🧪 Debug Tip</H2><P>Use function module <CODE>READ_TEXT</CODE>:</P><PRE><CODE>OBJECT = 'ESLZ' ID = 'LTXT' NAME = '001200400000000004'</CODE></PRE><P><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span> Helps verify actual stored text</P><HR /><H2 id="toc-hId--1594084559">Final Result</H2><P>✔ All lines updated correctly<BR />✔ Correct mapping in ML03<BR />✔ No missing or overwritten data</P><HR /><H2 id="toc-hId--1622414373">&nbsp;Conclusion</H2><P>Uploading Service Catalog Long Text becomes easy once you understand:</P><UL><LI><P>SAP stores text per <STRONG>LINE (ZEILE)</STRONG></P></LI><LI><P>Not per <STRONG>BLOCK (BLKNR)</STRONG></P></LI><LI><P>Correct text key is the key to success</P></LI></UL><HR /><H2 id="toc-hId--1818927878"><span class="lia-unicode-emoji" title=":light_bulb:">💡</span> Key Takeaway</H2><BLOCKQUOTE><P>If your long text upload is not working — you are most likely using the wrong key.</P></BLOCKQUOTE><HR /><H2 id="toc-hId--2015441383"><span class="lia-unicode-emoji" title=":raising_hands:">🙌</span> Closing Note</H2><P>This is a common issue with no clear documentation.<BR />Hope this blog saves you hours of debugging.</P><P>Feel free to share your feedback or improvements <span class="lia-unicode-emoji" title=":rocket:">🚀</span></P> 2026-03-24T10:40:00.160000+01:00 https://community.sap.com/t5/supply-chain-management-blog-posts-by-members/create-delete-and-updating-of-packing-specification-packspec-through-upload/ba-p/14353253 Create, Delete and Updating of Packing Specification(PACKSPEC) through Upload Program Report 2026-03-25T11:07:59.250000+01:00 Ramanathansp1 https://community.sap.com/t5/user/viewprofilepage/user-id/2029195 <H2 id="toc-hId-1792322658">Introduction:</H2><P>Maintaining of Packing Specification(Minimum Order Quantity and Target Quantity) for every Material-Plant combination in Service Parts Planning(SPP) system is a crucial step. Usually we do that through Standard T-Code <STRONG>/SCWM/IPU</STRONG>&nbsp;through upload file.</P><P>Instead to improve user experience and simplify the process of uploading, we created an Upload Report Program.</P><H2 id="toc-hId-1595809153"><STRONG>Body:</STRONG></H2><H5 id="toc-hId-1786543805"><STRONG>Development Completed on April 4 , 2025</STRONG></H5><P>Usually, creating, deleting or updating Packspec in T-Code <STRONG>/SCWM/PACKSPEC&nbsp;</STRONG>is a time-consuming process and requires lot of manual efforts to change every packspec directly in the standard screen.</P><P>This can also be done in T-Code <STRONG>/SCWM/IPU</STRONG> using upload template, but that is not user-friendly which requires us to download standard template of more than 100 columns and wants us to edit each and every column and upload. This is quite difficult.</P><P>It will also create a new packspec every time in the system, which will also increase the count of No. of Packspec in system, and which is also not consolidated with respect to Minimum Quantity-Target Quantity or plant-material combo. This makes us to go for custom upload program which is quite efficient in analyzing the Minimum Quantity-Target Quantity, Plant-material combination and decides to craete/update packspec based on user input.</P><P>Our Requirement is to reduce the manual intervention of changing the packspec directly in standard screen or reduce the complexity structure of upload file, instead we can have an upload program which does the Create, Update or Delete processes and provide results of the progress in SLG1 log and also as ALV report for end-users.</P><H5 id="toc-hId-1590030300">General Overview about Packing Specification:</H5><P>One Packspec number consists of many condition records. Each Condition record represents one product and one location.&nbsp;</P><P>Business users usually maintains set of material-plant combo under one specific packspec number with MOQ(Minimum Order Quantity)(Minimum Quantity for Supplier - SAP system identification name) and UOQ(Unit Order Quantity)( Target Quantity&nbsp;- SAP system identification name).</P><P>They will also be changing this from time-to-time as per business changes.</P><H5 id="toc-hId-1393516795">Detailed Overview about our Report Prorgam:</H5><P>Requirement consists of 2 mode namely Manual Mode and Full Mode.</P><OL><LI>Manual Mode is to change only the MOQ and UOQ of the packspec number, instead of keeping hands on the condition records. Suppose if business wants to change MOQ. UOQ from 2,3 to 6,2 respectively for all the same set of mat-loc combo present in the packspec number, they can use this manual mode to change only the MOQ and UOQ.</LI><LI>Full Mode will consume upload file as input. Upload Template: <TABLE width="556"><TBODY><TR><TD width="170">Material</TD><TD width="78">Plant</TD><TD width="104">DEPL/DRP</TD><TD width="68">MOQ</TD><TD width="68">UOQ</TD><TD width="68">Mode A/D</TD></TR></TBODY></TABLE></LI><LI>From inputs from this file, it will check mode first as A/D.</LI><LI>Based on that, it checks if the material-loc combo is present under any other packspec number, if yes, program will delete existing condition record and create a new one with given MOQ and UOQ.</LI><LI>Above is example of one scenario, like this it should work for every possible scenario.</LI><LI>Delete a packspec , if suppose the last condition record in packspec is requested to be deleted.</LI><LI>Create a new packspec if a new set of MOQ-UOQ is requested n upload file.</LI><LI>Add one more condition record, if the requested MOQ-UOQ is already present in System.</LI></OL><H5 id="toc-hId-1197003290">Arriving at Solution:</H5><OL><LI>We need to debug the standard T-code <STRONG>/SCWM/IPU</STRONG> to find all the standard FM's used to create, update and delete <STRONG>Packspec&nbsp;</STRONG>. FM's used to create, change, delete <STRONG>CONDITION RECORD </STRONG>is also required.</LI><LI>Function Modules found:<UL class="lia-list-style-type-square"><LI><STRONG>‘/SCWM/API_PACKSPEC_READ’ - </STRONG>To read the existing packspec details</LI><LI><STRONG>'/SCWM/API_PACKSPEC_CREATE' - </STRONG>To create a new Packspec</LI><LI><STRONG>'/SCWM/API_PACKSPEC_2ND_VERSION' - </STRONG>To create 2nd version of packspec (i.e) make it inactive, add required condition records.</LI><LI><STRONG>'/SCWM/API_PACKSPEC_CHANGE' - </STRONG>To change the MOQ and UOQ of the packspec</LI><LI><STRONG>'/SCWM/API_PACKSPEC_ACTIVATE' - </STRONG>To activate the inactive packspec.</LI><LI><STRONG>'/SCWM/API_PACKSPEC_DELETE' - </STRONG>To Delete the whole packspec</LI><LI><STRONG>'/SCWM/API_CONDITION_REPLICATE' - </STRONG>To create only one condition record within pakspec</LI><LI><STRONG>'/SCWM/PS_DELETE_CONDTECH' - </STRONG>To delete only condition record, if last condition record, call packspec delete FM also.</LI><LI><STRONG>'/SAPCND/MNT_SAVE_OW' -&nbsp;</STRONG>After deleting the condition record, call this FM to make the deletion process complete...as this is the process followed in standard process for successful deletion.</LI><LI><STRONG>'OWN_LOGICAL_SYSTEM_GET' -&nbsp;</STRONG>To get the logical system number.</LI></UL></LI><LI>Tables used:<UL class="lia-list-style-type-square"><LI><STRONG>'/1CN/CPSCUS_SPP' -&nbsp;</STRONG>To get packspec details of Deployment Packspec.</LI><LI>'<STRONG>/1CN/CPSCUS_PRPL</STRONG> ' -&nbsp;To get packspec details of DRP Packspec.</LI><LI><STRONG>'/SCWM/PNPAKH' </STRONG>- Pack Spec Header(ippe node)</LI><LI><STRONG>'PALTID'</STRONG> -&nbsp;iPPE Alternative: Time-Independent ID and Attributes</LI><LI><SPAN><STRONG>'/SCWM/PAPAK'</STRONG> -&nbsp;packaging specification level (ippe alternative)</SPAN></LI></UL></LI><LI>We created a report named <STRONG>"ZSPPR_PACKSPEC_UPLOAD"</STRONG> with selection screen to run the program and a backend global class named <STRONG>"ZCL_PS_MASTER"</STRONG> to support the required logics needed.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ZSPPR_PACKSPEC_UPLOAD" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/385949i194ADE578A00A061/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_0-1773905239251.png" alt="ZSPPR_PACKSPEC_UPLOAD" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">ZSPPR_PACKSPEC_UPLOAD</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ZCL_PS_MASTER global class" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/385950i5803F7DC7B6AE0D7/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_1-1773905271461.png" alt="ZCL_PS_MASTER global class" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">ZCL_PS_MASTER global class</span></span></LI><LI>Report consists of Top declarations, Selection screen logics including download the template of upload file, Modification ID to differentiate between manual and full mode , Program flow with object for <STRONG>ZCL_PS_MASTER</STRONG> and flow logic and forms with different set of operations involved like change_moq_uoq, upload_data_from excel_to_itab, data_validation, refresh_depl_table,&nbsp;<!-- StartFragment --><SPAN>refresh_drp_table, add_mode, delete_mode, Write_log, calculate_pass_fail records for summary, display manual ALV and display Full ALV output as result.</SPAN></LI><LI><SPAN>Importing data from Excel to ITAB can be done using Standard FM like CL_GUI_FRONTEND_SERVICES=&gt;GUI_UPLOAD, but this method has errors of terminating the whole SAP GUI session while trying to close the opened Excel file by our program.</SPAN></LI><LI><SPAN>To resolve this we came up with solution of importing set of custom classes&nbsp;<STRONG>‘ZCL_EXCEL_READER_2007' </STRONG>into a separate package. This is available in abap2xlsx github repository.&nbsp;<A title="ABAP2XLSX GITHUB repository" href="https://github.com/abap2xlsx/abap2xlsx" target="_blank" rel="noopener nofollow noreferrer">GitHub - abap2xlsx/abap2xlsx: Generate your professional Excel spreadsheet from ABAP · GitHub</A>&nbsp;</SPAN></LI><LI><SPAN>With help of <STRONG>ABAPGIT Standalone program </STRONG>, we were able to add this set of classes into a new package.&nbsp;&nbsp;</SPAN><A title="Procedure to install ABAPGIT Standalone program" href="https://docs.abapgit.org/user-guide/getting-started/install.html" target="_blank" rel="noopener nofollow noreferrer">Installation | abapGit Docs</A>&nbsp;</LI><LI><SPAN>Using method <STRONG>GET_CELL</STRONG> of class&nbsp;<STRONG>‘ZCL_EXCEL_READER_2007' </STRONG>, we will get all the data in excel to ITAB, without&nbsp;popping up of Excel GUI explicitly, avoiding unwanted termination of SAP GUI.</SPAN></LI><LI><SPAN>Once these classes are installed, we can make use multiple times in our future upload programs.</SPAN></LI><LI><SPAN>ALV display is enhanced with colored outputs with <STRONG>green/red</STRONG> for users to identify the error records easily.</SPAN></LI><LI>The below logic is used to identify that given line of Packspec comes under which condition of Add/Delete Packspec.<UL class="lia-list-style-type-circle"><LI><STRONG>[MODE - A]</STRONG></LI><LI>IF&nbsp; MOQ-UOQ from excel is present in system.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF MAT-LOC from excel is in the same MOQ-UOQ from EXCEL.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Throw ERROR"Same packspec combination already exists.".</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSEIF (Condition Record is present in system in another MOQ-UOQ).</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delete that Condition Record from existing packspec, create new condition record under given MOQ-UOQ.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Add the MAT-LOC to the given packspec.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF.</LI><LI>ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF Condition Record is present in system.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delete that Condition Record from existing packspec, create a new PACKSPEC.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Create a new PACKSPEC.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</LI><LI>ENDIF.</LI><LI><STRONG>[MODE - D].</STRONG></LI><LI>IF MOQ-EOQ from excel is present in system.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF MAT-LOC from excel is in the same MOQ-EOQ from EXCEL.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF No. of Condition Records = 1</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delete the PACKSPEC.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Delete the Condition Record from PACKSPEC.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Condition record is not under the given MOQ-UOQ.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDIF.</LI><LI>ELSE.</LI><LI>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Packspec(MOQ-UOQ) does not exist in system-THROW error.</LI><LI>ENDIF.</LI></UL></LI><LI>Technical Mindmap for the program flow:</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_4-1773909482015.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386010i06F82A6F207F07F3/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_4-1773909482015.png" alt="Ramanathansp1_4-1773909482015.png" /></span></LI><LI>&nbsp;Screenshots of Manual Mode Test run ALV, Real run ALV and SLG1 log output.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Test Run ALV Output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386073iA990D24D0FAA893C/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_5-1773913438840.png" alt="Test Run ALV Output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Test Run ALV Output</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Real Run ALV Output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386074i29E2DA791CE0E199/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_6-1773913459267.png" alt="Real Run ALV Output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Real Run ALV Output</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Real Run SLG1 log Output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386077i2A16A0B8D5C427BB/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_7-1773913570502.png" alt="Real Run SLG1 log Output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Real Run SLG1 log Output</span></span><P>Screenshots of Full mode Test run ALV, Real run ALV and SLG1 log output.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Test Run ALV Output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386081iC9BB599F34A75286/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_8-1773913699705.png" alt="Test Run ALV Output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Test Run ALV Output</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Real Run ALV Output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386082i772E8052F0DC50FB/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_9-1773913705425.png" alt="Real Run ALV Output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Real Run ALV Output</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Real Run SLG1 Log output" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386083iF6966FFE37410D31/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_10-1773913712703.png" alt="Real Run SLG1 Log output" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Real Run SLG1 Log output</span></span><P>Validation check results Screenshot:</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_11-1773914181402.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386090iC4FD3E4F0F936A69/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_11-1773914181402.png" alt="Ramanathansp1_11-1773914181402.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_12-1773914193705.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386091i9DEEA4F0EB6F31CB/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_12-1773914193705.png" alt="Ramanathansp1_12-1773914193705.png" /></span></LI><LI><SPAN>Difficult part is to find the relationship between the tables , where the condition number is getting stored.</SPAN></LI><LI><SPAN>While debugging, the condition record actually gets saved after another FM call of MNT_SAVE_OW, but to find that exact FM took really more time. </SPAN></LI><LI><SPAN>Faced lot of difficulties in DB storage malfunction due to continuous execution of FM's, so found solution with COMMIT WORK and Wait upto 2 seconds. This resolved the DB overflow issue.</SPAN></LI><LI><SPAN>Learned how to stop debugger exactly at CALL FUNCTION points while executing a t-code.&nbsp;</SPAN></LI><LI><SPAN><SPAN>You can create SQVI query like below for your convenience at the time of development for testing purpose and data-validation!</SPAN></SPAN></LI><LI><SPAN><SPAN>&nbsp;</SPAN></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SQVI query for Deployment packspec" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386122iAC7BF2F90982527E/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_19-1773916627205.png" alt="SQVI query for Deployment packspec" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SQVI query for Deployment packspec</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SQVI query for DRP packspec" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386120i6304D2ABD7283193/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_18-1773916557709.png" alt="SQVI query for DRP packspec" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SQVI query for DRP packspec</span></span></LI></OL><H2 id="toc-hId-613241628">Conclusion:</H2><P>We can create upload reports in this way consisting of Minimum and Target Quantity with Plant-Location Combination with mode A/D. We can modify this according to business use-cases and include /exclude columns in upload file. We've kept changing parameters in TVARVC table and hard-coded the constant parameters.</P><P>This was developed when I had 8-9 months of experience, excuse me for best coding practices.&nbsp;Attached complete code for your reference!&nbsp;Please feel free to post your comments and message me for any support regarding this!&nbsp;Hope this helps someone! <span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></P> 2026-03-25T11:07:59.250000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/bp-extension-search-by-email-in-ecc-6-0/ba-p/14358191 BP Extension - Search By Email in ECC 6.0 2026-03-25T18:50:42.904000+01:00 jayesh_mudaliar https://community.sap.com/t5/user/viewprofilepage/user-id/230182 <P><SPAN>The Client was having a legacy system where they can search the for particular Vendor if its created or not based on email ID. So moving forward they came up with requirement to centralize the Vendor Management System by migrating all things into ECC.</SPAN></P><P><SPAN>The first requirement came to make BP screen as it was in legacy system where user can search for Partner numbers created in system based on Email Id provided. I went through many SAP notes and found multiple approaches.</SPAN></P><P><SPAN>Approach</SPAN></P><UL><LI><SPAN>SPRO config – Search Criteria</SPAN></LI></UL><pre class="lia-code-sample language-abap"><code>SAP Customizing Implementation Guide → Logistics - General → Cross-Application Components → SAP Business Partner → Business Partner Search → Define Search Criteria for Business Partner</code></pre><P><SPAN><BR /><STRONG><BR />OR<BR /><BR />SAP Customizing Implementation Guide</STRONG> → <STRONG>Logistics - General</STRONG> → <STRONG>Cross-Application Components</STRONG> → <STRONG>SAP Business Partner</STRONG> → <STRONG>Business Partner Search</STRONG> → <STRONG>Basic Setting </STRONG>→ <STRONG>Search </STRONG>→ <STRONG>Define Search Views<BR /><BR /><EM>Note: These will only work if the BP Search Framework is fully active</EM><BR /><BR /></STRONG></SPAN></P><UL><LI><SPAN>BUS config<BR /><BR /></SPAN></LI><LI><SPAN>LOCA_CUST</SPAN></LI></UL><P><SPAN>The above 2 options didn’t worked due to lower SAP version. So the only option was to explore LOCA_CUST.<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_0-1774459749276.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388889i0FF34121E4CF0F03/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_0-1774459749276.png" alt="jayesh_mudaliar_0-1774459749276.png" /></span></P><P><SPAN>Here is the details of all technical objects created and mapping to LOCA_CUST.</SPAN></P><OL><LI><SPAN>Create a Database View (SE11)<BR />Since email addresses live in table ADR6, we need a view that joins the BP to its email.<BR />&nbsp;Tables &amp; Joins:<BR />&nbsp;BUT000 (Partner) joined to BUT020 (BP/Address Link) on PARTNER = PARTNER.<BR />&nbsp;BUT020 joined to ADR6 (Email) on ADDRNUMBER = ADDRNUMBER.</SPAN><SPAN><SPAN><BR /></SPAN></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_1-1774459876962.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388890iCE1A9C8F6F7598C3/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_1-1774459876962.png" alt="jayesh_mudaliar_1-1774459876962.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_2-1774459885473.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388891iC76E83F65CD6DD07/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_2-1774459885473.png" alt="jayesh_mudaliar_2-1774459885473.png" /></span><P>&nbsp;</P></LI><LI>Create an Elementary Search Help<BR />Once the view is active, create the search help that the BP transaction will actually display.<BR />SE11 -&gt; Search Help<BR />&nbsp;Selection Method: Enter the view you just created (ZBP_EMAIL_SEARCH).<BR />&nbsp;Search Help Exit: Use F4UT_OPTIMIZE_COLWIDTH (optional, for better UI).<BR />&nbsp;Parameters:<BR />&nbsp;SMTP_ADDR: Mark as IMP (Import) and EXP (Export). LPos = 1, SPos = 1.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_3-1774459910103.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388892i43579B1F47019547/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_3-1774459910103.png" alt="jayesh_mudaliar_3-1774459910103.png" /></span><BR /><BR /></LI><LI><SPAN><SPAN>Append to the Collective Search Help<BR />Now you must tell the BP transaction to include your new "Email" tab in the locator.<BR />Open Collective Search Help BUPA_ALL<BR />Go to the Included Search Helps tab.<BR />Click the Append Search Help button (F5).<BR />Create a new Append . In the "Included Search Helps" of your append, add your elementary search help<BR /></SPAN></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_4-1774459948462.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388893iD40C72BEE90AF74D/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_4-1774459948462.png" alt="jayesh_mudaliar_4-1774459948462.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_5-1774459957263.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388894i97B0464B48CD7880/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_5-1774459957263.png" alt="jayesh_mudaliar_5-1774459957263.png" /></span><P>Click Parameter Assignment to map the PARTNER field from your search help to the collective search help.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_6-1774459974224.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388895i0958416895A11952/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_6-1774459974224.png" alt="jayesh_mudaliar_6-1774459974224.png" /></span><SPAN><BR /><BR /></SPAN></LI><LI>&nbsp;Verification<BR />After activating everything:<BR />Run transaction BP.<BR />In the Locator (left-hand side), click the "Find By" dropdown.<BR />You should now see your new entry ( with the Z name).<BR /><STRONG><EM><BR />NOTE: However if you click on the new field it will throw error “Program name and Screen are not configured”</EM></STRONG>&nbsp;<BR /><BR /></LI><LI>&nbsp;Pass the value of email field in Standard SAP flow of BP transaction<BR />Create Append structure in BUS_JOEL_SEARCH. SE11 -&gt;&nbsp; BUS_JOEL_SEARCH - &gt;Append Structure(F5)<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_7-1774460019928.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388896i0078E0DFFB489A57/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_7-1774460019928.png" alt="jayesh_mudaliar_7-1774460019928.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_8-1774460025023.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388897i019F8EF6DB23893C/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_8-1774460025023.png" alt="jayesh_mudaliar_8-1774460025023.png" /></span><BR /><BR /></LI><LI>Here comes the Important Step for mapping to SAP hook using ABAP code. This FM will capture the data of new field and integrate it into the standard BP process for this we need to use the OOPS concept and include some standard processing code from LBUPA_DIALOG_SEARCHF02 and LBUS_LOCATORO01.</LI><LI>Create a Function Group. SE37-&gt; Goto-&gt; Function Group -&gt; Create Group .<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_9-1774460080779.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388898i7AF47B98839040D9/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_9-1774460080779.png" alt="jayesh_mudaliar_9-1774460080779.png" /></span><BR /><BR /></LI><LI>Click on Master Program of function group and define a local class in TOP include along with the Global variable for fetching the value of email in GV_EMAIL.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_10-1774460123529.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388899i5D29802A43103C0B/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_10-1774460123529.png" alt="jayesh_mudaliar_10-1774460123529.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_11-1774460131063.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388900iF291C31504D7112C/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_11-1774460131063.png" alt="jayesh_mudaliar_11-1774460131063.png" /></span></LI></OL><pre class="lia-code-sample language-abap"><code>FUNCTION-POOL ZBP_FMGRP_BUPA. "MESSAGE-ID .. * INCLUDE LZBP_FMGRP_BUPAD... " Local class definition TABLES bus_joel_search. DATA: gs_dynpro_id TYPE bus_screen-area, gv_email type adr6-smtp_addr. " capture screen value CLASS lcl_searcher DEFINITION FINAL. PUBLIC SECTION. CLASS-METHODS: select_by_email IMPORTING iv_search TYPE REF TO cl_bus_locator_search iv_email TYPE bus_joel_search-smtp_addr EXCEPTIONS search_values_missing. ENDCLASS.</code></pre><UL><LI>Create a Copy FM from Standard BUPA_DIALOG_SEARCH into a&nbsp; Z Function module. Follow the below code to fetch the partner from the view created in STEP1 based on input from email of BP screen.</LI></UL><pre class="lia-code-sample language-abap"><code>FUNCTION zbp_bupa_dialog_emailrch. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" REFERENCE(IV_SEARCH) TYPE REF TO CL_BUS_LOCATOR_SEARCH *" EXCEPTIONS *" SEARCH_VALUES_MISSING *"---------------------------------------------------------------------- * Local data. DATA: ls_search_fields TYPE bus_joel_search. * Convert generic container into specific fields. ls_search_fields = iv_search-&gt;gv_search_fields. * Choose the select. CASE iv_search-&gt;gv_search_id. * The empty search? WHEN space. CALL METHOD lcl_searcher=&gt;select_by_nothing EXPORTING iv_search = iv_search. WHEN 'ZBP_EMAIL_SRCHELP'. "name of elementary search help CALL METHOD lcl_searcher=&gt;select_by_email EXPORTING iv_search = iv_search iv_email = ls_search_fields-smtp_addr EXCEPTIONS search_values_missing = 1. WHEN OTHERS. CLEAR sy-subrc. ENDCASE. * CASE sy-subrc. WHEN 1. RAISE search_values_missing. ENDCASE. ENDFUNCTION. ​</code></pre><UL><LI>Implement the method by creating a new include in Master Program.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_12-1774460258359.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388901i64779AC52C2A13C2/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_12-1774460258359.png" alt="jayesh_mudaliar_12-1774460258359.png" /></span><P>with the below code the Partner GUID is passed back again to BP framework to display the result of partner number based on the user input of email id.&nbsp;</P></LI></UL><pre class="lia-code-sample language-abap"><code>*&amp;---------------------------------------------------------------------* *&amp; Include ZBP_FMGRP_BUPA01 *&amp;---------------------------------------------------------------------* CLASS lcl_searcher IMPLEMENTATION. *--------------------------------------------------------------------- METHOD select_by_email. * Local data. DATA: lv_partner_type TYPE bus_partner-type, lr_email TYPE RANGE OF adr6-smtp_addr, lt_partner_guids TYPE bus_partner-guid_table. IF gv_email NE space. SELECT partner_guid INTO TABLE lt_partner_guids FROM zbp_email_search UP TO iv_search-&gt;gv_maximum_rows ROWS WHERE smtp_addr EQ gv_email. * BREAK-POINT. IF sy-subrc NE 0. TRANSLATE gv_email TO LOWER CASE. SELECT partner_guid INTO TABLE lt_partner_guids FROM zbp_email_search UP TO iv_search-&gt;gv_maximum_rows ROWS WHERE smtp_addr EQ gv_email. ENDIF. ENDIF. * Pass result table CALL METHOD cl_bupa_dialog_searcher=&gt;add_partner_guids_to_result EXPORTING it_partner_guids = lt_partner_guids iv_filter_by_search_type = space iv_search = iv_search. ENDMETHOD. "select_by_email ENDCLASS. "lcl_searcher IMPLEMENTATION</code></pre><UL><LI>Create a new screen by Right click on Function group -&gt; Create-&gt;Screen<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_13-1774460438398.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388904iB4816B7AF6BB0801/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_13-1774460438398.png" alt="jayesh_mudaliar_13-1774460438398.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_14-1774460443990.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388905iE619502018AB1D30/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_14-1774460443990.png" alt="jayesh_mudaliar_14-1774460443990.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_15-1774460457798.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388906iE6D1DF7D04877773/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_15-1774460457798.png" alt="jayesh_mudaliar_15-1774460457798.png" /></span><P><SPAN><EM>Note: GV_EMAIL is the same which is declared in step 8.Don’t forget to make the text box as scrollable otherwise you may loose data .</EM></SPAN></P></LI><LI>Double click on PBO and PAI and create new include in Master Program of function group. And do the following code. This code helps to pass the necessary information of standard processing copied from LBUPA_DIALOG_SEARCHF02 and LBUS_LOCATORO01.</LI></UL><pre class="lia-code-sample language-abap"><code>----------------------------------------------------------------------* ***INCLUDE LZBP_FMGRP_BUPAO01. *----------------------------------------------------------------------* *&amp;---------------------------------------------------------------------* *&amp; Module DYNPRO_PBO OUTPUT *&amp;---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE dynpro_pbo OUTPUT. gs_dynpro_id-program_name = sy-repid. gs_dynpro_id-dynpro_number = sy-dynnr. CALL METHOD cl_bus_abstract_screen=&gt;dynpro_pbo EXPORTING iv_program_name = gs_dynpro_id-program_name iv_dynpro_number = gs_dynpro_id-dynpro_number. ENDMODULE. " DYNPRO_PBO OUTPUT *&amp;---------------------------------------------------------------------* *&amp; Module DYNPRO_PAI INPUT *&amp;---------------------------------------------------------------------* * text *----------------------------------------------------------------------* MODULE dynpro_pai INPUT. gs_dynpro_id-program_name = sy-repid. gs_dynpro_id-dynpro_number = sy-dynnr. CALL METHOD cl_bus_abstract_screen=&gt;dynpro_pai EXPORTING iv_program_name = gs_dynpro_id-program_name iv_dynpro_number = gs_dynpro_id-dynpro_number. ENDMODULE. " DYNPRO_PAI INPUT ​</code></pre><UL><LI>Create a new include in Master Program of function group and enter the below code. These subroutines are called from the BUS_JEOL_LOCATOR framework hence it is required in our FM.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_16-1774460538164.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388907iDC749C2AA5506965/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_16-1774460538164.png" alt="jayesh_mudaliar_16-1774460538164.png" /></span></LI></UL><pre class="lia-code-sample language-abap"><code>*---------------------------------------------------------------------* * FORM bus_locator_get_search_fields * *---------------------------------------------------------------------* FORM bus_locator_get_search_fields "#EC CALLED USING iv_search_application TYPE bus_locator-search_application CHANGING ev_search_fields TYPE bus_locator-search_fields. CASE iv_search_application. WHEN cl_bupa_dialog_searcher=&gt;gc_search_application_bupa. ev_search_fields = bus_joel_search."#EC ENHOK ENDCASE. ENDFORM. *---------------------------------------------------------------------* * FORM bus_locator_set_search_fields * *---------------------------------------------------------------------* FORM bus_locator_set_search_fields "#EC CALLED USING iv_search_application TYPE bus_locator-search_application iv_search_fields TYPE bus_locator-search_fields. CASE iv_search_application. WHEN cl_bupa_dialog_searcher=&gt;gc_search_application_bupa. bus_joel_search = iv_search_fields. "#EC ENHOK ENDCASE. ENDFORM.</code></pre><UL><LI>Functional Configuration in LOCA_CUST<BR /><BR />Create new entry under <STRONG><STRONG><EM>Search by ID<BR /></EM></STRONG></STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_17-1774460587964.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388908i8B53A4587BB8B050/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_17-1774460587964.png" alt="jayesh_mudaliar_17-1774460587964.png" /></span><P>Search for the Search Help created in Step gy doing an F4 on Locator Search ID.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_18-1774460600291.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388909i4980C5030D72DD32/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_18-1774460600291.png" alt="jayesh_mudaliar_18-1774460600291.png" /></span><P>Screen text would be displayed on the drop of Find by screen of BP .Now do F4 for FM and Program name and enter screen number created in step 11 the details. That’s the end for the required config for mapping the new field to BP screen.<BR /><BR /></P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_19-1774460636263.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388910i2E5407C5EF093B92/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_19-1774460636263.png" alt="jayesh_mudaliar_19-1774460636263.png" /></span><BR /><BR /></LI><LI><STRONG><STRONG>Let’s test<BR /><EM>Enter Tcode BP. Click on BY dropdown to see the new field available under name Email.<BR /></EM></STRONG></STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_20-1774460683985.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388912iC384F08E4078C75E/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_20-1774460683985.png" alt="jayesh_mudaliar_20-1774460683985.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_21-1774460690609.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388913i0EBD1DF4DF2AECA4/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_21-1774460690609.png" alt="jayesh_mudaliar_21-1774460690609.png" /></span><P><STRONG><SPAN><EM>Enter any relevant email Id to find the respective BP . You can find the BP from the view created in Step 1 as well.</EM><BR /></SPAN></STRONG></P><P><STRONG><SPAN>Result<BR /><BR /></SPAN></STRONG></P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_22-1774460719689.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388914iF52F68F09EDF9A03/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_22-1774460719689.png" alt="jayesh_mudaliar_22-1774460719689.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_23-1774460730449.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388915i445A9CA8A2DC0F44/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_23-1774460730449.png" alt="jayesh_mudaliar_23-1774460730449.png" /></span><P>&nbsp;</P><STRONG><EM><BR /></EM></STRONG></LI></UL><P><SPAN>&nbsp;</SPAN></P> 2026-03-25T18:50:42.904000+01:00 https://community.sap.com/t5/supply-chain-management-blog-posts-by-members/spp-snc-supply-portal-collaboration-portal-badi-web-dynpro-screen-epn/ba-p/14353549 SPP SNC (Supply Portal Collaboration) Portal - BADI - Web Dynpro Screen EPN Column inclusion 2026-03-26T07:10:11.114000+01:00 Ramanathansp1 https://community.sap.com/t5/user/viewprofilepage/user-id/2029195 <H2 id="toc-hId-1792325516">Introduction:</H2><P>When we need to modify an existing column in SNC(Supply Network Collaboration) Portal under any tab with Header name and column values, we need to follow follow several set of procedures to find correct BADI and implement it.</P><P>In this blog I've explained about adding column EPN(Engineering Part Number) under Release Process-&gt;Overview tab in SNC portal.</P><H2 id="toc-hId-1595812011">Body:</H2><H5 id="toc-hId-1983057310" id="toc-hId-1786546663"><STRONG>Development Completed on Feb 5 , 2026</STRONG></H5><OL><LI>Business requested to include EPN(Engineering Part Number) column in the SAP SNC(Supply Network Collaboration) Portal.</LI><LI>T-Code for SNC Portal under APO box is <STRONG>/SAPAPO/SPP_CUSTOMER</STRONG> or we can also use <STRONG>/SAPAPO/SPP_SUPPLIER</STRONG></LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SNC Poral Initial Screen" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386338i230E5C0683E3795A/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_1-1773929538049.png" alt="SNC Poral Initial Screen" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SNC Poral Initial Screen</span></span></LI><LI>Under this screen go to Release Process-&gt;Overview Tab.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_3-1773929655552.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386340iA107EEC5AF97805A/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_3-1773929655552.png" alt="Ramanathansp1_3-1773929655552.png" /></span></LI><LI>Here you can see 7th column named as "My Product Number" should be changed to "Eng. Part Number (EPN)" column with the necessary EPN numbers to be populated against every Product number.</LI></OL><H5 id="toc-hId-1590033158">Arriving at Solution:</H5><OL><LI>After going to Release Process-&gt;Overview tab, go to debugging screen and need to find what are the available and useful BADI's for this solution to enhance this standard Web Dynpro screen.</LI><LI>To trigger debugging WD screen within SAP system, go to T-Code <STRONG>/N/SCF/WD_START&nbsp;</STRONG>and provide our Application ID :&nbsp;<STRONG>/SCF/SPP_CUSTOMER&nbsp;</STRONG>and check the checkbox <STRONG>"Internal Modus". </STRONG>So that it Web Dynpro Screen will start within SAP system. We can set breakpoint at <STRONG>"CALL BADI"</STRONG> statement and find the available BADI's.</LI><LI>Other way to find the class involved in particular Web Dynpro Screen is go to T-Code <STRONG>"/N/SCF/SCREENCFG" </STRONG>and click on <STRONG>ICH</STRONG> and go to screen definitions, then click on <STRONG>DSOVW</STRONG>-Release process Overview Screen (Supplier View) and click on Screen Layout. You will get the classes involved in fetching data etc.</LI><LI>This process is same for all Web Dynpro screens to get the respective class name.</LI><LI>With help of class name, we can get the logics involved in populating the screen data and BADI's called in-between.</LI><LI>We got BADI <STRONG>"/SCF/RELEASE_UI" </STRONG>which is useful here to populate the data from the backend. Create Enhancement Implementation and one BADI implementation within the created Enhancement Implementation.</LI><LI><TABLE width="593"><TBODY><TR><TD width="592px" height="30px">BADI 1:</TD></TR><TR><TD width="225.094px" height="30px">BADI Definition Name</TD><TD width="366.906px" height="30px">/SCF/RELEASE_UI</TD></TR><TR><TD width="225.094px" height="30px">Interface Used</TD><TD width="366.906px" height="30px">/SCF/IF_EX_RELEASE_UI</TD></TR><TR><TD width="225.094px" height="30px">Class where BADI is Triggered&nbsp;</TD><TD width="366.906px" height="30px">/SCF/CL_MDLTBV_DSOVERVIEW</TD></TR><TR><TD width="225.094px" height="30px">Method called in Class</TD><TD width="366.906px" height="30px">LOAD_DATA</TD></TR><TR><TD width="225.094px" height="30px">Enhancement Implementation</TD><TD width="366.906px" height="30px">Z*</TD></TR><TR><TD width="225.094px" height="30px">BADI Implementation</TD><TD width="366.906px" height="30px">Z*</TD></TR><TR><TD width="225.094px" height="30px">Implementing Class</TD><TD width="366.906px" height="30px">Z*</TD></TR><TR><TD width="225.094px" height="30px">Method used</TD><TD width="366.906px" height="30px">/SCF/IF_EX_RELEASE_UI~LOAD_OVERVIEW_TBV</TD></TR></TBODY></TABLE></LI><LI>Always keep your enhancement codes within Enhancement Switch which is maintained in a separate custom table. So that, whenever there's a misfortune happens, we can turn it off immediately to prevent more damages. Always check the Switch turned on and write your own logic.</LI><LI>In this BADI code logic, we are fetching all the EPN values from Transparent Table <STRONG>/SAPAPO/MATAPN&nbsp;</STRONG>and assigning against the column "<!-- StartFragment --><STRONG>CUSTMATERIAL </STRONG>"(My Product Number column).</LI><LI>This BADI will push the data into the target column.</LI><LI>Next, we need another BADI to change the Column header name in Web Dynpro Screen.</LI><LI>We got BADI <STRONG>"WD_BADI_DOMODIFYVIEW" </STRONG>which will be triggered multiple times. Hence, we have filter option where we need to fill required parameters.</LI><LI><TABLE width="593"><TBODY><TR><TD width="593">BADI 2:</TD></TR><TR><TD>BADI Definition Name</TD><TD>WD_BADI_DOMODIFYVIEW</TD></TR><TR><TD>Interface Used</TD><TD>IF_WD_BADI_DOMODIFYVIEW</TD></TR><TR><TD>Class where BADI is Triggered&nbsp;</TD><TD>CL_WDR_DELEGATING_VIEW</TD></TR><TR><TD>Method called in Class</TD><TD>DO_MODIFY_VIEW</TD></TR><TR><TD>Enhancement Implementation</TD><TD>Z*</TD></TR><TR><TD>BADI Implementation</TD><TD>Z*</TD></TR><TR><TD>Implementing Class</TD><TD>Z*</TD></TR><TR><TD>Method used</TD><TD>IF_WD_BADI_DOMODIFYVIEW~WDDOMODIFYVIEW</TD></TR></TBODY></TABLE></LI><LI>Here we are using COMPONENT_NAME as <STRONG>"SALV_WD_TABLE"</STRONG> and VIEW_NAME as <STRONG>"VIEW_TABLE"</STRONG>.{ These BADI's aren't that easy to find like I mentioned here simply, it takes lot of effort to find each and every BADI <span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span>}. You can also find the exact component and view name from technical help on the WD screen.</LI><LI>&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_2-1773938903673.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386453iAF9CBCD6C13700C8/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_2-1773938903673.png" alt="Ramanathansp1_2-1773938903673.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_1-1773940816879.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386458i70FD593C4AB176CD/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_1-1773940816879.png" alt="Ramanathansp1_1-1773940816879.png" /></span></LI><LI>These parameters we need to find through debugging as and when our logic needs to be executed.</LI><LI>Create EI and BI like previous BADI and add the filter values.</LI><LI>In the BADI code logic, check for Enhancement Switch and get the exact object where our Column Header name lies within. We need to change both Header name and Caption name (visible during Hovering the column header).&nbsp;</LI><LI>We can compare ID of both elements, but it keeps on changing from system to system, but name remains consistent. Hence, We choose name of the column.</LI><LI>To find the element name from the WD screen, right click on the column header name from WD screen and press <STRONG>"Technical Help". </STRONG>Go to <STRONG>"View and View Elements"</STRONG> tab. Now, dropdown the <STRONG>"View Elements and Properties"&nbsp;</STRONG>tab. Now the dropped down screen exactly represents the properties of column header where you right clicked for technical help.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_3-1773938969922.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386454iCB42EDA38C651A47/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_3-1773938969922.png" alt="Ramanathansp1_3-1773938969922.png" /></span></LI><LI>Catch correct exceptions in correct order where subclass exception must be caught first, and then superclass exception can be caught. CX_ROOT must be caught at last of all exceptions. This BADI will also be triggered in other screens of SNC portal also, hence, if we miss catching exception, it will result in Screen Dump.</LI><LI>I faced lot of difficulties while finding correct component name, view name, tooltip, text of target elements. Biggest difficulty happened was to find the class name from where the data on screen is getting populated from.&nbsp;</LI><LI><STRONG><STRONG>Previous State/when Enhancement Switch is turned off :</STRONG></STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_0-1774339905381.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388199iFD9BD86407A89302/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_0-1774339905381.png" alt="Ramanathansp1_0-1774339905381.png" /></span></LI><LI><P>&nbsp;</P><STRONG>Current State/when Enhancement Switch is turned On:</STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ramanathansp1_2-1773941141837.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386459i132D292373BB7B4B/image-size/medium?v=v2&amp;px=400" role="button" title="Ramanathansp1_2-1773941141837.png" alt="Ramanathansp1_2-1773941141837.png" /></span></LI></OL><H2 id="toc-hId-1006271496">Conclusion:</H2><P><SPAN>This is how we change column name and related contents in SNC Portal. I've also worked on adding column <STRONG>"Commitment Level"</STRONG> column under "Receipts and Requirements"-&gt;"Due list for Purchasing Documents" tab by implementing the BADI <STRONG>"/SCF/ICH_POWL"</STRONG>. Attached complete code for your reference!&nbsp;</SPAN><SPAN>Please feel free to post your comments and message me for any support regarding this.&nbsp;</SPAN><SPAN>Hope this helps someone! <span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></SPAN></P> 2026-03-26T07:10:11.114000+01:00 https://community.sap.com/t5/abap-blog-posts/fiori-list-report-the-quot-process-all-quot-dilemma-parsing-odata-filter-in/ba-p/14359159 Fiori List Report: The "Process All" Dilemma — Parsing OData $filter in ABAP 2026-03-26T18:27:35.306000+01:00 AlessandroSpadoni https://community.sap.com/t5/user/viewprofilepage/user-id/141302 <H3 id="toc-hId-1921583168">The Problem</H3><P class="">This scenario is more common than you might think.</P><P class="">In the old SAP GUI world, ALV lists frequently had buttons like "Execute All" or "Process All" defined in the GUI Status, or users could simply "Select All" rows and trigger an action. The entire dataset was right there in memory — stateful, accessible, simple.</P><P class="">Unfortunately, the same approach is still often requested in Fiori Elements List Reports. The reason? There's still a widespread difficulty in understanding the fundamental difference between stateful and stateless, between a classic ALV list and a Fiori List Report.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AlessandroSpadoni_0-1774545069380.png" style="width: 566px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389401iAE06BFFD8424D291/image-dimensions/566x156?v=v2" width="566" height="156" role="button" title="AlessandroSpadoni_0-1774545069380.png" alt="AlessandroSpadoni_0-1774545069380.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AlessandroSpadoni_1-1774545139469.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389403i2FBEFF5C8EF959B1/image-size/large?v=v2&amp;px=999" role="button" title="AlessandroSpadoni_1-1774545139469.png" alt="AlessandroSpadoni_1-1774545139469.png" /></span></P><P class="">When we try to explain that there's an OData protocol with pagination behind the scenes, that "Select All" doesn't truly select all rows, or that an "Execute All" action has no knowledge of which records to process — unlike in ALV where the entire internal table was available — we can often steer the design away from this pattern. But sometimes, we can't.</P><P class="">The Fiori warning message helps users understand that "Select All" is only partial — it's no longer the same as it was with ALV lists.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AlessandroSpadoni_2-1774545196426.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389404iDDCFC40BEF6A9545/image-size/large?v=v2&amp;px=999" role="button" title="AlessandroSpadoni_2-1774545196426.png" alt="AlessandroSpadoni_2-1774545196426.png" /></span></P><P class="">There are legitimate use cases where, after filtering a dataset, reviewing it, validating it, the user needs to "confirm" an action or a status change to be applied to that specific result set they're currently looking at.</P><P class="">I won't go into the details of how the action should be implemented in ABAP — there could be timeout concerns, and often these actions are executed via background tasks or jobs. I want to focus specifically on the approach for capturing the "snapshot" of what the user has filtered.</P><P class="">As we said, "Select All" is not a viable option. In the modern world we have pagination, and we can't expect the user to scroll all the way to the bottom of the list. Retrieving all row identifiers from the frontend is simply not feasible.</P><H3 id="toc-hId-1725069663">Our Approach</H3><P class="">The best solution we've implemented (together with&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/137528">@SimoneLicciardi</a>&nbsp;) is to pass the applied filter criteria back to a Static Action — essentially the same filters that were active when the user pressed "Go".</P><P class="">We can define an Abstract Entity as the import parameter for the RAP action. If the action dialog already has other parameters, this is simply an additional hidden parameter (@UI.hidden: true) that we can call FilterString.</P><pre class="lia-code-sample language-abap"><code>define abstract entity ZA_ProcessAllParams { @UI.hidden: true FilterString : abap.string(4000); // ... other action parameters if needed }</code></pre><H3 id="toc-hId-1528556158">The Fiori Elements Extension</H3><P class="">On the Fiori Elements List Report side, we need custom action logic that does two things when the user triggers the action: capture the current $filter string and inject it into the hidden parameter.</P><P class="">This can be achieved through a custom action defined in the manifest.json (or via a controller extension, depending on your app setup).&nbsp;</P><P class="">The _getFilterString method extracts the $filter from the current table row binding — this is exactly the same filter the framework sent to the backend when the user pressed "Go".</P><pre class="lia-code-sample language-javascript"><code>function _getFilterString(oView) { // Table ID follows Fiori Elements convention: // "&lt;appId&gt;::&lt;ListReportPage&gt;--fe::table::&lt;EntitySet&gt;::LineItem" var oTable = oView.byId("&lt;your-table-control-id&gt;"); if (oTable) { var oRowBinding = oTable.getRowBinding(); if (oRowBinding) { var sPath = oRowBinding.getDownloadUrl(); if (sPath) { var iFilterStart = sPath.indexOf("$filter="); if (iFilterStart &gt; -1) { var sFilter = sPath.substring(iFilterStart + 8); var iNextParam = sFilter.indexOf("&amp;"); if (iNextParam &gt; -1) { sFilter = sFilter.substring(0, iNextParam); } return decodeURIComponent(sFilter); } } } } return ""; }</code></pre><P>Then in the action handler, we invoke the static action and pass the $filter string as the hidden parameter:</P><pre class="lia-code-sample language-javascript"><code>onPressExecuteAll: function () { var oView = this.editFlow.getView(); var sActionName = "&lt;your action bound context&gt;"; var sFilterString = _getFilterString(oView); var oInvokeParams = { controlId: "&lt;your-table-control-id&gt;", bStaticAction: true, invocationGrouping: "Isolated", parameterValues: [{ name: "FilterString", value: sFilterString }] }; this.editFlow.invokeAction(sActionName, oInvokeParams) .then(function (oResult) { // handle success }).catch(function (oError) { console.error("Action error:", oError); }); }</code></pre><P>The key point: the parameterValues array injects the filter string into the hidden FilterString field of the Abstract Entity. The user never sees it — the action dialog shows only the visible parameters (if any), while the filter criteria travel silently to the backend.</P><P><EM>Note:&nbsp; this was tested on S/4HANA 2023 with OData V4 and SAPUI5 1.120.</EM></P><H3 id="toc-hId-1332042653">The ABAP Parser</H3><P class="">On the backend, the action handler receives the $filter string and needs to parse it into ABAP range tables to re-execute the query with the same criteria.</P><P class="">We looked for standard solutions — for example, the method ODATA_FILTER2SELECT_OPTION of class CL_CLB2_TOOLS — but it only supports OData V2.</P><P class="">So we built a custom reusable class: ZCL_ODATA_FILTER_PARSER, which handles both V2 and V4 syntax and converts the $filter string directly into ABAP range tables.</P><pre class="lia-code-sample language-abap"><code>DATA(lo_parser) = NEW zcl_odata_filter_parser( iv_filter = lv_filter_string iv_version = zcl_odata_filter_parser=&gt;gc_version-v4 ). DATA(lt_r_plant) = lo_parser-&gt;get_range( 'Plant' ). DATA(lt_r_mat) = lo_parser-&gt;get_range( 'Material' ). DATA(lt_r_date) = lo_parser-&gt;get_range( 'DeliveryDate' ).</code></pre><P class="">The class is open source, includes ABAP Unit tests&nbsp; and is installable via abapGit. You can find the&nbsp; usage examples in the repository:</P><P class=""><A href="https://github.com/alespad/abap-odata-filter-parser" target="_self" rel="nofollow noopener noreferrer">https://github.com/alespad/abap-odata-filter-parser</A>&nbsp;</P><P class="">This is how we approached solving this problem. If you know of better approaches, closer to standard functionality, we'd love to hear about them — please share in the comments!</P><P class="">&nbsp;</P> 2026-03-26T18:27:35.306000+01:00 https://community.sap.com/t5/abap-blog-posts/send-email-with-inline-base64-image-in-sap-abap/ba-p/14359761 Send Email with inline BASE64 Image in SAP ABAP. 2026-03-27T12:30:41.235000+01:00 dmitry_sharshatkin https://community.sap.com/t5/user/viewprofilepage/user-id/186675 <H2 id="toc-hId-1792506238">Introduction&nbsp;</H2><DIV><P>I recently came across the need to send an automatically generated email based on a given HTML template. To my surprise, this time the template arrived with embedded/inline (src="data&amp;colon;image/png;base64,...) images using Base64 encoding. I should mention that all previous HTML mail templates I worked with contained image links pointing to a content web server.</P><P>Since this was new to me, I did some research on the topic but did not find much information, except for this helpful blog post:<BR /><A href="https://community.sap.com/t5/technology-blog-posts-by-members/send-email-with-image-from-mime-repository-in-sap-abap/ba-p/14285931" target="_blank">https://community.sap.com/t5/technology-blog-posts-by-members/send-email-with-image-from-mime-repository-in-sap-abap/ba-p/14285931</A>&nbsp;</P><P>In that scenario, the images are stored in the MIME repository, whereas in my case they are embedded directly in the HTML file. Therefore, I needed to extract the picture content from the HTML code, rebuild the template, and generate an email using standard SAP BCS functionality.</P><P>After implementing this successfully, I would like to share some of my coding approach with the community.</P><P><STRONG>Code Example:&nbsp;</STRONG></P></DIV><pre class="lia-code-sample language-abap"><code>REPORT zemail_to_send_img2. *---------------------------------------------------------------------- * Data Declarations *---------------------------------------------------------------------- TYPES: BEGIN OF lty_pic_str, name TYPE string, mime TYPE w3conttype, src TYPE xstring, END OF lty_pic_str. DATA: lv_html_in TYPE string, "HTML body string (input) lv_html_out TYPE string, "HTML body string (output) lt_html_out TYPE soli_tab, "HTML body lines lv_pic_cnt TYPE i, "Picture counter lv_src TYPE xstring, "Image content in XSTRING lt_solix TYPE solix_tab, "Binary table lv_len TYPE so_obj_len, "Length of binary content lt_pic_tab TYPE TABLE OF lty_pic_str. "Table with pictures DATA: lo_mime_srv TYPE REF TO cl_gbt_multirelated_service, lo_doc TYPE REF TO cl_document_bcs, lo_bcs TYPE REF TO cl_bcs, lo_sender TYPE REF TO if_sender_bcs, lo_recipient TYPE REF TO if_recipient_bcs. *---------------------------------------------------------------------- * Step 1: Build HTML Email Body *---------------------------------------------------------------------- lv_html_in = |&lt;html&gt;| &amp;&amp; |&lt;!-- To work with BCS, styles should be defined locally !!! --&gt;| &amp;&amp; |&lt;body style="background-color:#e6f0fa; font-family:Arial; margin:0; padding:10px;"&gt;| &amp;&amp; |&lt;div style="max-width:600px; margin:auto; background:#ffffff; padding:20px; border-radius:8px; border:1px solid #d0d7e3;"&gt;| &amp;&amp; | &lt;div style="text-align:center; margin-bottom:15px;"&gt;| &amp;&amp; |&lt;!-- Inline BASE64 PNG Image --&gt;| &amp;&amp; | &lt;img src="data&amp;colon;image/png;base64,| &amp;&amp; |iVBORw0KGgoAAAANSUhEUgAAAKMAAACUCAMAAADIzWmnAAAAY1BMVEX///8AAABHR0f7+/vz8/PV1dXw8PA6Ojr29vbk5OTp6ekyMj| &amp;&amp; |Ls7OwpKSnc3NxAQECcnJyRkZFfX1/MzMxkZGStra2+vr5WVlZQUFB1dXUeHh6mpqaLi4sPDw99fX1vb28XFxcA3zptAAAMl0lEQVR4| &amp;&amp; |nO1c52LyvA6G7EH2hCzu/yo/Sw7BQ06B0vGe0+dPm0Esy1qWZR8Of/jDH/7wh/97RG7bDnkxAop8aCs3+mmSRERtUVp+cpmOd0yXxL| &amp;&amp; |fqovoFhAZpO/vHPfhjmwY/SGGaL7FGVKKTuQzhzxDoNOVFpOSCV6UbuOX9cnu4tN/PTLeQaDiWOZK24MMFic076Y04d7+Xwlke0a71| &amp;&amp; |DhX723MViXr2f3XwWoXKOf0+Csu1zZJLYwkMOjHVuVTrGxVjsn+Cf/irVr3K7fI9VKbzlbc7tAtqRIOSNrB/x+2lkV0N8I/TAHXXuR| &amp;&amp; |osLpjj16uPPXBT4zdehDwqeZseXHjbax484ZcpDvjZ8Rr+y6z5Ygpd3k7Zsrbhn+utwZZdFMKbBbtu1/8HFAw29C0f+f5LB3zEYU4a| &amp;&amp; |hwllBg3fyDiw1hNRb12mVOXtogEN60IYedS1ZPgyCl0uUgWMoQti5m9URTCctvCufWZ3NkeIb1tw6RVHQULeDs6DGnU3hDHP7g0Nwt| &amp;&amp; |BytDetQaTwfocCWtUoz/Lb74GdIwMGBy48aCcTxIpdXzzpfY+Zn/p+iZyckdMOyuf0/vE+Ye87Prj2DFZECGmAgrPyCzbYsSCh4eWu| &amp;&amp; |VS6q+uwd3oqQf9XhV8CIpBIeN+hXZIDfEc1Me7nLgzOj2LyVyBSc2zFfwwLQWal54GusRopRfBvcFdAzfxXhACWnfGN06UL0er0xKg| &amp;&amp; |Krk4vPvatCzo3wq8QpcD7lOhSHCsxY8jb1RsPtb2OJTUmRlivp8A3ANynUcXqxcxV8tX8TkWg34k2JQc4SOcwaBC7fAZySKXdBJDeq| &amp;&amp; |UjSabyEyTCRT6PWKMB7QyfQn7YenXnA1HMDaehOKMBMk9DPAYOGY5Tc+QjOd/ErAerGo4sgEkoVFiRJ9W4KtT3kotHw6QA+W44ppbs| &amp;&amp; |MAzdxV6TqoFGWRWXcmJfaGQIQFlkHUrhHekdC2ZwHudZuTXur8TKiHphw32nWpOIDNmfNaCuM/6XFaRt/UVOer8MnrWEVS10HRKV7Y| &amp;&amp; |RzHshRtRNYuT8OtSNZMQvr8E9LLYzWouxWnq1M9566ahF9gHh0lsRv48Q3toB16YulV+7kX64m6uoGOD4vmfBijesv5vu82YHSVMfr| &amp;&amp; |fMRcGIL9M0jLwgsKFZ2w4CLwrTlBEfF8W8dNkk/zAbG/emKouuhM8AdVj0VzCq2UVpEKlNkjj2szv8OE4S6sUr9FOM2KOOENuHAUb4| &amp;&amp; |KioDzFI655C2+Vxbej5iH4lVM/lI0cBeRHvjsmYuL869A7CMkl8GpeRKaDuhW7XDyIbxI1qTrFtGyKOFjr19pVU/S9jXRwAjLfllh9| &amp;&amp; |lcXwlV7MCpYZY45ON8XpaaY1nO85gPMBOsnUBpPmTy24n3kBkvjTZYa9kvgyEq9BctIxfA01j6bSbVk8RICPYS3Zl+DNAPybodIDDV| &amp;&amp; |vSt4QoOrgPBM9YYH7mzkvo7anYcA6ZBJuhMmWoyAt49mTzGQvTp0WigxabHUI9CdXkNLjauOnACQDqLpRtUa7Mz8LIkwHp0832A2wy| &amp;&amp; |ccQrPjzGAwiG5BRFpLd7yO5vguzlpXT4ausqgjMfmyNCHlDBMEspy2zzMSPm7pX6EMBNNd3zTB8/y7LxWhzyMD6+nZTaETxPo+UfO4| &amp;&amp; |3hRRAJjj64nb4aRxrVEdxkeIWP9jmY0Q+RO2Ds0jRQbH3o9k5gfMslvP2MhW7xSIP9VPJ1PlXwTzQZlD3M91W5Nr47+PUtcD+ARlwc| &amp;&amp; |Czmc0vk5mYkjIiRE9p82sCZurkoQZVzKihAD9m9rWNwTafMs05BaDsj2dXCGvtxBrZHCAD5jxdazCeQJCvCIHBR9Cw2VBflA8YPR64| &amp;&amp; |ErMYVSYnBI5FsRLORZx8fwDdDXAtIhuD3punI6mJNy2hIbWUdt0HZa1HOZt4hyFsWGFkv0uomu7GzYD4Tm221gzaCqbvV7NZO10Nlh| &amp;&amp; |lmDOpYhXR8SiFgP+8U9Qh8UyAL7pqygBwO7bB5+Ku6p4AFFv1jmZWU6A4E5XRbLIz1zYJu+6YAmPXtog5WQQwgjZbQxWoyyD7QaO3Q| &amp;&amp; |aJloZMI3qUqzbyNEFIR6NAYvgzmrvRl8Z0qMUckgSpFo9IR65CYfALNCs7tGXatJcfWIOAcU6bGUBeU3YVJEvgzpSXXVQ8R5W9tUoU| &amp;&amp; |3pDjxOeIREMPdqRAze+kK+DSHbXvw8kylewEVZvVvfVh0cCSrjCSNKB4kni2CHgNEYFfaEFBBZVRKgXKpaw4jSUgcLIXtizhQwo1dh| &amp;&amp; |akIKKJNCgXLAkXFEIXzcC/ELYnWJY97KL+4wuncFoMLq6MAKAD2ikBjYozE3TqVGIoI4PTipKbR5JV8Kpn/7Oo05se4RPJhTmQkVhu| &amp;&amp; |UeOl8CTnIv5z4QLm97EmtBHWFTCOD6pEaJcUJwojMRGyCLQet1Q3FYXQc10AjzaEsB1k6oN7cnCfmEAxfJyCcx9WQijCZN44/if4jG| &amp;&amp; |3z7Wh39AZ/4F2/NP2HCTL6R/+zO+8LmYIvogpsi/JKYwxWZUPvanYrN/Icb1DHMFeqLx/rnCQ+m95+ZcnUkKOL5mzkXkqrmyk5MhkI| &amp;&amp; |I9Gp+eu5pz6yJMOQAyg/dDOQBTLoVUOAg3+51cSv9sLuWx5N7P5qQeK/8gc3tEESbHSC7/3gC5PdI0QW7PVxt5PLdH5khLrKQgUOya| &amp;&amp; |C8iRkvw35Uj3bK0IKsE/0ouuXOPNpZaRyQGDeqj0PJNrNuTsaS/1iZy9+r3axAcCgWHtg26MXkZfYVyAN6x9lA+Xpww6QY6pauL1Na| &amp;&amp; |SYWEN6vDyOWouDEhNKN15fizsTa3FPFBH39JomJSyvr2kqPIM1zWfqzgxrw9RIeNmew4YVDor7uS4DWvnUBwDmKGvskWVYurX2ur+3| &amp;&amp; |xi6HbOAl1CKsXdijrjWLWu79ARkbLcTtiK5VeK4MCaqklZoPk4Wtdae2wSEsLf0trPl4slRz0b6yUztDqgXApFBQFSaPCWjA3voEBV| &amp;&amp; |A8pQbJoivOX6xBkmUYa5CernitNeug7+PhdHxQy0XQrwcEwwts5EWkck1cSic6XqiJK7XEwIvVzVptoa1LESC4mCOqUSlr5Qi16ZZe| &amp;&amp; |x/gYUq3ez+BQLWM+zlCjWahCA/7UkLn6AGD4pVpXcClyRZEdnCLYouQXUOla38ArXduqsigfBEVYkuvHWtfXiu3l7S43qkHW7xXDvr| &amp;&amp; |x7mMClW8ZGqBjmQjqony1f3FkBWinVXoOJrLHyun+x8prR6XSKWEPtNbH95kGA4Ai5LQfLzbXCdNxI5ftYwW5ZvILdj5PkclXfPE6X| &amp;&amp; |rlBrb/GjT1XsyYCcNRco223HXmkQdwLkzcDeWk6wEwDHC3cCnGCHQsVaTxYmEBqthXsXa/Bo/uskop8A2anGMhb5Zy24o+KEMgZ7Ku| &amp;&amp; |ioAkKlUwD0tvnZkndUnCsugSCddOXQowBzMwkHEwBLrFSxNHt7UwSjb0dtsYi7MpY2Qj/9VNhIYBbEvizadIH9NMo7wArK16ZH3aTg| &amp;&amp; |roxN4bI5Pr5UGS7B4Vv6p+vShiBDKVOEWHE26o7MG4jdm+EV3GDUiucJfH5DVwiacr2TMBw1uwxzRiogOOslVPd9KOHtbAtDevIpgE| &amp;&amp; |8U9iriLk2FO50WxwEg3lJmEcDZfiMbZTF5y35S3N4q74FU4khiBnWgKnjxS9uHcG/lw4mJD1DBp+97SUGN5KGl8p1EbRX65U1BcC+p| &amp;&amp; |/7ZzNYB1d3eFe9glkrzJsCd3kiQA/PK2yIB7ch9aRHgQeEDBtrcZt4SINg2WHWJ19eAUKzEb8PUW7PG9ze/akcuRIpHnlS25KkiDrk| &amp;&amp; |fIfNE6osSsNzxcJO/efHABmqDbXnvcYCrmCEAZ1GnELIfIEbjVVSD4Xvv6lZ1HuwhGtGb8zIJTKbMBKqEVUwhGU8jU4UBwa83PLDjm| &amp;&amp; |n93mSiHHeJaf/QAJJNH66skaOWWE25jxgIr17Ifki04kqXhAwM/QAILvsWV0VAcbLNT9DI3NFK5naPRfdpZPME6cB866FTbbFKUjzi| &amp;&amp; |LZnEyL76bbWSSXz0YRe7ArHgvAmS4uknsb4L0zXRo0heF2psv7DDeNIOeRgN94/MyKMx9Q3O5+1xrnLq5hyZX4djaO/3UHumxw15DS| &amp;&amp; |alqU/r5FBR0kRhY3WxhwypZ2PWNoGr/lJCS7Wo+J8js+8ngAE5zVtEkkSCOe1bQe6xSX65ym/r5zr6qzPK9eKgclUjzzqtXOvErm7z| &amp;&amp; |2ZqxrlOWw96GeHlTKFxfdSCHCaTppA75/BVv7AGWyINF/0fIV+J17y7zkyjMbvPxNwRdSO9NmKbLL7C85WvEM9o7L9XWdU/uEPf/jD| &amp;&amp; |H34G/wGmG7NImfqvDAAAAABJRU5ErkJggg==| &amp;&amp; |" alt="World" style="width:80px;" /&gt;| &amp;&amp; | &lt;/div&gt;| &amp;&amp; | &lt;p style="font-size:12px; color:#000;text-align:center"&gt;| &amp;&amp; | &lt;b&gt;HELLO WORLD!!!&lt;/b&gt;&lt;br&gt;&lt;br&gt;| &amp;&amp; | &lt;/p&gt;| &amp;&amp; | &lt;/div&gt;| &amp;&amp; |&lt;/body&gt;&lt;/html&gt;|. *---------------------------------------------------------------------- * Step 2: Extract all pictures and build new HTML Email Body *---------------------------------------------------------------------- lv_html_out = lv_html_in. " Get All Images... FIND ALL OCCURRENCES OF REGEX `&lt;img\b[^&gt;]*&gt;` IN lv_html_in RESULTS DATA(lt_matches) IGNORING CASE. LOOP AT lt_matches ASSIGNING FIELD-SYMBOL(&lt;m&gt;). DATA(lv_img) = lv_html_in+&lt;m&gt;-offset(&lt;m&gt;-length). " Get Source... FIND FIRST OCCURRENCE OF REGEX `src="([^"]+)"` IN lv_img SUBMATCHES DATA(lv_source) IGNORING CASE. IF sy-subrc = 0 AND lv_source IS NOT INITIAL. " BASE64... IF to_lower( lv_source ) CS ';base64,'. " Get Picture... FIND FIRST OCCURRENCE OF REGEX ';base64,(.*)$' IN lv_source SUBMATCHES DATA(lv_base64) IGNORING CASE. IF sy-subrc = 0 AND lv_base64 IS NOT INITIAL. ADD 1 TO lv_pic_cnt. " Get Picture Name... DATA(lv_pic_name) = |inline_image_{ lv_pic_cnt }.png|. " Append Image Table... CLEAR: lv_src. CALL FUNCTION 'SCMS_BASE64_DECODE_STR' EXPORTING input = lv_base64 IMPORTING output = lv_src EXCEPTIONS failed = 1 OTHERS = 2. IF sy-subrc &lt;&gt; 0. CONTINUE. ENDIF. " Mime type is hardcoded here for simplicity... APPEND VALUE #( name = lv_pic_name mime = 'image/png' src=lv_src ) TO lt_pic_tab[]. " Build new Source... DATA(lv_new_source) = |cid:{ lv_pic_name }|. " Replace Source... DATA(lv_new_img) = lv_img. REPLACE FIRST OCCURRENCE OF lv_source IN lv_new_img WITH lv_new_source. " Replace Image... REPLACE FIRST OCCURRENCE OF lv_img IN lv_html_out WITH lv_new_img. ENDIF. ENDIF. ENDIF. ENDLOOP. *---------------------------------------------------------------------- * Step 3: Convert HTML-Out STRING to SOLIX *---------------------------------------------------------------------- lt_html_out[] = cl_document_bcs=&gt;string_to_soli( lv_html_out ). *---------------------------------------------------------------------- * Step 4: Create MIME Multi-Part Object for Email *---------------------------------------------------------------------- CREATE OBJECT lo_mime_srv. *---------------------------------------------------------------------- * Step 5: Add Inline Images (Content-ID Based Embedding) *---------------------------------------------------------------------- LOOP AT lt_pic_tab ASSIGNING FIELD-SYMBOL(&lt;fs_pic&gt;). CLEAR: lt_solix[], lv_len. lt_solix = cl_bcs_convert=&gt;xstring_to_solix( &lt;fs_pic&gt;-src ). lv_len = xstrlen( &lt;fs_pic&gt;-src ). lo_mime_srv-&gt;add_binary_part( content = lt_solix content_type = &lt;fs_pic&gt;-mime length = lv_len content_id = &lt;fs_pic&gt;-name ). ENDLOOP. *---------------------------------------------------------------------- * Step 6: Set HTML Body into MIME Service *---------------------------------------------------------------------- lo_mime_srv-&gt;set_main_html( content = lt_html_out filename = 'email.htm' description = 'Hello World!' ). *---------------------------------------------------------------------- * Step 7: Create Email Document with Subject *---------------------------------------------------------------------- TRY. lo_doc = cl_document_bcs=&gt;create_from_multirelated( i_subject = 'Hello World!' i_multirel_service = lo_mime_srv ). CATCH cx_root INTO DATA(lx_root). WRITE: /, |Something went wrong....|. RETURN. ENDTRY. *---------------------------------------------------------------------- * Step 8: Create and Send Email Using BCS *---------------------------------------------------------------------- TRY. lo_bcs = cl_bcs=&gt;create_persistent( ). lo_bcs-&gt;set_document( lo_doc ). lo_sender = cl_sapuser_bcs=&gt;create( sy-uname ). lo_bcs-&gt;set_sender( lo_sender ). lo_recipient = cl_cam_address_bcs=&gt;create_internet_address( 'hello.world@gmail.com' ). lo_bcs-&gt;add_recipient( lo_recipient ). lo_bcs-&gt;send( i_with_error_screen = abap_true ). CATCH cx_root INTO lx_root. WRITE: /, |Something went wrong....|. RETURN. ENDTRY. COMMIT WORK AND WAIT. *---------------------------------------------------------------------- * Final Message *---------------------------------------------------------------------- WRITE / 'Email sent successfully Check It in SOST. !'.</code></pre><P><STRONG>&nbsp;Output:&nbsp;</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmitry_sharshatkin_0-1774609604056.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389741iE71CCBA0EA2922FE/image-size/medium?v=v2&amp;px=400" role="button" title="dmitry_sharshatkin_0-1774609604056.png" alt="dmitry_sharshatkin_0-1774609604056.png" /></span></P><H2 id="toc-hId-1595992733"><STRONG>Explanation</STRONG></H2><DIV><P>The program performs the following major steps:</P><OL><LI><STRONG>Construct an HTML template</STRONG> containing inline Base64‑encoded images. (But you may get it as local file on your PC or form MIME repository. These options are not considered here ).</LI><LI><STRONG>Scan the HTML</STRONG> for <CODE>&lt;img&gt;</CODE> tags and extract the Base64 image data.&nbsp;</LI><LI><STRONG>Decode each Base64 image</STRONG>&nbsp;with the help of function module&nbsp;<CODE><SPAN>SCMS_BASE64_DECODE_STR</SPAN>E</CODE>&nbsp;and store it as a binary part for the email.&nbsp;</LI><LI><STRONG>Replace Base64 data in HTML with CID references</STRONG> (e.g., <CODE>cid:inline_image_1.png</CODE>).</LI><LI><STRONG>Convert HTML to BCS format</STRONG> (SO_DOCUMENT format).</LI><LI><STRONG>Create a MIME multi-part message</STRONG> via class <CODE>CL_GBT_MULTIRELATED_SERVICE</CODE>.</LI><LI><STRONG>Embed all images as MIME parts</STRONG> so email clients can render them inline.</LI><LI><STRONG>Assemble the email document</STRONG> with subject, HTML body, and images.</LI><LI><STRONG>Send the email using BCS</STRONG> to the configured recipient.</LI></OL></DIV><P>This ABAP report builds an HTML email containing Base64‑encoded inline images, extracts and decodes those images, embeds them as MIME parts in the email, rewrites the HTML to use Content‑ID (CID) references, and sends the fully constructed HTML email with inline images using the SAP BCS framework. The email is sent from the logged-on SAP user to a fixed email address and can be traced via transaction <CODE>SOST</CODE>.</P><P>&nbsp;</P><DIV>Thank you for taking the time to read my post. I hope this information helps anyone facing a similar requirement. If you have questions, feedback, or suggestions for improvement, feel free to leave a comment below.</DIV> 2026-03-27T12:30:41.235000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/custom-business-configurations-f4579-define-default-grouping-and-sorting/ba-p/14359823 Custom Business Configurations (F4579): Define default grouping and sorting 2026-03-27T13:50:03.260000+01:00 patrick_winkler https://community.sap.com/t5/user/viewprofilepage/user-id/729521 <H1 id="toc-hId-887480474" id="toc-hId-1663424358">Introduction</H1><P><SPAN>The&nbsp;</SPAN><A href="https://help.sap.com/docs/btp/sap-business-technology-platform/custom-business-configurations-app" target="_blank" rel="noopener noreferrer"><SPAN class="">Custom Business Configurations</SPAN></A><SPAN>&nbsp;(CUBCO) app serves as an entry point to the&nbsp;</SPAN><A class="" title="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/business-configuration-maintenance-object?version=Cloud" href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/business-configuration-maintenance-object?version=Cloud" target="_blank" rel="noopener noreferrer">Business Configuration Maintenance Object</A><SPAN>&nbsp;(SMBC) provided by custom applications or partners.<BR /><BR />This blog explains how to define the default grouping and sorting for the tables of the business configuration object.<BR />The basic procedure is already <A href="https://github.com/SAP-samples/abap-platform-fiori-feature-showcase/blob/main/06_object_page_content.md#presentation-variant---object-page" target="_self" rel="nofollow noopener noreferrer">explained here</A>,&nbsp;but we apply it directly to the result of the ADT wizard.<BR /></SPAN></P><P>This blog is relevant for</P><UL><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+S%25252F4HANA+Cloud+Public+Edition/pd-p/08e2a51b-1ce5-4367-8b33-4ae7e8b702e0" class="lia-product-mention" data-product="1199-1">SAP S/4HANA Cloud Public Edition</a>&nbsp;</LI><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+BTP+ABAP+environment/pd-p/73555000100800001164" class="lia-product-mention" data-product="11-1">SAP BTP ABAP environment</a>&nbsp;</LI><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+S%25252F4HANA+Cloud+Private+Edition/pd-p/5c26062a-9855-4f39-8205-272938b6882f" class="lia-product-mention" data-product="1198-1">SAP S/4HANA Cloud Private Edition</a>&nbsp;</LI></UL><P>Further reading:</P><UL><LI><A href="https://community.sap.com/t5/tag/business%20configuration%20maintenance%20object/tg-p/board-id/technology-blog-sap" target="_blank">Related blog posts</A></LI><LI>Learn how you can use<SPAN>&nbsp;</SPAN><A href="https://learning.sap.com/products/business-technology-platform/development/abap?url_id=text-sapcommunity-prdteng-ABAP" target="_blank" rel="noopener noreferrer">ABAP technology</A><SPAN>&nbsp;</SPAN>to develop innovative applications and business solutions across SAP’s portfolio on<SPAN>&nbsp;</SPAN><A href="https://learning.sap.com/products/business-technology-platform/development/abap" target="_blank" rel="noopener noreferrer">SAP Learning Site</A>.</LI></UL><H1 id="toc-hId-1439888495" id="toc-hId-1466910853">Example scenario</H1><P>Company codes are defined in the configuration table ZDEMO_CC. In the CUBCO app, the rows are to be grouped and sorted by country.</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Company Code' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #C @AbapCatalog.dataMaintenance : #ALLOWED define table zdemo_cc { key client : abap.clnt not null; key company_code : abap.numc(4) not null; country : land1; last_changed_at : abp_lastchange_tstmpl; local_last_changed_at : abp_locinst_lastchange_tstmpl; }</code></pre><H1 id="toc-hId-1243374990" id="toc-hId-1270397348">Define presentation variant</H1><P>First you use the<SPAN>&nbsp;</SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/generating-business-configuration-maintenance-object-with-generate-abap-repository-objects-wizard" target="_blank" rel="noopener noreferrer">ADT wizard to generate a Business Configuration Maintenance Object</A><SPAN>&nbsp;</SPAN>for this table.</P><P>In the generated CDS view ZI_COMPANYCODE_S of the Singleton entity, you change the facet type from #LINEITEM_REFERENCE to #<SPAN>PRESENTATIONVARIANT_REFERENCE and add the targetQualifier attribute:</SPAN></P><pre class="lia-code-sample language-abap"><code> <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.facet: [ { id: 'ZI_CompanyCode', purpose: #STANDARD, type: #PRESENTATIONVARIANT_REFERENCE, targetQualifier: 'myVariant', label: 'Company Codes', position: 1 , targetElement: '_CompanyCode' } ] .lineItem: [ { position: 1 } ] key 1 as SingletonID,</code></pre><P>In the metadata extension ZI_COMPANYCODE of the company code entity, add the following presentation variant:</P><pre class="lia-code-sample language-abap"><code><a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.presentationVariant: [ { qualifier: 'myVariant', sortOrder: [ { by: 'Country', direction: #ASC } ], groupBy: [ 'Country' ], visualizations: [{type: #AS_LINEITEM}] } ] annotate view ZI_CompanyCode with</code></pre><P>Finally, open the generated SMBC object ZCOMPANYCODE in ADT and open the table settings section. Change the table type attribute from Grid Table to Responsive Table because&nbsp;<A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/468a97775123488ab3345a0c48cadd8f/d344c5aa5c81483482dbbed5b3abb142.html?version=202510.001" target="_self" rel="noopener noreferrer">grouping is not supported for grid tables</A>. If you only need the default sorting, you can continue to use the grid table.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="patrick_winkler_1-1774615697786.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389766iEE96390108EFA388/image-size/medium?v=v2&amp;px=400" role="button" title="patrick_winkler_1-1774615697786.png" alt="patrick_winkler_1-1774615697786.png" /></span></P> 2026-03-27T13:50:03.260000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/our-2026-roadmap-for-joule-for-developers-abap-ai-capabilities/ba-p/14360358 Our 2026 Roadmap for Joule for Developers ABAP AI capabilities 2026-03-28T20:13:48.908000+01:00 JanMatthes https://community.sap.com/t5/user/viewprofilepage/user-id/194386 <P data-unlink="true"><A title="ABAP AI Capabilities" href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><BR /><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="J4D_Agentic.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/390078iDD4D1E72EFCEDA09/image-size/small?v=v2&amp;px=200" role="button" title="J4D_Agentic.png" alt="J4D_Agentic.png" /></span></A><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog?search=ABAP&amp;tab.sessionplanned=1692641568884001cZ9d" target="_blank" rel="noopener noreferrer"><STRONG>Sapphire 2026 </STRONG>is approaching quickly and as usual it will bring lots of new announcements.</A> So now is the right point in time to recap what has been announced already until Q2/2026 and prepare for the <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-abap-ai-sapphire-and-asug-2026-sessions/ba-p/14365782" target="_blank">ABAP AI sessions</A>.</P><P class="lia-indent-padding-left-30px" data-unlink="true" style="padding-left : 30px;">The <STRONG>ABAP Platform&nbsp;AI</STRONG> (covering both SAP BTP ABAP Environment and SAP S/4HANA) transitions from a set of independent AI skills to full-scale <STRONG>Agentic AI</STRONG>. <SPAN class="">The roadmap focuses heavily on developer productivity via Joule and the modernization of ABAP development tools. The key benefits for customers and partners of the&nbsp;<STRONG>roadmap until Q2/2026 are:</STRONG></SPAN></P><P data-unlink="true">&nbsp;</P><OL><LI><SPAN class="">ABAP </SPAN><SPAN class="">development&nbsp;</SPAN><SPAN class="">tools</SPAN>&nbsp;<SPAN class="">in</SPAN><STRONG><SPAN class="">&nbsp;VS Code with ABAP MCP Server.</SPAN></STRONG></LI><LI><SPAN class="">ABAP AI </SPAN><SPAN class="">f</SPAN><SPAN class="">or lower releases of </SPAN><STRONG><SPAN class="">SAP S/4HANA Cloud Private Edition (i.e. 2021, 2022, 2023 and 2025).</SPAN></STRONG></LI><LI><STRONG><SPAN class="">Simplified customer on-boarding of ABAP AI&nbsp;</SPAN></STRONG><SPAN class="">via SAP for Me and Central Business Configuration</SPAN><STRONG><SPAN class="">.</SPAN></STRONG></LI><LI><SPAN class=""><STRONG>Faster innovation with Side-by-Side consumption of SAP and 3rd party Agentic IDEs and LLMs</STRONG><BR />(e.g. Microsoft, Amazon, IBM, OpenAI, Anthropic, Google, Mistral…)</SPAN></LI></OL><DIV class="">&nbsp;</DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="J4D_Agentic_sbs.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/390119i0AFD64FE139637CA/image-size/large?v=v2&amp;px=999" role="button" title="J4D_Agentic_sbs.png" alt="J4D_Agentic_sbs.png" /></span></DIV><DIV class=""><P><SPAN class="">The biggest shift in 2026 will be the <STRONG>move toward Agentic AI</STRONG>, where the existing ABAP AI skills doesn't just explain, complete or generate code (e.g. RAP, CDS, Tests) <STRONG>independently but acts as an autonomous collaborator</STRONG>.&nbsp;</SPAN><SPAN class="">This includes built-in <STRONG>ABAP MCP (Model Context Protocol) server.</STRONG> The introduction of VS Code as IDE can only be a start as the depth and breath of Eclipse which we achieved in so many years cannot be reached with one or two steps in VS Code. It'll be a journey which starts with first providing&nbsp;End-to-end UI services development with agents.</SPAN></P><P><SPAN class="">The new ABAP AI side-by-side architecture is designed to provide a scalable and future‑proof foundation for <STRONG>ABAP AI capabilities across heterogeneous SAP landscapes</STRONG>. It enables customers to consume ABAP AI services side‑by‑side, independent of the underlying S/4HANA release, ensuring access even <STRONG>for lower‑release Private Edition systems</STRONG>.&nbsp;</SPAN></P><P><SPAN class="">A core benefit of the architecture is also its simplified enablement model through SAP for Me and Central Business Configuration, reducing on-boarding effort and ensuring consistent lifecycle management across environments.&nbsp;<BR />In addition, the architecture allows us to accelerate innovation speed by allowing to <STRONG>leverage SAP‑provided ABAP AI models alongside leading third‑party LLMs</STRONG> (e.g., Microsoft, Amazon, IBM, OpenAI, Anthropic, Google, Mistral) <STRONG>more independently from releases</STRONG>. This flexibility ensures rapid adoption of new capabilities without dependency on individual release cycles.</SPAN></P><P><SPAN class="">If you missed the <STRONG>highlights we delivered in Q1/2026</STRONG> have a look into what <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/custom-code-migration-to-sap-s-4hana-powered-by-sap-joule-for-developers/ba-p/14329094" target="_blank">Olga Dolinskaja shared about ABAP AI ATC finding explain and custom code explain and proposals</A>. Although this will be a focus also for our future roadmap we will also not stop investing into AI app generators like the&nbsp;<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/cds-analytical-model-generation-powered-by-ai" target="_blank" rel="noopener noreferrer">Embedded Analytics model generator</A>.&nbsp;</SPAN></P></DIV><DIV class="">&nbsp;</DIV><DIV class=""><STRONG>Here you can learn more:</STRONG></DIV><DIV class=""><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FaU3Eu2SlvxE%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DaU3Eu2SlvxE&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FaU3Eu2SlvxE%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="ABAP AI Roadmap, CAP Jan 2026 Release, Brazil CodeJams, CAP Roundtable, DYK #3 | SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></DIV><OL><LI><SPAN class=""><A class="" href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-joule-for-developers-expands-to-private-cloud-accelerating-abap/ba-p/14237958" target="_blank">SAP Joule for Developers (J4D) Expands to Private Cloud: Accelerating ABAP Innovation and Transformation </A></SPAN></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/your-2026-roadmap-to-getting-started-with-abap-ai-and-abap-1/ba-p/14312060" target="_blank"><SPAN class="">Your Roadmap for getting started with ABAP AI</SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/abap-ai-revolution-accelerates-the-abap-developer-who-built-enterprise-apps/ba-p/14216073" target="_blank"><SPAN class="">ABAP AI Revolution Accelerates: The ABAP Developer Who Built Enterprise Apps in Minutes </SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-next-era-of-abap-development/ba-p/14260522" target="_blank"><SPAN class="">Joule for Developers and ABAP AI capabilities are coming to SAP S/4HANA Private Edition 2021, 2022, and 2023</SPAN></A></LI><LI><SPAN class="">Public Roadmap: <A href="https://help.sap.com/docs/abap-cross-product/roadmap-info/genai" target="_blank" rel="noopener noreferrer">SAP Help</A> / <A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001562&amp;PRODUCT=73555000100800001164&amp;range=CURRENT-LAST" target="_blank" rel="noopener noreferrer">SAP Roadmap Explorer</A></SPAN></LI><LI><SPAN class="">Help &amp; Guides</SPAN><OL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-joule-for-developers-abap-ai-capabilities-for-sap-s-4hana-cloud-private/ba-p/14236954" target="_blank"><SPAN class="">Step-by-step guide how to activate SAP Joule for Developers, ABAP AI capabilities for your SAP S/4HANA Cloud Private Edition</SPAN></A></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-with-sap-s-4hana-public-cloud-edition-setup-guide/ba-p/14209989" target="_blank">Joule for Developers (J4D) for S/4HANA Public Cloud Setup Guide</A></SPAN></SPAN></LI><LI><A href="https://discovery-center.cloud.sap/search/abap%20ai" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>SAP ABAP AI Discovery Center</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://discovery-center.cloud.sap/search/Free-tier" target="_blank" rel="noopener nofollow noreferrer">SAP BTP Discovery Center (Free Tier Services)</A></SPAN></SPAN></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/custom-code-migration-to-sap-s-4hana-powered-by-sap-joule-for-developers/ba-p/14329094" target="_blank">Custom code migration to SAP S/4HANA powered by SAP Joule for Developers, ABAP AI capabilities</A> </SPAN></SPAN></LI><LI><A href="http://www.youtube.com/playlist?list=PL6RpkC85SLQAt9lvPw0gF4E3nwbJD0EUe" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>YouTube playlist for Joule for Developers (J4D)</SPAN></SPAN></A></LI><LI><A href="https://help.sap.com/docs/abap-ai" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>Joule for Developers Help (J4D)</SPAN></SPAN></A></LI><LI><A href="https://github.com/SAP-samples/abap-platform-rap120" target="_blank" rel="noopener nofollow noreferrer">Build SAP Fiori Apps with ABAP Cloud and SAP Joule for developers (RAP120)</A>&nbsp;</LI><LI><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>ADT Eclipse AI Capabilities Help</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://help.sap.com/docs/abap-ai/generative-ai-in-abap-cloud/set-up-abap-ai-sdk-powered-by-intelligent-scenario-lifecycle-management" target="_blank" rel="noopener noreferrer">ABAP AI SDK Help</A></SPAN></SPAN></LI><LI><A href="https://help.sap.com/docs/sap-ai-core/generative-ai/sap-abap-1?locale=en-US&amp;version=LATEST" target="_blank" rel="noopener noreferrer"><SPAN class="">ABAP-1 Help</SPAN></A></LI></OL></LI></OL><P data-unlink="true"><SPAN class="">More high-level insights about <A href="https://www.sap.com/sea/products/artificial-intelligence/joule-for-developers.html" target="_blank" rel="noopener noreferrer">Joule for Developers/ABAP AI</A> and <A href="https://www.sap.com/products/technology-platform/abap/environment.html" target="_blank" rel="noopener noreferrer">ABAP platform can be found&nbsp;here</A>&nbsp;. Here you find <A href="https://www.sap.com/products/artificial-intelligence/sap-abap.html" target="_blank" rel="noopener noreferrer">more on ABAP-&nbsp;1</A>,</SPAN></P> 2026-03-28T20:13:48.908000+01:00 https://community.sap.com/t5/abap-blog-posts/optional-task-use-joule-cds-unit-test-generation/ba-p/14358864 Optional Task: Use Joule CDS Unit Test Generation 2026-03-30T06:30:00.020000+02:00 Shilpa_Shankar https://community.sap.com/t5/user/viewprofilepage/user-id/141830 <P>Thank you to everyone who participated in the ABAP Developer Challenge over the past four weeks and successfully completed all four tasks focused on ABAP AI capabilities. We truly appreciate the enthusiasm and engagement shown throughout the challenge. As a follow-up, we are excited to introduce an additional bonus task.</P><P>In Week 2, you enhanced a CDS data definition by implementing simple logic. Building on that work, your next step is to create an ABAP test class to validate the logic within the CDS data definition. For this task, you will utilize another feature of Joule’s ABAP AI capabilities — <STRONG>CDS Test Generation</STRONG>.</P><P>Task:</P><UL><LI>Select the CDS data definition that you enhanced in Week 2.</LI><LI>Generate an ABAP test class using Joule’s CDS Test Generation feature.</LI><LI>Execute the test class and ensure that all generated test cases run successfully.</LI></UL><P>Please refer to the link below for detailed guidance on how to use this ABAP AI capability.</P><P><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-cds-test-class-generator?locale=en-US" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-cds-test-class-generator?locale=en-US</A></P> 2026-03-30T06:30:00.020000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/smaller-abap-runtime-size-now-available-in-sap-btp-abap-environment/ba-p/14350033 Smaller ABAP Runtime Size Now Available in SAP BTP ABAP Environment 2026-03-31T14:40:48.302000+02:00 Burcu_Karlidag https://community.sap.com/t5/user/viewprofilepage/user-id/151005 <P>Starting <STRONG>March 31, 2026</STRONG>, SAP BTP ABAP environment introduces a new runtime sizing option: <STRONG>0.5 ABAP Compute Units (ACU)</STRONG>&nbsp;which is<SPAN class=""><STRONG>&nbsp;8 GB of runtime memory</STRONG>.</SPAN></P><P><SPAN class="">With the introduction of 0.5 ACU, customers can now operate ABAP systems at<STRONG>&nbsp;50% lower ABAP runtime cost compared to the previous minimum size of 1 ACU</STRONG>&nbsp;making it significantly more cost-efficient to run development, test, and sandbox systems.</SPAN></P><P>This enhancement allows&nbsp;SAP BTP ABAP environment to run on <STRONG>smaller runtime units,&nbsp;</STRONG>&nbsp;lowering the entry barrier for development and test systems.</P><H2 id="toc-hId-1792231301"><STRONG>What is an ABAP Compute Unit (ACU)?</STRONG></H2><P>ABAP Compute Units (ACUs) define the runtime capacity of an SAP BTP ABAP environment system. One ACU corresponds to <STRONG>16 GB of memory</STRONG> allocated to the ABAP runtime. The total runtime size determines how much capacity is available across all ABAP application servers. For more information, see the documentation on <A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/abap-compute-units" target="_self" rel="noopener noreferrer">ABAP Compute Units</A>.</P><H2 id="toc-hId-1595717796">What’s New?</H2><P>With this update&nbsp;<STRONG>SAP BTP ABAP environment</STRONG> now supports <STRONG>0.5 ABAP Compute Units (ACU)</STRONG>&nbsp;as the new minimum system configuration.</P><P>It allows to run smaller systems, enabling more granular runtime sizing compared to previous configurations. It creates an additional option to better match the actual workloads, particularly for smaller environments.</P><H2 id="toc-hId-1399204291"><STRONG>What are the Key Benefits?</STRONG></H2><UL><LI><STRONG>50% lower ABAP runtime cost</STRONG> compared to the previous minimum size (1 ACU)</LI><LI><STRONG>Improved resource utilization</STRONG> for smaller or variable workloads</LI><LI><STRONG>Lower entry barrier</STRONG> for new and existing customers</LI></UL><P>For a detailed breakdown of cost components, see my previous <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/optimize-your-sap-btp-abap-environment-budget-a-detailed-cost-analysis-for/ba-p/13574333" target="_self">blog post</A> on ABAP environment cost calculation.</P><H2 id="toc-hId-1202690786"><STRONG>How to Adjust Existing Systems?</STRONG></H2><P data-unlink="true">Adjusting the ABAP runtime size (ACUs) is handled via manual scaling and <STRONG>does not lead to a system downtime</STRONG>&nbsp;. You can use the SAP BTP Cockpit to update the service instance, for example, from 1 ACU to 0,5 ACU, see the documentation on <A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/updating-abap-system" target="_self" rel="noopener noreferrer">Updating an ABAP System</A>.</P><H2 id="toc-hId-1006177281"><STRONG>What Needs to be Considered?</STRONG></H2><P>For systems with a runtime size of <STRONG>0.5 ACU</STRONG>, only one application server is used. This setup is suited for development and test, but <STRONG>not recommended for productive use</STRONG>, as it may increase the likelihood of short outages.</P><H3 id="toc-hId-938746495"><SPAN class="">Overview about typical use cases and recommend systems sizes</SPAN></H3><TABLE border="1"><TBODY><TR><TD width="409px" height="50px"><P><STRONG>Use Case</STRONG></P></TD><TD width="143px" height="50px"><P><STRONG>Size</STRONG></P></TD><TD width="198px" height="50px"><STRONG>Total Runtime Memory</STRONG></TD><TD width="178px" height="50px"><STRONG>Application Servers</STRONG></TD></TR><TR><TD width="409px" height="41px"><P>Development, test, sandbox systems for smaller projects</P></TD><TD width="143px" height="41px"><P><STRONG>0.5 ACU (new)</STRONG></P></TD><TD width="198px" height="41px">8 GB</TD><TD width="178px" height="41px">1 á 8 GB</TD></TR><TR><TD width="409px" height="57px">Development, test, sandbox systems for bigger projects;<BR />Productive systems for up to 1,000 active users per day</TD><TD width="143px" height="57px"><STRONG>1 ACU</STRONG></TD><TD width="198px" height="57px">16 GB</TD><TD width="178px" height="57px">2 á 8 GB</TD></TR><TR><TD width="409px" height="57px">Productive systems with higher concurrency or up to 100 tenants&nbsp;</TD><TD width="143px" height="57px"><STRONG>2 ACU</STRONG></TD><TD width="198px" height="57px">32 GB</TD><TD width="178px" height="57px">4 á 8 GB</TD></TR><TR><TD width="409px" height="30px">Productive systems with bigger max session size</TD><TD width="143px" height="30px"><STRONG>4 ACU</STRONG></TD><TD width="198px" height="30px">64 GB</TD><TD width="178px" height="30px">2 á 32 GB</TD></TR><TR><TD width="409px" height="57px">Productive systems with higher load in multitenant SaaS solution&nbsp;</TD><TD width="143px" height="57px"><STRONG>4 ACU</STRONG></TD><TD width="198px" height="57px">64 GB</TD><TD width="178px" height="57px">8 á 8 GB</TD></TR></TBODY></TABLE><P>&nbsp;</P><H2 id="toc-hId-613150271">Further References&nbsp;</H2><P>For more information about sizing options and configuration parameters in <STRONG>SAP BTP ABAP environment</STRONG>, see the documentation on&nbsp;<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/creating-abap-system?version=Cloud" target="_self" rel="noopener noreferrer">Creating an ABAP System</A>.</P> 2026-03-31T14:40:48.302000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/the-agentic-revolution-is-here-and-your-abap-code-is-the-foundation/ba-p/14358726 The Agentic Revolution Is Here — And Your ABAP Code Is the Foundation 2026-04-03T18:00:00.017000+02:00 Faaiez https://community.sap.com/t5/user/viewprofilepage/user-id/44178 <H1 id="toc-hId-1663393609">Three Waves in Two Years</H1><P><SPAN>To understand where we are, you need to understand the three inflection points Jensen described. They happened faster than anyone expected.</SPAN></P><H3 id="toc-hId-1725045542">Wave 1: Generative AI (2022–2023)</H3><P><SPAN>ChatGPT changed computing from retrieval-based to generative. Instead of a database returning a record, a model generates an answer. Jensen put it bluntly: "Computing used to be retrieval-based. Now it's generative." The architecture implications of that sentence are enormous and still rippling through every layer of enterprise software.</SPAN></P><H3 id="toc-hId-1528532037">Wave 2: Reasoning AI (2024)</H3><P><SPAN>OpenAI's o1 model introduced something that made generative AI trustworthy: the ability to think. To reflect. To decompose a problem it couldn't solve into steps it could. To ground itself on facts before answering. Reasoning AI made large language models genuinely useful for complex, multi-step work — not just creative writing and summarisation.</SPAN></P><H3 id="toc-hId-1332018532">Wave 3: Agentic AI (2025–2026)</H3><P><SPAN>This is the one that changes your job. Jensen cited Claude Code — the very AI assistant many of us now use daily — as the breakthrough moment:</SPAN></P><P class="lia-align-center" style="text-align: center;"><EM>"<FONT color="#008000">Claude Code has revolutionised software engineering. There is not one software engineer at NVIDIA today who is not assisted by an AI coding agent."</FONT></EM></P><P><SPAN>The shift is fundamental. With generative AI, you ask a question. With agentic AI, you give a task. The agent reads your files, writes code, compiles it, tests it, finds the failures, fixes them, and iterates — autonomously, in a loop, until the work is done or it needs your input.</SPAN></P><P><SPAN>Computing demand, Jensen said, has grown </SPAN><FONT color="#FF0000"><STRONG>one million times </STRONG></FONT><SPAN>in the last two years. That is not a typo. The explosion is driven by agentic inference: every time an agent thinks, plans, reads a file, calls a tool, or generates an output, it burns tokens.</SPAN></P><P><A href="https://www.nvidia.com/gtc/keynote/?regcode=em-even-504-en-gb-1-l1&amp;ncid=em-even-504-en-gb-1-l1" target="_blank" rel="noopener nofollow noreferrer"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Faaiez_0-1774510570417.png" style="width: 937px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389071i9259D9899541470A/image-dimensions/937x607?v=v2" width="937" height="607" role="button" title="Faaiez_0-1774510570417.png" alt="Faaiez_0-1774510570417.png" /></span></A></P><P><EM>GTC 2026 Keynote — Jensen Huang's enterprise agentic architectures slide (02:02:57). SAP is bottom-left. Each diagram is a production blueprint, not a roadmap.</EM></P><H1 id="toc-hId-877339589">&nbsp;</H1><H1 id="toc-hId-680826084">What Jensen Showed at 02:02:57</H1><P><SPAN>At just over two hours into the keynote, Jensen showed a slide he called a renaissance. Each of the twelve architecture diagrams was a real, production blueprint. Not a roadmap. Not a vision. Each company had already rebuilt its product around AI agents.</SPAN></P><P class="lia-align-center" style="text-align: center;"><FONT color="#008000"><EM>"This is a reinvention. A renaissance of enterprise IT. Every single SaaS company will become an Agentic as a Service company. No question about it."</EM></FONT></P><P><SPAN>He compared it to three previous platform shifts:</SPAN></P><UL><LI><SPAN>When Linux arrived → every company needed a Linux strategy</SPAN></LI><LI><SPAN>When HTML/HTTP arrived → every company needed a web strategy</SPAN></LI><LI><SPAN>When Kubernetes arrived → every company needed a cloud-native strategy</SPAN></LI><LI><STRONG><SPAN>Now </SPAN></STRONG><SPAN>Now OpenClaw (the open-source agentic OS) has arrived → every company needs an agentic strategy</SPAN></LI></UL><H1 id="toc-hId-484312579">NemoClaw and SAP: A Security Partnership</H1><P><SPAN>Jensen announced NemoClaw as NVIDIA's enterprise-hardened version of OpenClaw. To understand where it fits in the SAP picture, it helps to be precise about what it is — and what it is not.</SPAN></P><P><STRONG>OpenClaw </STRONG><SPAN>is, in Jensen's words, </SPAN><EM>"the operating system of agentic computers." </EM><SPAN>It handles task decomposition, sub-agent spawning, tool calling, file access, cron scheduling, multi-modal I/O, and LLM orchestration. It reached more GitHub stars in a few weeks than Linux achieved in thirty years.</SPAN></P><P><SPAN>The enterprise problem with a system that can "access sensitive information, execute code, and communicate externally" is obvious. You cannot deploy raw OpenClaw in an SAP landscape and have it reach your vendor master, financial postings, and HR records without controls.</SPAN></P><P><SPAN>NemoClaw solves this by adding three security layers on top of OpenClaw:</SPAN></P><TABLE><TBODY><TR><TD width="173"><P><STRONG>Layer</STRONG></P></TD><TD width="451"><P><STRONG>What It Does</STRONG></P></TD></TR><TR><TD width="173"><P><STRONG>OpenShell</STRONG></P></TD><TD width="451"><P>Sandboxes agent execution; controls what it can read, write, and call</P></TD></TR><TR><TD width="173"><P><STRONG>Policy Engine</STRONG></P></TD><TD width="451"><P>Enforces the enterprise's own business rules</P></TD></TR><TR><TD width="173"><P><STRONG>Network Guardrail<BR />+ Privacy Router</STRONG></P></TD><TD width="451"><P>Prevents data leaving the enterprise boundary</P></TD></TR></TBODY></TABLE><P>&nbsp;</P><P><STRONG>Important clarification: </STRONG><SPAN>NemoClaw is not the foundation SAP Joule is built on. Joule is SAP's own product, with its own architecture, models, and AI infrastructure running on BTP and SAP AI Core. NemoClaw is NVIDIA technology that SAP — as a launch enterprise partner — is integrating as an <STRONG>optional security and governance layer </STRONG>within BTP, tied specifically to Joule Studio. It is available for customers who require the strongest possible compliance controls when agents interact with sensitive ERP, financial, or supply chain data.</SPAN></P><P><SPAN>The architecture looks like this:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Faaiez_2-1774511587745.png" style="width: 935px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/389079i98A3CF5B3FBB0149/image-dimensions/935x325?v=v2" width="935" height="325" role="button" title="Faaiez_2-1774511587745.png" alt="Faaiez_2-1774511587745.png" /></span></P><P><SPAN>The bottom line for ABAP developers remains unchanged regardless of which security envelope is in play: when an agent needs to do something in SAP — read a purchase order, create a vendor, trigger a workflow, query a cost centre — it calls <STRONG>your ABAP</STRONG>.</SPAN></P><P><STRONG>Your BAPIs. Your CDS views. Your OData services.</STRONG></P><H1 id="toc-hId-287799074">&nbsp;</H1><H1 id="toc-hId-91285569">What This Means in Practice</H1><P><SPAN>Let me make this concrete with an example that exists today.</SPAN></P><P><EM>A procurement manager asks Joule: "Which of our top twenty suppliers have delivery performance below 90% this quarter, and what is the total open invoice value against them?"</EM></P><P><SPAN>In the pre-agentic world, someone writes a report in SE38, schedules it, exports to Excel, and manually cross-references two tables. Elapsed time: hours, or days if it hits a queue.</SPAN></P><P><SPAN>In the agentic world, <FONT color="#3366FF">Joule</FONT>:</SPAN></P><OL><LI><SPAN>Decomposes the question into sub-tasks</SPAN></LI><LI><STRONG><SPAN>Calls a procurement agent → queries I_SupplierDeliveryPerformance</SPAN></STRONG><SPAN> CDS view via OData</SPAN></LI><LI><STRONG><SPAN>Calls a finance agent → queries I_SupplierOpenItemMD</SPAN></STRONG><SPAN> CDS view via OData</SPAN></LI><LI><SPAN>Synthesises both results</SPAN></LI><LI><SPAN>Returns a structured answer in seconds</SPAN></LI></OL><P><SPAN>The entire chain runs through NemoClaw's policy engine and your ABAP authorization framework. The agent's service user has only the authorizations you have granted. Every CDS view it accesses must have the proper access control annotation and a corresponding DCL.</SPAN></P><P>&nbsp;</P><P><STRONG><FONT size="6">The Four Things Your ABAP Must Get Right</FONT></STRONG><BR />If agents are going to call your code — and they are — four things matter more than they ever did before.</P><H2 id="toc-hId-23854783"><BR />1. Clean, Annotated CDS Views</H2><P><BR />CDS views are the primary structured data interface for AI agents in SAP. An agent does not navigate transaction codes. It calls OData endpoints backed by CDS. If your CDS views lack semantic annotations, have incomplete access control, or expose data structures that predate any logical data model, they become a liability.<STRONG>The minimum bar for agent-ready CDS:</STRONG></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #CHECK @EndUserText.label: 'Supplier Delivery Performance' @VDM.viewType: #CONSUMPTION @OData.publish: true define view entity I_SupplierDeliveryPerformance as select from ... { @Semantics.businessPartner.role: #SUPPLIER SupplierID, @Semantics.quantity.unitOfMeasure: 'DeliveryUnit' ConfirmedDeliveryQty, @Semantics.percentage OnTimeDeliveryRate }</code></pre><P><SPAN>Semantic annotations tell the LLM what each field means. Without them, the agent is guessing from column names. With them, it can reason correctly.</SPAN></P><P>&nbsp;</P><H2 id="toc-hId-174595635">2. Authority Checks on Every Agent-Callable Interface</H2><P><BR />NemoClaw's policy engine delegates final security enforcement to ABAP. This is not a weakness — it is the correct architecture. The LLM should not be trusted with authorization decisions. ABAP should.<BR /><STRONG>Every function module, BAPI, and method that an agent can call must perform an explicit authority check:</STRONG></P><pre class="lia-code-sample language-abap"><code>METHOD get_supplier_invoice_data. AUTHORITY-CHECK OBJECT 'F_LFA1_BUK' ID 'BUKRS' FIELD iv_company_code ID 'ACTVT' FIELD '03'. IF sy-subrc &lt;&gt; 0. RAISE EXCEPTION TYPE cx_sy_authorization_check EXPORTING textid = cx_sy_authorization_check=&gt;no_authorization. ENDIF. " ... proceed with data retrieval ENDMETHOD.</code></pre><P>An agent running as a service user with overly broad authorizations is an insider threat waiting to happen. Lock it down at the ABAP layer.</P><H2 id="toc-hId--21917870">3. Machine-Speed Performance</H2><P><BR />A human clicks a button every thirty seconds. An agent may call your BAPI ten thousand times per hour. An interface that performs acceptably under human load may collapse completely under agent load.<BR /><STRONG>Review your agent-callable interfaces against these criteria:</STRONG><BR />• No SELECT * in performance-critical paths — agents fetch data in loops, field-level selects only.<BR />• Buffer vendor master, material master, and configuration data where appropriate.<BR />• Avoid dialogue modules and unnecessary commits in agent-exposed interfaces — agents expect atomic, stateless calls.<BR />• Consider ABAP Cloud compatibility — if you are on S/4HANA, agent integrations will increasingly come via BTP.</P><H2 id="toc-hId--218431375"><BR />4. Reliable, Structured Error Returns</H2><P><BR />Agents chain multiple tool calls into a single business process. If step three of a five-step chain fails silently — no exception raised, just a blank result set — the agent may proceed with corrupted state and complete a transaction based on missing data.<BR /><STRONG>Your interfaces need to fail loudly, clearly, and catchably:</STRONG></P><pre class="lia-code-sample language-abap"><code>METHOD create_purchase_requisition. TRY. " ... BAPI call IF lt_return[] IS NOT INITIAL. LOOP AT lt_return INTO ls_return WHERE type = 'E' OR type = 'A'. RAISE EXCEPTION TYPE cx_pr_creation_failed EXPORTING message = ls_return-message message_id = ls_return-id number = ls_return-number. ENDLOOP. ENDIF. CATCH cx_sy_authorization_check INTO DATA(lx_auth). RAISE EXCEPTION TYPE cx_pr_creation_failed EXPORTING message = 'Authorization check failed'. ENDTRY. ENDMETHOD.</code></pre><P>A well-structured exception gives the orchestration layer the information it needs to retry, compensate, or escalate. A dump gives it nothing.</P><H1 id="toc-hId--121541873">&nbsp;</H1><H1 id="toc-hId--318055378">Physical AI: Why EWM and IBP Developers Should Pay Close Attention</H1><P><SPAN>Jensen spent a significant portion of the keynote on physical AI — robots, autonomous vehicles, digital twins. At first glance this might seem distant from ABAP. &nbsp;<STRONG>It is not.</STRONG></SPAN></P><P><SPAN>He announced partnerships with </SPAN><STRONG>ABB, KUKA, Universal Robots, BYD, Hyundai, Nissan, and Geely</STRONG><SPAN> — collectively representing the automation of manufacturing floors and logistics networks at a scale never seen before. These physical systems will generate transactions. Inventory movements, goods receipts, production confirmations, delivery completions — triggered by machines at machine speed, not by warehouse workers scanning barcodes.</SPAN></P><P><SPAN>If you work in SAP Extended Warehouse Management, SAP Integrated Business Planning, or SAP Manufacturing Integration and Intelligence, the interfaces you build today will be called by robots tomorrow. The same four principles apply — and the <STRONG>performance requirement</STRONG> becomes even more acute.</SPAN></P><H1 id="toc-hId--514568883">&nbsp;</H1><H1 id="toc-hId--711082388">Your Learning Roadmap</H1><P><SPAN>The field is moving fast. But not everything needs to be learned at once. Here is how I would prioritise it.</SPAN></P><H2 id="toc-hId--1200998900">Start Now — Zero Extra Investment Required</H2><UL><LI><STRONG><SPAN>AI tools today.</SPAN></STRONG><SPAN> Use AI coding tools on real ABAP work — every unit test, every code review, every CDS view.</SPAN></LI><LI><STRONG><SPAN>Learn what SAP Joule can already do.</SPAN></STRONG><SPAN> Log into your BTP account and explore the Joule capabilities available today.</SPAN></LI><LI><STRONG><SPAN>Audit your CDS views.</SPAN></STRONG><SPAN> Run a quick check across your landscape for CDS views with @AccessControl.authorizationCheck: #NOT_REQUIRED — these are potential agent-accessible data leaks.</SPAN></LI></UL><H2 id="toc-hId--1397512405">Next Three to Six Months</H2><UL><LI><STRONG><SPAN>ABAP RAP (RESTful Application Programming Model).</SPAN></STRONG><SPAN> If you have been deferring it, stop. RAP is the model that produces the OData V4 services that Joule agents consume.</SPAN></LI><LI><STRONG><SPAN>SAP AI Core and SAP BTP basics.</SPAN></STRONG><SPAN> You do not need to become a BTP developer. Understand the platform well enough to design ABAP interfaces that integrate cleanly with it.</SPAN></LI><LI><STRONG><SPAN>Python literacy.</SPAN></STRONG><SPAN> Not fluency — literacy. Most AI tooling and agent orchestration frameworks are Python-first. Being able to read a Python agent script is now a professional responsibility.</SPAN></LI></UL><H2 id="toc-hId--1594025910">Strategic Awareness</H2><UL><LI><STRONG><SPAN>OpenClaw and MCP (Model Context Protocol).</SPAN></STRONG><SPAN> OpenClaw is the open-source agent OS. MCP is the protocol that defines how agents discover and call tools. SAP Joule implements MCP under the hood.</SPAN></LI><LI><STRONG><SPAN>HANA Vector Engine.</SPAN></STRONG><SPAN> HANA Cloud's vector engine brings unstructured data (PDFs, emails, contracts) directly into your SAP data layer.</SPAN></LI></UL><H1 id="toc-hId--1328952717">&nbsp;</H1><H1 id="toc-hId--1525466222">The Part Nobody Is Saying Loudly Enough</H1><P><SPAN>Jensen made a prediction that deserves more attention than it received.</SPAN></P><P><EM><FONT color="#339966">In the near future, every engineer at NVIDIA will receive an annual token budget — roughly equivalent to half their salary in additional compensation </FONT>— because AI-amplified engineers are demonstrably ten times more productive. Engineers are already asking: "<FONT color="#339966">How many tokens come with this job?"</FONT></EM></P><P><SPAN>Here is the part that matters for us specifically:</SPAN></P><P><STRONG><FONT color="#3366FF">AI tokens without SAP domain expertise produce plausible-looking but wrong ABAP.</FONT> </STRONG><SPAN>An LLM that does not understand the difference between a financial posting document and a parked document will generate code that compiles, passes basic tests, and silently corrupts your general ledger. It will call RFC_READ_TABLE in production because it found an example online. It will bypass the credit check in a sales order because it did not know the check existed.</SPAN></P><P><SPAN>Your twenty years of knowing where the bodies are buried in SAP — that is not a liability in an AI-augmented world. </SPAN><STRONG>It is the irreplaceable ingredient that makes the AI's output correct and trustworthy.</STRONG></P><P><SPAN>The developers who will thrive are not the ones who <STRONG>resist this shift</STRONG>. And they are not the <STRONG>ones who hand everything to an LLM</STRONG> and hope for the best. They are the ones who <STRONG>treat AI as a powerful amplifier of their own judgment</STRONG> — <FONT color="#3366FF">who know enough to direct it well, verify its output, and design the systems it integrates with</FONT>.</SPAN></P><P><SPAN>That combination — </SPAN><STRONG>deep SAP domain knowledge plus AI tool fluency</STRONG><SPAN> — is genuinely rare right now. The window to build it is open. It will not stay open long.</SPAN></P><H1 id="toc-hId--1721979727">&nbsp;</H1><H1 id="toc-hId--1918493232">Wrapping Up</H1><P><SPAN>GTC 2026 was not a technology conference for GPU enthusiasts. It was a signal that the enterprise software industry has passed an inflection point. Jensen's slide showing SAP, Salesforce, ServiceNow, and Siemens side by side — each with a production agentic architecture — was not a prediction of what is coming. It was a photograph of what has already happened.</SPAN></P><P><SPAN>SAP has placed its bet. Joule is real, BTP is the platform, and the structured data of your SAP landscape — managed, modelled, and secured by ABAP code — is what gives every agent running on top of it the ground truth it needs to be useful.</SPAN></P><TABLE width="935px"><TBODY><TR><TD width="934px"><P><STRONG>Action Items</STRONG></P><P>✓<SPAN>&nbsp; </SPAN>Write clean CDS views.</P><P>✓<SPAN>&nbsp; </SPAN>Lock down your authority checks.</P><P>✓<SPAN>&nbsp; </SPAN>Tune for machine-speed consumption.</P><P>✓<SPAN>&nbsp; </SPAN>Raise clear exceptions.</P><P>✓<SPAN>&nbsp; </SPAN>Learn RAP.</P><P>✓<SPAN>&nbsp; </SPAN>Open Claude Code.</P><P><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P></TD></TR></TBODY></TABLE><P class="lia-align-center" style="text-align: center;"><SPAN>The revolution is not coming for your job. It is coming for the parts of your job that should have been automated years ago. What remains — and what becomes more valuable — is everything that requires judgment, domain knowledge, and the ability to see when the AI is confidently wrong.</SPAN></P><P class="lia-align-center" style="text-align: center;"><FONT color="#3366FF"><STRONG>That is the ABAP developer of 2026.</STRONG></FONT></P> 2026-04-03T18:00:00.017000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-abap-ai-sapphire-and-asug-2026-sessions/ba-p/14365782 Joule for Developers ABAP AI Sapphire and ASUG 2026 Sessions 2026-04-04T17:52:59.936000+02:00 JanMatthes https://community.sap.com/t5/user/viewprofilepage/user-id/194386 <P data-unlink="true"><A title="ABAP AI Capabilities" href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><BR /><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="J4D_Agentic.png" style="width: 242px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/390078iDD4D1E72EFCEDA09/image-dimensions/242x242?v=v2" width="242" height="242" role="button" title="J4D_Agentic.png" alt="J4D_Agentic.png" /></span></A>In case you do not have planned your <STRONG>Sapphire and ASUG agenda</STRONG> here are my recommendations if you want to learn about the <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/our-2026-roadmap-for-joule-for-developers-abap-ai-capabilities/ba-p/14360358" target="_blank">latest innovations from ABAP Platform and Joule for developers (J4D) ABAP AI capabilities</A>:</P><P data-unlink="true"><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog/session/1770220974077001eR0r" target="_blank" rel="noopener noreferrer"><STRONG>1.&nbsp;Introduction to ABAP Cloud supported by generative AI | BTP1429:&nbsp;</STRONG></A>Get an overview on&nbsp;ABAP Cloud and recent innovations, get insights on Clean Core and see how generative AI boosts your adoption of ABAP Cloud conducted&nbsp;<STRONG>by Alexander Rother</STRONG> (VP, Head of ABAP Platform Product Management).</P><P data-unlink="true"><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog/session/1774374412394001bVsg" target="_blank" rel="noopener noreferrer"><STRONG>2.&nbsp;Build smarter: Agentic ABAP development tools for Visual Studio Code | BTP2573</STRONG></A>:&nbsp;<STRONG>Simona Marincei</STRONG> (Head of AI - SAP ABAP Platform) will show how ABAP agents orchestrate in VS Code via the ABAP MCP-server tasks, speed up coding, and boost productivity across orchestrators from various partners.</P><P data-unlink="true"><STRONG><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog/session/1770220933562001wFEi" target="_blank" rel="noopener noreferrer">3.&nbsp;Agentic ABAP with SAP Joule for Developers: Build faster, migrate smarter | JOU1428:</A></STRONG>&nbsp;<STRONG>Simona Marincei</STRONG> (Head of AI - SAP ABAP Platform) and <STRONG>Nora Klemp</STRONG> (Senior Product Specialist) will explain how&nbsp;agentic ABAP accelerates SAP S/4HANA migrations and streamline ABAP Cloud development across modern and legacy environments.</P><P data-unlink="true"><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog/session/1770745065449001Tvua" target="_blank" rel="noopener noreferrer"><STRONG>4.&nbsp;Customer Influence and feedback: The product road map for ABAP Cloud | BTP1603:</STRONG></A> Learn from&nbsp;<STRONG>Alexander Rother</STRONG> (VP, Head of ABAP Platform Product Management) how to give feedback to the ABAP product roadmap with the&nbsp;Customer Influence site which allows submitting, tracking, and prioritizing ideas.</P><P data-unlink="true"><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog/session/1770220536294001LBuf" target="_blank" rel="noopener noreferrer"><STRONG>5.&nbsp;Modernize classic extensions for clean core in SAP Cloud ERP Private | BTP1426:</STRONG></A> <STRONG>Volker Drees</STRONG> (Product Expert, ABAP Cloud, SAP SE) will explain&nbsp;clean core extensibility practice in SAP S/4HANA Cloud Private Edition. Learn how to govern clean core development using the ABAP test cockpit and how to use the ABAP Cloud development model and clean core extensibility principles to modernize your custom on-stack extensions.</P><P>&nbsp;</P><DIV class=""><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog?search=ABAP&amp;tab.sessionplanned=1692641568884001cZ9d" target="_blank" rel="noopener noreferrer"><STRONG>The full Sapphire and ASUG 2026 agenda can be found here.</STRONG></A></DIV><DIV class="">&nbsp;</DIV><DIV class=""><STRONG>Here you can learn more:</STRONG></DIV><OL><LI><SPAN class=""><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/our-2026-roadmap-for-joule-for-developers-abap-ai-capabilities/ba-p/14360358" target="_blank">Our Roadmap for 2026 before Sapphire</A></SPAN></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/your-2026-roadmap-to-getting-started-with-abap-ai-and-abap-1/ba-p/14312060" target="_blank"><SPAN class="">Your Roadmap for getting started with ABAP AI</SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/abap-ai-revolution-accelerates-the-abap-developer-who-built-enterprise-apps/ba-p/14216073" target="_blank"><SPAN class="">ABAP AI Revolution Accelerates: The ABAP Developer Who Built Enterprise Apps in Minutes </SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-next-era-of-abap-development/ba-p/14260522" target="_blank"><SPAN class="">Joule for Developers and ABAP AI capabilities are coming to SAP S/4HANA Private Edition 2021, 2022, and 2023</SPAN></A></LI><LI><SPAN class="">Public Roadmap: <A href="https://help.sap.com/docs/abap-cross-product/roadmap-info/genai" target="_blank" rel="noopener noreferrer">SAP Help</A> / <A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001562&amp;PRODUCT=73555000100800001164&amp;range=CURRENT-LAST" target="_blank" rel="noopener noreferrer">SAP Roadmap Explorer</A></SPAN></LI><LI><SPAN class="">Help &amp; Guides</SPAN><OL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-joule-for-developers-abap-ai-capabilities-for-sap-s-4hana-cloud-private/ba-p/14236954" target="_blank"><SPAN class="">Step-by-step guide how to activate SAP Joule for Developers, ABAP AI capabilities for your SAP S/4HANA Cloud Private Edition</SPAN></A></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-with-sap-s-4hana-public-cloud-edition-setup-guide/ba-p/14209989" target="_blank">Joule for Developers (J4D) for S/4HANA Public Cloud Setup Guide</A></SPAN></SPAN></LI><LI><A href="https://discovery-center.cloud.sap/search/abap%20ai" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>SAP ABAP AI Discovery Center</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://discovery-center.cloud.sap/search/Free-tier" target="_blank" rel="noopener nofollow noreferrer">SAP BTP Discovery Center (Free Tier Services)</A></SPAN></SPAN></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/custom-code-migration-to-sap-s-4hana-powered-by-sap-joule-for-developers/ba-p/14329094" target="_blank">Custom code migration to SAP S/4HANA powered by SAP Joule for Developers, ABAP AI capabilities</A> </SPAN></SPAN></LI><LI><A href="http://www.youtube.com/playlist?list=PL6RpkC85SLQAt9lvPw0gF4E3nwbJD0EUe" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>YouTube playlist for Joule for Developers (J4D)</SPAN></SPAN></A></LI><LI><A href="https://help.sap.com/docs/abap-ai" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>Joule for Developers Help (J4D)</SPAN></SPAN></A></LI><LI><A href="https://github.com/SAP-samples/abap-platform-rap120" target="_blank" rel="noopener nofollow noreferrer">Build SAP Fiori Apps with ABAP Cloud and SAP Joule for developers (RAP120)</A>&nbsp;</LI><LI><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>ADT Eclipse AI Capabilities Help</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://help.sap.com/docs/abap-ai/generative-ai-in-abap-cloud/set-up-abap-ai-sdk-powered-by-intelligent-scenario-lifecycle-management" target="_blank" rel="noopener noreferrer">ABAP AI SDK Help</A></SPAN></SPAN></LI><LI><A href="https://help.sap.com/docs/sap-ai-core/generative-ai/sap-abap-1?locale=en-US&amp;version=LATEST" target="_blank" rel="noopener noreferrer"><SPAN class="">ABAP-1 Help</SPAN></A></LI></OL></LI></OL><P data-unlink="true"><SPAN class="">More high-level insights about <A href="https://www.sap.com/sea/products/artificial-intelligence/joule-for-developers.html" target="_blank" rel="noopener noreferrer">Joule for Developers/ABAP AI</A> and <A href="https://www.sap.com/products/technology-platform/abap/environment.html" target="_blank" rel="noopener noreferrer">ABAP platform can be found&nbsp;here</A>&nbsp;. Here you find <A href="https://www.sap.com/products/artificial-intelligence/sap-abap.html" target="_blank" rel="noopener noreferrer">more on ABAP-&nbsp;1</A>,</SPAN></P> 2026-04-04T17:52:59.936000+02:00 https://community.sap.com/t5/artificial-intelligence-blogs-posts/how-i-connected-claude-ai-to-my-sap-abap-system-using-mcp-a-complete/ba-p/14365831 How I Connected Claude AI to My SAP ABAP System Using MCP — A Complete Windows Guide 2026-04-07T12:35:07.976000+02:00 Ahmed_Mosbah https://community.sap.com/t5/user/viewprofilepage/user-id/2292286 <P class=""><STRONG>Introduction</STRONG></P><P>The SAP developer community has been buzzing about connecting Claude AI&nbsp;directly to live SAP ABAP systems using MCP (Model Context Protocol) — reading code, modifying objects, creating transports, and activating changes, all from a natural language chat interface.</P><P>I tried it myself on Windows, and it works. This blog walks you through exactly how to set it up.</P><HR /><P class=""><STRONG>What is MCP?</STRONG></P><P class="">MCP (Model Context Protocol) is an open standard that lets AI models like Claude connect to external tools and data sources. Think of it as a plugin system for AI — instead of just answering questions from training data, Claude can actually <EM>call tools</EM> that interact with real systems.</P><P class="">For SAP developers, this means Claude can:</P><UL class=""><LI>Read your actual ABAP code directly from your system</LI><LI>Write and modify objects</LI><LI>Run syntax checks</LI><LI>Create transport requests</LI><LI>Activate objects</LI></UL><P class="">All without you copy-pasting anything.</P><HR /><P class=""><STRONG>The Architecture</STRONG></P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Claude Desktop / Claude Code CLI</SPAN><SPAN> ↕ MCP Protocol</SPAN><SPAN> ┌──────────────────────────┐</SPAN><SPAN> │ mcp-abap-adt │ ← Read-only (13 tools)</SPAN><SPAN> │ mcp-abap-abap-adt-api │ ← Full CRUD (30 tools)</SPAN><SPAN> └──────────────────────────┘</SPAN><SPAN> ↕ ADT REST API</SPAN><SPAN> Your SAP ABAP System</SPAN></CODE></PRE></DIV></DIV><P class="">Both MCP servers were built by Mario Andreschak and communicate with SAP via the same ADT (ABAP Development Tools) API that Eclipse uses under the hood.</P><HR /><P class=""><STRONG>Prerequisites</STRONG></P><P class="">Before starting, you need:</P><UL class=""><LI>Windows 10 or 11 (64-bit)</LI><LI>An SAP ABAP system with <CODE>/sap/bc/adt</CODE> active in SICF</LI><LI>A user with <CODE>SAP_ADT_DEVELOPER</CODE> role (or equivalent)</LI><LI>A Claude Pro/Max/Team subscription at claude.ai</LI><LI>Internet connection</LI></UL><HR /><P class=""><STRONG>Step 1 — Install Node.js</STRONG></P><P class="">Node.js is the runtime required by Claude Code CLI and the MCP servers.</P><OL class=""><LI>Go to <STRONG><A class="" href="https://nodejs.org" target="_blank" rel="noopener nofollow noreferrer">https://nodejs.org</A></STRONG> and download the LTS version</LI><LI>Install with all defaults</LI><LI>Verify in Command Prompt:</LI></OL><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>node -v → v24.x.x</SPAN><SPAN>npm -v → 11.x.x</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Step 2 — Install Git for Windows</STRONG></P><P class="">Git provides the bash shell Claude Code requires on Windows.</P><OL class=""><LI>Go to <STRONG><A class="" href="https://git-scm.com/downloads/win" target="_blank" rel="noopener nofollow noreferrer">https://git-scm.com/downloads/win</A></STRONG> and download the installer</LI><LI>During setup, on the PATH screen select: <EM>"Git from the command line and also from 3rd-party software"</EM></LI><LI>Complete with all other defaults</LI></OL><HR /><P class=""><STRONG>Step 3 — Install Claude Code CLI</STRONG></P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>npm install -g @anthropic-ai/claude-code</SPAN><SPAN>claude --version</SPAN></CODE></PRE></DIV></DIV><P class="">Then log in:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude</SPAN></CODE></PRE></DIV></DIV><P class="">Select option 1 (Claude subscription), log in via browser, return to terminal.</P><HR /><P class=""><STRONG>Step 4 — Install mcp-abap-adt (Read-Only MCP Server)</STRONG></P><P class="">This server gives Claude read access to your SAP system with 13 tools including GetProgram, GetClass, GetFunction, GetTable, SearchObject, and more.</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>mkdir C:\Tools</SPAN><SPAN>cd C:\Tools</SPAN><SPAN>git clone https://github.com/mario-andreschak/mcp-abap-adt</SPAN><SPAN>cd mcp-abap-adt</SPAN><SPAN>npm install</SPAN><SPAN>npm run build</SPAN></CODE></PRE></DIV></DIV><P class="">Create a <CODE>.env</CODE> file in the folder:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>SAP_URL=https://your-sap-system.com:44300</SPAN><SPAN>SAP_USERNAME=YOUR_USERNAME</SPAN><SPAN>SAP_PASSWORD=YOUR_PASSWORD</SPAN><SPAN>SAP_CLIENT=300</SPAN><SPAN>TLS_REJECT_UNAUTHORIZED=0</SPAN></CODE></PRE></DIV></DIV><P class="">Register with Claude Code:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add mcp-abap-adt node C:/Tools/mcp-abap-adt/dist/index.js</SPAN><SPAN>claude mcp list</SPAN></CODE></PRE></DIV></DIV><P class="">You should see: <CODE>mcp-abap-adt: ✓ Connected</CODE></P><HR /><P class=""><STRONG>Step 5 — Install mcp-abap-abap-adt-api (Full CRUD Server)</STRONG></P><P class="">This is the powerful one — 30 tools including read, write, syntax check, activate, lock/unlock, and transport management.</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>cd C:\Tools</SPAN><SPAN>git clone https://github.com/mario-andreschak/mcp-abap-abap-adt-api.git</SPAN><SPAN>cd mcp-abap-abap-adt-api</SPAN><SPAN>npm install</SPAN><SPAN>npm run build</SPAN></CODE></PRE></DIV></DIV><P class="">Create <CODE>.env</CODE> (note: slightly different variable names):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>SAP_URL=https://your-sap-system.com:44300</SPAN><SPAN>SAP_USER=YOUR_USERNAME</SPAN><SPAN>SAP_PASSWORD=YOUR_PASSWORD</SPAN><SPAN>SAP_CLIENT=300</SPAN><SPAN>SAP_LANGUAGE=EN</SPAN><SPAN>NODE_TLS_REJECT_UNAUTHORIZED=0</SPAN></CODE></PRE></DIV></DIV><P class="">Register:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add mcp-abap-adt-api node C:/Tools/mcp-abap-abap-adt-api/dist/index.js</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Step 6 — Setup Claude Desktop (GUI Interface)</STRONG></P><P class="">Claude Desktop is where it really comes alive — a beautiful chat UI like the LinkedIn video.</P><OL class=""><LI>Download from <STRONG><A class="" href="https://claude.ai/download" target="_blank" rel="noopener nofollow noreferrer">https://claude.ai/download</A></STRONG></LI><LI>Install and log in</LI><LI>Go to <STRONG>☰ → Settings → Developer → Edit Config</STRONG></LI><LI>Replace the content with:</LI></OL><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">json</DIV><DIV class=""><PRE><CODE><SPAN><SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"mcpServers"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"mcp-abap-adt"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"command"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"C:\\Program Files\\nodejs\\node.exe"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"args"</SPAN><SPAN class="">:</SPAN> <SPAN class="">[</SPAN><SPAN class="">"C:\\Tools\\mcp-abap-adt\\dist\\index.js"</SPAN><SPAN class="">]</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"env"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_URL"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"https://your-sap-system.com:44300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_USERNAME"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_USERNAME"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_PASSWORD"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_PASSWORD"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_CLIENT"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"TLS_REJECT_UNAUTHORIZED"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"0"</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"mcp-abap-adt-api"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"command"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"C:\\Program Files\\nodejs\\node.exe"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"args"</SPAN><SPAN class="">:</SPAN> <SPAN class="">[</SPAN><SPAN class="">"C:\\Tools\\mcp-abap-abap-adt-api\\dist\\index.js"</SPAN><SPAN class="">]</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"env"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_URL"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"https://your-sap-system.com:44300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_USER"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_USERNAME"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_PASSWORD"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_PASSWORD"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_CLIENT"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_LANGUAGE"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"EN"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"NODE_TLS_REJECT_UNAUTHORIZED"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"0"</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN><SPAN class="">}</SPAN></SPAN></CODE></PRE></DIV></DIV><BLOCKQUOTE><P class=""><span class="lia-unicode-emoji" title=":warning:">⚠️</span> <STRONG>Windows-specific tip:</STRONG> You MUST use the full path <CODE>C:\\Program Files\\nodejs\\node.exe</CODE> — using just <CODE>"node"</CODE> does not work in Claude Desktop on Windows. Also note double backslashes <CODE>\\</CODE> in all paths.</P></BLOCKQUOTE><OL class=""><LI>Kill Claude in Task Manager and reopen</LI><LI>Go back to Settings → Developer — you should see both servers listed as <STRONG>running</STRONG> <span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span></LI></OL><HR /><P class=""><STRONG>Step 7 — Add Free Official SAP MCP Servers</STRONG></P><P class="">Bonus: Claude Desktop has a built-in directory of official SAP MCP servers. Click <EM>"Connect your tools to Claude"</EM> at the bottom of the chat, search for "SAP", and add:</P><UL class=""><LI><STRONG>SAPUI5 MCP Server</STRONG> — for UI5 development</LI><LI><STRONG>SAP CAP MCP Server</STRONG> — for CAP projects</LI><LI><STRONG>SAP Fiori MCP Server</STRONG> — for Fiori Elements apps</LI></UL><P class="">Also add these free hosted servers to Claude Code CLI (no installation needed):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add --transport http abap-docs https://mcp-abap.marianzeis.de/mcp</SPAN><SPAN>claude mcp add --transport http sap-docs https://mcp-sap-docs.marianzeis.de/mcp</SPAN></CODE></PRE></DIV></DIV><P class="">These give Claude access to the full ABAP keyword documentation across 8 SAP releases, ABAP cheat sheets, CAP docs, UI5 docs, and SAP Community posts.</P><HR /><P class=""><STRONG>Testing It</STRONG></P><P class="">Open Claude Desktop, create a New Chat, and type:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Get the source code of program SAPMV45A</SPAN></CODE></PRE></DIV></DIV><P class="">Watch Claude automatically call your SAP system, retrieve the source code, and explain it — all in seconds.</P><P class="">For write operations (test on $TMP objects only!):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Find a simple Z program in $TMP, add a comment at the top </SPAN><SPAN>saying "Modified by Claude", save and activate it</SPAN></CODE></PRE></DIV></DIV><P class="">For complex workflows like the LinkedIn video:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Connect to my SAP system. Copy class ZCL_SOURCE from package </SPAN><SPAN>ZPKG_A into ZPKG_B, rename it to ZCL_TARGET, change the </SPAN><SPAN>carrier_id in the SELECT for /DMO/CONNECTION, create a </SPAN><SPAN>transport and activate.</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Security Notes</STRONG></P><UL class=""><LI>Never commit <CODE>.env</CODE> files to Git</LI><LI>Change your SAP password if shared in screenshots</LI><LI>Use dedicated service accounts with minimum required authorizations</LI><LI>Only test write operations in $TMP before moving to real packages</LI><LI>The <CODE>TLS_REJECT_UNAUTHORIZED=0</CODE> flag disables SSL validation — use only in dev environments</LI><LI>Check your company's AI policy before sending code to external APIs</LI></UL><HR /><P class=""><STRONG>My Experience</STRONG></P><P class="">What surprised me most is how Claude handles the entire workflow autonomously. It doesn't just write code — it searches for the object, reads the source, understands the structure, reads class includes, creates the transport, locks the object, writes the code, runs a syntax check, activates, and unlocks. All from one natural language request.</P><P class="">&nbsp;</P><P class=""><STRONG>Important Hint</STRONG></P><P class="">It can make ABAP-specific mistakes (like forgetting RAP locking fields, or using reserved DDIC words). Always review AI-generated code before activating in production. But as a development accelerator and code reviewer, it's genuinely powerful.</P><HR /><P class=""><STRONG>References</STRONG></P><UL class=""><LI>GitHub: <A class="" href="https://github.com/mario-andreschak/mcp-abap-adt" target="_blank" rel="noopener nofollow noreferrer">mcp-abap-adt</A> — Mario Andreschak</LI><LI>GitHub: <A class="" href="https://github.com/mario-andreschak/mcp-abap-abap-adt-api" target="_blank" rel="noopener nofollow noreferrer">mcp-abap-abap-adt-api</A> — Mario Andreschak</LI><LI>GitHub: <A class="" href="https://github.com/secondsky/sap-skills" target="_blank" rel="noopener nofollow noreferrer">sap-skills</A> — 35 Claude Code plugins for SAP</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/technology-blog-posts-by-members/feed-sap-help-ui5-apis-amp-sap-community-content-into-your-ai-with-this/ba-p/14195007" target="_blank">SAP Docs MCP Server</A> — Marian Zeis</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/claude-code-via-mcp-poor-man-s-joule-or-a-practical-tool/ba-p/14344261" target="_blank">Claude Code via MCP</A> — SAP Community</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/installing-and-extending-an-abap-mcp-server-by-vibe-coding-with-claude-code/ba-p/14343600" target="_blank">Installing and Extending an ABAP MCP Server</A> — SAP Community</LI></UL><HR /><P class=""><EM>I hope this helps other ABAP developers get started. If you run into issues or have questions, feel free to comment below. Happy coding!</EM></P> 2026-04-07T12:35:07.976000+02:00 https://community.sap.com/t5/human-capital-management-blog-posts-by-members/hrform-sending-payslips-to-individual-employees-from-sap-to-outlook-or/ba-p/14366425 HRFORM - Sending Payslips to Individual Employees from SAP to Outlook or Mails - for all countries 2026-04-07T13:23:33.058000+02:00 jagadee https://community.sap.com/t5/user/viewprofilepage/user-id/844362 <H3 id="toc-hId-1922420102">Introduction</H3><P><BR />Are you an ABAP developer working in the HCM module, HR ABAP? Explore this blog to learn how to create a custom program for sending employee pay slips by mail.</P><H3 id="toc-hId-1725906597"><BR />Requirement</H3><P><BR />Even though Payslips are accessible in EC, clients will often ask us to send them by mail as attachments.<BR /><BR /></P><H3 id="toc-hId-1529393092">Challenges</H3><P>1. There are no standard reports available for all the countries to send payslips by mail, like the one for India.&nbsp;<BR />2. Also, developing a report from scratch is very complex for HR Forms.</P><H3 id="toc-hId-1332879587"><BR /><BR />Steps to create a custom report</H3><P><BR /><BR />1. We are not going to create a report from Scratch; SAP already developed a report for India&nbsp;<STRONG>HINU_HRFORMS_MAIL</STRONG>, but for other countries, standard reports are not available.</P><P>Changes in the report: Change the default constant and parameter values (your custom HR Form name, country grouping, payroll area for your country, etc).<BR /><BR />Code for your reference</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>CONSTANTS : gc_applogname TYPE balobj_d VALUE 'ZHRPAYSLIP', gc_applogsubname TYPE balsubobj VALUE 'ZHRFORM_MAIL'. PARAMETERS: p_molga LIKE thrforms_01-molga VALUE CHECK DEFAULT '24', p_fclass TYPE hrf_class VALUE CHECK DEFAULT 'PAYSLIP', "thrforms_01-formclass p_fname LIKE thrforms_01-infonet OBLIGATORY DEFAULT 'ZHR_PAYSLIP'.</code></pre><P>&nbsp;</P><P><BR />2. This report will work after implementing the BADI&nbsp;<STRONG>HRFORM_HRF02; </STRONG>otherwise, we can only display the payslip.<BR /><BR />3. Write your own logic to send mail in the method&nbsp;<STRONG>AFTER_PDF_PRINT. </STRONG>Also sample implementation class is available for our reference.</P><P><STRONG>Report Analysis</STRONG><BR /><BR />1. This is a SUBMIT program of the HRFORM report.</P><P>2. It needs a BADI implementation of&nbsp;<STRONG>HRFORM_HRF024.</STRONG></P><P>3. Functionality is the same as HRFORM display tcode, e.g.,&nbsp;PC00_M24_HRF, etc.</P><P>4. Designed with SLG1 log. (log gets updated in SLG1 after running the report).</P><H3 id="toc-hId-1136366082"><BR />Results &amp; thoughts</H3><P><BR />With the help of the&nbsp;<STRONG>HINU_HRFORMS_MAIL report,&nbsp;</STRONG>we can develop our custom report to send a payslip as an attachment to all employees. And it would be better if SAP had given a standard report for other countries, too or else any SAP Support Note for reference, mentioning this report.</P> 2026-04-07T13:23:33.058000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/custom-business-configurations-f4579-collaborative-draft/ba-p/14368541 Custom Business Configurations (F4579): Collaborative draft 2026-04-08T10:55:35.536000+02:00 patrick_winkler https://community.sap.com/t5/user/viewprofilepage/user-id/729521 <H1 id="toc-hId-887480474" id="toc-hId-1664315265">Introduction</H1><P><SPAN>The&nbsp;</SPAN><A href="https://help.sap.com/docs/btp/sap-business-technology-platform/custom-business-configurations-app" target="_blank" rel="noopener noreferrer"><SPAN class="">Custom Business Configurations</SPAN></A><SPAN>&nbsp;(CUBCO) app serves as an entry point to the&nbsp;</SPAN><A class="" title="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/business-configuration-maintenance-object?version=Cloud" href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/business-configuration-maintenance-object?version=Cloud" target="_blank" rel="noopener noreferrer">Business Configuration Maintenance Object</A><SPAN>&nbsp;(SMBC) provided by custom applications or partners.<BR /><BR />When you use the&nbsp;<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/generating-business-configuration-maintenance-object-with-generate-abap-repository-objects-wizard" target="_blank" rel="noopener noreferrer">ADT wizard to generate a Business Configuration Maintenance Object</A></SPAN>, the singleton pattern is used when generating the draft enabled RAP BO. One <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/rap-transactional-app-performance-considerations-for-singleton-pattern-in/ba-p/14140680" target="_blank">characteristic of this pattern</A> is that all child entities are locked together, so it is not possible for multiple users to work with the same configuration at the same time.<BR /><BR />This blog describes how to avoid this restriction by using <A href="https://help.sap.com/docs/abap-cloud/abap-rap/collaborative-draft" target="_blank" rel="noopener noreferrer">collaborative draft</A>.</P><P>This blog is relevant for</P><UL><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+S%25252F4HANA+Cloud+Private+Edition/pd-p/5c26062a-9855-4f39-8205-272938b6882f" class="lia-product-mention" data-product="1198-1">SAP S/4HANA Cloud Private Edition</a>&nbsp;(2025)</LI><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+BTP+ABAP+environment/pd-p/73555000100800001164" class="lia-product-mention" data-product="11-1">SAP BTP ABAP environment</a>&nbsp;</LI><LI><a href="https://community.sap.com/t5/c-khhcw49343/SAP+S%25252F4HANA+Cloud+Public+Edition/pd-p/08e2a51b-1ce5-4367-8b33-4ae7e8b702e0" class="lia-product-mention" data-product="1199-1">SAP S/4HANA Cloud Public Edition</a>&nbsp;</LI></UL><P>Further reading:</P><UL><LI><A href="https://community.sap.com/t5/tag/business%20configuration%20maintenance%20object/tg-p/board-id/technology-blog-sap" target="_blank">Related blog posts</A></LI><LI>Learn how you can use<SPAN>&nbsp;</SPAN><A href="https://learning.sap.com/products/business-technology-platform/development/abap?url_id=text-sapcommunity-prdteng-ABAP" target="_blank" rel="noopener noreferrer">ABAP technology</A><SPAN>&nbsp;</SPAN>to develop innovative applications and business solutions across SAP’s portfolio on<SPAN>&nbsp;</SPAN><A href="https://learning.sap.com/products/business-technology-platform/development/abap" target="_blank" rel="noopener noreferrer">SAP Learning Site</A>.</LI></UL><H1 id="toc-hId-1439888495" id="toc-hId-1467801760">Example scenario</H1><P>In the configuration table ZDEMO_CC, the company codes are stored.</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Company Code' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #C @AbapCatalog.dataMaintenance : #ALLOWED define table zdemo_cc { key client : abap.clnt not null; key company_code : abap.numc(4) not null; country : land1; last_changed_at : abp_lastchange_tstmpl; local_last_changed_at : abp_locinst_lastchange_tstmpl; }</code></pre><H1 id="toc-hId-1271288255">Enable collaborative draft</H1><P>In the generated behavior definition, add "collaborative" to the draft annotation:</P><pre class="lia-code-sample language-abap"><code>managed with additional save implementation in class ZBP_I_COMPANYCODE_S unique; strict; with collaborative draft;</code></pre><P>Add the draft query annotation and the share action to the singleton entity definition:</P><pre class="lia-code-sample language-abap"><code>define behavior for ZI_CompanyCode_S alias CompanyCodeAll draft table ZDEMO_CC_D_S query ZR_DEMO_CC_CD [...] { draft action Share; [...] }</code></pre><P>&nbsp;<SPAN>Right-click the singleton draft table and choose New Data Definition to create the CDS view for the draft query:<BR /></SPAN></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Draft Query View' define view entity ZR_DEMO_CC_CD as select from zdemo_cc_d_s { key singletonid as Singletonid, lastchangedatmax as Lastchangedatmax, transportrequestid as Transportrequestid, draftentitycreationdatetime as Draftentitycreationdatetime, draftentitylastchangedatetime as Draftentitylastchangedatetime, draftadministrativedatauuid as Draftadministrativedatauuid, draftentityoperationcode as Draftentityoperationcode, hasactiveentity as Hasactiveentity, draftfieldchanges as Draftfieldchanges }</code></pre><P>You need to <A href="https://help.sap.com/docs/abap-cloud/abap-rap/adding-collaboration-capability-to-draft-enabled-managed-business-object?version=LATEST&amp;locale=en-US&amp;state=PRODUCTION#prerequisites" target="_self" rel="noopener noreferrer">enhance the authorization of the involved users</A>. In SAP BTP ABAP environment and SAP S/4HANA Public Cloud Edition you assign business catalog&nbsp;<SPAN>SAP_CORE_BC_RAP_DRAFT_PC to the user, in SAP S/4HANA Private Cloud Edition authorization object S_DRAFT.</SPAN></P><H1 id="toc-hId-1074774750"><SPAN>Collaboration</SPAN></H1><P><SPAN>User TB is creating a new company code 400 while at the same time user PW is editing company code 100. All changes are recorded on the same transport request.<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="patrick_winkler_0-1775638407159.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394868i8F2BB89D6419285F/image-size/large?v=v2&amp;px=999" role="button" title="patrick_winkler_0-1775638407159.png" alt="patrick_winkler_0-1775638407159.png" /></span></P><P>Since the collaborative draft is enabled for the singleton root entity, the save and discard draft action are applied to all object changes. In this example, users PW and TB process two different company codes, which are logically different objects. Technically, however, they process the same singleton root entity. In practice, this means that discarding the draft or saving must be aligned between the users involved, as the save action persists the changes in all company codes.<BR />For completely independent editing of individual objects, you must develop a RAP BO without a singleton pattern.</P> 2026-04-08T10:55:35.536000+02:00 https://community.sap.com/t5/artificial-intelligence-blogs-posts/github-copilot-for-sap-abap-in-vs-code-setup-guide-for-on-premise-teams/ba-p/14365497 GitHub Copilot for SAP ABAP in VS Code: Setup Guide for On-Premise Teams 2026-04-09T08:24:40.755000+02:00 shaikferoz https://community.sap.com/t5/user/viewprofilepage/user-id/706305 <H1 id="toc-hId-1664225092">How I Got Here — My Personal Experience</H1><P>I’ve been working in SAP for close to 20 years now. Over that time, I’ve seen the development landscape evolve from SE38 and SE80 to Eclipse ADT, from classical ABAP to ABAP OO, and now RAP. But nothing has shifted the day-to-day developer experience as quickly as AI-assisted coding.</P><P>When our team started discussing AI tools for ABAP development, the first name that came up was SAP Joule. It looked promising, deeply trained on SAP code, integrated into Eclipse ADT, and purpose-built for ABAP. But when I dug into the availability details, I hit a wall: Joule for Developers is not available for on-premise S/4HANA systems. Our landscape is on-premises, and that wasn’t going to change overnight.</P><P>So I started exploring what else was out there. I looked at Amazon Q Developer, which has strong ABAP capabilities and an impressive ABAP Accelerator MCP server. But it required standing up AWS infrastructure. Then I checked GitHub Copilot and realized our organization already had Copilot Business licenses under our GitHub Enterprise agreement. The path of least resistance was clear.</P><P>I set it up on a Friday afternoon. By Monday morning, I was using it in real development work. The speed at which I became productive surprised me. I honestly expected a longer ramp-up.</P><H2 id="toc-hId-1596794306">What Surprised Me Most</H2><P>I initially set up Copilot in both Eclipse ADT and VS Code, expecting roughly the same experience. I was wrong. The Eclipse plugin gives you solid code completions and a useful chat panel, but VS Code with Agent Mode is on a different level entirely. The first time I described a multi-step task in natural language and watched the agent plan its approach, create files, and iterate on errors autonomously, I knew this was going to change how my team works.</P><P>One moment that stood out: I pointed Agent Mode at a legacy report that nobody on the current team had written. Within minutes, it had analyzed the entire program, generated a functional description, flagged two performance issues with nested SELECTs, and suggested refactored code with JOINs. That single interaction would have taken a developer half a day to do manually.</P><P>Another area where I’ve seen real value is unit test generation. Let’s be honest, ABAP Unit tests are often the first thing that gets cut from project timelines. With Copilot’s /tests command, you can generate a solid test scaffold in seconds. It’s not perfect, you still need to review and adjust, but it removes the biggest barrier, which is the blank-page problem of writing test classes from scratch.</P><H1 id="toc-hId-1271198082">The AI Landscape for On-Premise ABAP Teams</H1><P>If you’re on an on-premise SAP system, here’s where things stand today:</P><TABLE width="656"><TBODY><TR><TD width="140"><P><STRONG>Solution</STRONG></P></TD><TD width="100"><P><STRONG>On-Premise?</STRONG></P></TD><TD width="176"><P><STRONG>IDE Support</STRONG></P></TD><TD width="240"><P><STRONG>Key Consideration</STRONG></P></TD></TR><TR><TD width="140"><P>SAP Joule</P></TD><TD width="100"><P>No</P></TD><TD width="176"><P>Eclipse ADT</P></TD><TD width="240"><P>Cloud only (BTP / S/4HANA Cloud)</P></TD></TR><TR><TD width="140"><P>Amazon Q Developer</P></TD><TD width="100"><P>Yes</P></TD><TD width="176"><P>Eclipse, VS Code, BAS</P></TD><TD width="240"><P>Requires AWS ecosystem</P></TD></TR><TR><TD width="140"><P>GitHub Copilot</P></TD><TD width="100"><P>Yes</P></TD><TD width="176"><P>Eclipse ADT, VS Code</P></TD><TD width="240"><P>Broad model choice, mature Agent Mode</P></TD></TR></TBODY></TABLE><P>I went with GitHub Copilot because we already had the licenses. Your mileage may vary, if your organization is on AWS, Amazon Q Developer is absolutely worth evaluating. The important thing is that on-premise ABAP teams are no longer locked out of AI-assisted development.</P><H1 id="toc-hId-1074684577">Eclipse vs. VS Code — What I Found</H1><P>For AI-powered development tasks, VS Code with Copilot Agent Mode is in a different league.</P><P><STRONG>Eclipse ADT + Copilot: </STRONG>Good code completions, a helpful chat panel, and basic agent support that’s been improving with each release. For day-to-day ABAP work, it’s a meaningful step forward.</P><P><STRONG>VS Code + Copilot: </STRONG>Everything Eclipse has, plus fully autonomous Agent Mode with multi-step planning, terminal integration, and direct SAP system awareness through the ABAP FS extension. This is where I do my complex development work now.</P><H1 id="toc-hId-878171072">Installation Steps</H1><P>Here’s the exact setup I followed. The whole process took me about 30–45 minutes, and I was productive immediately after.</P><P><STRONG>Step 1:&nbsp; </STRONG><STRONG>Install Visual Studio Code</STRONG></P><P>Download and install the latest version of VS Code from code.visualstudio.com. I’d recommend getting the latest stable release — older versions may not support all Copilot features.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_0-1775502991777.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393818i1FD5148B509733B3/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_0-1775502991777.png" alt="shaikferoz_0-1775502991777.png" /></span></P><P><STRONG>Step 2:&nbsp; </STRONG><STRONG>Install ABAP Remote Filesystem Extension</STRONG></P><P>This is the extension that makes VS Code talk to your SAP system. Without it, Copilot has no ABAP context — with it, the AI can see your actual system objects.</P><UL><LI>&nbsp; Open VS Code and navigate to Extensions (Ctrl+Shift+X)</LI><LI>&nbsp; Search for and install ABAP Remote Filesystem</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_1-1775502991783.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393819iDBF7067F455DFDAE/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_1-1775502991783.png" alt="shaikferoz_1-1775502991783.png" /></span></P><UL><LI>&nbsp; Click on the extension settings to configure</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_2-1775502991790.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393820i382FE0B9ED08DF26/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_2-1775502991790.png" alt="shaikferoz_2-1775502991790.png" /></span></P><UL><LI>&nbsp; Click on Abapfs: Remote to add your SAP system</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_3-1775502991794.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393822iFEA7250D9F485C49/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_3-1775502991794.png" alt="shaikferoz_3-1775502991794.png" /></span></P><P>Add the SAP system connection details. I configured both our DEV and SBX systems here. Use placeholder values if you’re just testing the setup initially.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_4-1775502991798.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393821i51F1A3673AF8733F/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_4-1775502991798.png" alt="shaikferoz_4-1775502991798.png" /></span></P><P><STRONG>Step 3:&nbsp; </STRONG><STRONG>Install SAP Web IDE Adapter for VS Code</STRONG></P><P>This extension enables SAP-specific development workflows within VS Code. It’s a small addition but it rounds out the SAP development experience.</P><UL><LI>&nbsp; From the Extensions marketplace, install SAP Web IDE Adapter</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_5-1775502991803.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393823iC07C8AB2DA300571/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_5-1775502991803.png" alt="shaikferoz_5-1775502991803.png" /></span></P><P><STRONG>Step 4:&nbsp; </STRONG><STRONG>Install SAP Joule Studio Code Extension</STRONG></P><P>Even though Joule isn’t available for on-premise ABAP, I installed the Joule Studio Code Editor extension anyway — it’s useful if you also work with BTP environments, and it doesn’t interfere with Copilot.</P><UL><LI>&nbsp; Install SAP Joule (Joule Studio Code Editor) from the Extensions marketplace</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_6-1775502991808.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393825i8B526A131DF9F6A8/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_6-1775502991808.png" alt="shaikferoz_6-1775502991808.png" /></span></P><P><STRONG>Step 5:&nbsp; </STRONG><STRONG>Install GitHub Copilot Extension</STRONG></P><P>This is the main event. Install the GitHub Copilot extension and sign in with your company’s GitHub account.</P><UL><LI>&nbsp; Install GitHub Copilot from the VS Code Extensions marketplace</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_7-1775502991814.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393824i88C9B1FC608914BA/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_7-1775502991814.png" alt="shaikferoz_7-1775502991814.png" /></span></P><UL><LI>&nbsp; Sign in using your Company GitHub account and ensure Copilot is enabled</LI></UL><P>A tip from my experience: if your company uses SSO for GitHub, make sure you complete the authentication through the browser window that pops up. I initially missed this and spent 10 minutes wondering why Copilot wasn’t activating.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_8-1775502991823.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393826iE3DC9B4330A63F04/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_8-1775502991823.png" alt="shaikferoz_8-1775502991823.png" /></span></P><P><STRONG>Step 6:&nbsp; </STRONG><STRONG>Activate ADT Service on SAP System</STRONG></P><P>This is the SAP Basis step. Make sure the ADT service is active in transaction SICF. If your Basis team hasn’t already enabled this for Eclipse ADT, you’ll need to request it.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_9-1775502991827.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393829i216D600E4C8D493F/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_9-1775502991827.png" alt="shaikferoz_9-1775502991827.png" /></span></P><P><STRONG>Step 7:&nbsp; </STRONG><STRONG>Connect to the SAP System</STRONG></P><P>Now connect VS Code to your SAP system. This is the moment where everything comes together.</P><UL><LI>&nbsp; Open the Command Palette (Ctrl+Shift+P)</LI><LI>&nbsp; Run: ABAP FS: Connect to an ABAP system</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_10-1775502991829.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393828iAA96F6610463D07F/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_10-1775502991829.png" alt="shaikferoz_10-1775502991829.png" /></span></P><UL><LI>&nbsp; Select the SAP system to connect</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_11-1775502991831.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393827i551EB3BF667313C4/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_11-1775502991831.png" alt="shaikferoz_11-1775502991831.png" /></span></P><P><STRONG>Step 8:&nbsp; </STRONG><STRONG>Verify SAP System Connection</STRONG></P><P>Once connected, you should see your SAP system’s object tree in the Explorer pane. When I first saw our $TMP package, Core Data Services, and Source Code Library appear in VS Code, it felt like two worlds merging.</P><UL><LI>&nbsp; Confirm the connected SAP system appears under ABAP Remote Filesystem</LI><LI>&nbsp; You should now be able to browse SAP objects remotely</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_12-1775502991833.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393831i963DF61AE70D9C29/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_12-1775502991833.png" alt="shaikferoz_12-1775502991833.png" /></span></P><P><STRONG>Step 9:&nbsp; </STRONG><STRONG>Verify GitHub Copilot and Model Availability</STRONG></P><P>Finally, confirm that Copilot is active and check which AI models your organization has approved. In our case, we have access to Claude Haiku, Claude Opus, Claude Sonnet, and GPT models. I primarily use Claude Haiku for quick tasks and Claude Sonnet for complex agent work.</P><UL><LI>&nbsp; Confirm that GitHub Copilot is active in the editor</LI><LI>&nbsp; Verify that your company-approved AI models are available</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_13-1775502991836.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393830i4C0BEA98242FC485/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_13-1775502991836.png" alt="shaikferoz_13-1775502991836.png" /></span></P><H1 id="toc-hId-681657567">Quick Start: Using Copilot for ABAP in VS Code</H1><P>Once installed, open the Copilot Chat panel (Ctrl+Alt+I) and choose your mode. Here’s how I use each one in practice:</P><H2 id="toc-hId-614226781">Ask Mode — My Go-To for Quick Answers</H2><P>I use this multiple times a day. Instead of searching SAP Help or opening a browser, I just ask Copilot directly in the IDE. It’s especially useful for BAPIs and function modules I don’t work with regularly.</P><P><EM>“Explain how BAPI_USER_GET_DETAIL works”</EM></P><P><EM>“Best practices for exception handling in ABAP OO?”</EM></P><H2 id="toc-hId-417713276">Edit Mode — For Targeted Refactoring</H2><P>When I have existing code open and want specific changes, I select the code, press Ctrl+I, and describe what I need. This has been particularly useful for modernizing older code patterns.</P><P><EM>“Refactor this to use NEW instead of CREATE OBJECT”</EM></P><P><EM>“Optimize this to use a JOIN instead of nested SELECTs”</EM></P><H2 id="toc-hId-221199771">Agent Mode — Where the Magic Happens</H2><P>This is the feature that changed my workflow. I describe a complex task and let the agent figure out the approach. It plans, generates, reviews its own output, and iterates. Not every result is perfect on the first try, but the starting point it gives you is usually 70–80% there.</P><P><EM>“Create an ABAP class ZCL_BP_VALIDATOR with unit tests for BP number validation”</EM></P><P><EM>“Analyze program ZSALES_ORDER_REPORT — generate documentation and flag performance issues”</EM></P><P><EM>“Create a complete RAP application for insurance claims with CDS views, behavior definition, and service binding”</EM></P><H2 id="toc-hId-24686266">Slash Commands I Use Daily</H2><P>These are quick shortcuts in the chat panel that I’ve made part of my routine:</P><UL><LI>&nbsp; <STRONG>/explain</STRONG> — I use this constantly on unfamiliar legacy code</LI><LI>&nbsp; <STRONG>/fix</STRONG> — Helpful when I get a syntax error I can’t immediately spot</LI><LI>&nbsp; <STRONG>/tests</STRONG> — My favorite — generates unit test scaffolds in seconds</LI><LI>&nbsp; <STRONG>/doc</STRONG> — Generates inline documentation for methods and classes</LI></UL><H2 id="toc-hId-175427118">Creating and Searching Custom Objects</H2><P>One thing I didn’t expect was how smooth object creation is directly from VS Code. Enter the ‘&gt;’ command to list options, then select ABAP Create Object.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_14-1775502991839.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393832i0D10776C43EBE4A3/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_14-1775502991839.png" alt="shaikferoz_14-1775502991839.png" /></span></P><UL><LI>&nbsp; Select the object type to be created</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_15-1775502991842.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393833iD1D94A1030D23792/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_15-1775502991842.png" alt="shaikferoz_15-1775502991842.png" /></span></P><UL><LI>&nbsp; Enter the object name</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_16-1775502991845.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393835i73179D9BB40B0E9A/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_16-1775502991845.png" alt="shaikferoz_16-1775502991845.png" /></span></P><UL><LI>&nbsp; Enter the description</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_17-1775502991847.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393834i36860D54040E72EC/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_17-1775502991847.png" alt="shaikferoz_17-1775502991847.png" /></span></P><UL><LI>&nbsp; Enter the package and transport number to save</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_18-1775502991848.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393836iCFD9E2DC67D68406/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_18-1775502991848.png" alt="shaikferoz_18-1775502991848.png" /></span></P><P>For searching existing objects, use the ABAP Search for Object command. The filter option is handy when you’re looking for a specific object type.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_19-1775502991852.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393838iD42BAC78B1EFB9D2/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_19-1775502991852.png" alt="shaikferoz_19-1775502991852.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_20-1775502991855.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393837i0D045DA105CC2120/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_20-1775502991855.png" alt="shaikferoz_20-1775502991855.png" /></span></P><H1 id="toc-hId-272316620">Custom Instructions — This Is a Game-Changer</H1><P>If you set up only one additional thing beyond the basic installation, make it this. Custom Instructions tell Copilot how your team writes code — your naming conventions, your preferred patterns, your performance rules. Without them, Copilot gives you generic ABAP. With them, it gives you code that looks like your team wrote it.</P><P>Create a file called .github/copilot-instructions.md under each connected system. You define your rules in plain English, and Copilot follows them automatically across all suggestions.</P><P>The instructions I set up for our team enforce:</P><UL><LI>&nbsp; Use of modern ABAP syntax (7.55+) — no legacy patterns in new code</LI><LI>&nbsp; Our naming conventions (ZCL_*, ZIF_*, ZCX_* prefixes)</LI><LI>&nbsp; Performance-safe data access patterns (CDS-first, no SELECT *)</LI><LI>&nbsp; Domain-specific knowledge for our business context</LI><LI>&nbsp; Under each system, add a folder ‘.github’ and a file ‘copilot-instructions.md’</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_21-1775502991855.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393839i15C3C07615EC6982/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_21-1775502991855.png" alt="shaikferoz_21-1775502991855.png" /></span></P><UL><LI>&nbsp; You can deploy centrally or explore global deployment options with your GitHub Administrator</LI><LI>&nbsp; Below is a sample of the instruction file I created for our team</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shaikferoz_22-1775502991857.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/393840i0B7480E63C084A3C/image-size/medium?v=v2&amp;px=400" role="button" title="shaikferoz_22-1775502991857.png" alt="shaikferoz_22-1775502991857.png" /></span></P><P>A personal observation: after deploying Custom Instructions, I noticed the quality of Copilot’s ABAP suggestions improved dramatically. It stopped suggesting CREATE OBJECT and started using NEW. It stopped generating SELECT * and started using explicit field lists. These are small things individually, but across a team of developers, they add up to consistently better code.</P><H1 id="toc-hId-75803115">How My Team Uses This Daily</H1><P>Here are the five ways GitHub Copilot has become part of our regular workflow:</P><UL><LI>&nbsp; <STRONG>Agent Mode for direct development — </STRONG>Writing ABAP code directly into the SAP system. This is the use case that saves the most time, especially for generating boilerplate like data declarations, ALV setup, and standard SELECT patterns.</LI><LI>&nbsp; <STRONG>Documentation generation — </STRONG>Pointing Copilot at legacy code and getting clear, readable documentation. For a team maintaining 15+ years of custom ABAP, this alone justified the setup effort.</LI><LI>&nbsp; <STRONG>Code reviews — </STRONG>Using Copilot to review code for quality, performance patterns, and best practices before peer review. It catches things humans miss when they’re deep in the logic.</LI><LI>&nbsp; <STRONG>Unit test generation — </STRONG>Creating ABAP Unit test scaffolds with /tests. We’ve gone from almost zero test coverage on new code to having at least basic test classes for every new method.</LI><LI>&nbsp; <STRONG>Code modernization — </STRONG>Refactoring older ABAP to modern syntax and OO patterns. This is especially useful during S/4HANA preparation work.</LI></UL><H1 id="toc-hId--120710390">Honest Limitations — What I’ve Learned the Hard Way</H1><P>I want to be transparent about where Copilot falls short for ABAP, because I think setting realistic expectations is important:</P><UL><LI>&nbsp; The AI models are not fine-tuned for ABAP. ABAP has far less training data on GitHub compared to languages like Python or JavaScript. Copilot sometimes suggests almost-but-not-quite right syntax, especially for SAP-specific APIs and BAPIs.</LI><LI>&nbsp; Module-specific business logic still needs human expertise. Copilot doesn’t know your company’s custom tables, your specific process flows, or your regulatory requirements. Custom Instructions help, but they don’t replace domain knowledge.</LI><LI>&nbsp; Always review the generated code before activating. I’ve caught subtle issues with incorrect table key definitions and missing authority checks. The AI gets you 70–80% there; the last 20–30% is where your experience matters.</LI><LI>&nbsp; This is a developer productivity tool, not an enterprise transformation platform. It complements the specialized tools organizations use for large-scale migration and conversion programs.</LI></UL><H1 id="toc-hId--317223895">Bottom Line</H1><P>AI-assisted ABAP development works on-premise today. GitHub Copilot in VS Code, especially Agent Mode, has genuinely changed how I work and how my team approaches development tasks. The setup takes an afternoon, and the productivity gains start from day one.</P><P>If your organization has GitHub Copilot licenses and an on-premise SAP landscape, I’d encourage you to try this setup.&nbsp;</P><P>I’d love to hear from others in the community who are exploring AI tools for ABAP development. What’s working for you? What challenges have you faced? Let’s keep the conversation going.</P><P>#SAP #ABAP #GitHubCopilot #VSCode #AgentMode #AI #OnPremise #S4HANA #GenAI</P> 2026-04-09T08:24:40.755000+02:00 https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/my-learning-in-logistics-tracking-app-field-logistics/ba-p/14369552 My Learning in Logistics Tracking app - Field Logistics 2026-04-09T11:58:09.026000+02:00 vimal https://community.sap.com/t5/user/viewprofilepage/user-id/3165 <P>This blog walks through the real-world challenges we faced while building the logistics tracking app. This is an attempt to capture all the pointers and if there's any further points to be added , it will be added later.<BR /><BR />The Logistics Tracking (LT) app is SAP's standard tool for monitoring shipments and deliveries in real time. But out of the box, it comes with its own set of challenges — limited flexibility in status updates, gaps in milestone triggering, and difficulty handling complex scenarios like partial deliveries or kit item management — which can quickly become pain points on a project.</P><P>The heart of all logistics milestone is via config <STRONG>SPRO-&gt;Logistics - General -&gt; Field Logistics-&gt;Reporting-&gt;Define Logistics Tracking Profile </STRONG>. Once you are here , you can then see the below screenshot having all milestones for a particular Profile id as shown below.&nbsp;</P><P class="lia-indent-padding-left-90px" style="padding-left : 90px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vimal_0-1775728312738.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395418i920175066FDF51DB/image-size/medium?v=v2&amp;px=400" role="button" title="vimal_0-1775728312738.png" alt="vimal_0-1775728312738.png" /></span></P><UL><LI>Starting with "<STRONG>Milestone ID</STRONG>" - There are standard milestone ID's and there might be case that a custom milestone id is needed for your specific case. In that case, the problem can occur in the related stand. class of milestone because the constants used by standards might be referring to the standard milestone and you might need to copy the standard class and create your own custom class and change the constant value to your milestone id and use custom class instead of stand. milestone class.</LI></UL><P>&nbsp;</P><UL><LI><STRONG>Sequence</STRONG> : All the milestone listed above will be executed in a sequence mentioned in column "Sequence". If a sequence gets the dump then the next sequence will not be executed and you won't see any milestone in LT app . So if there's something which is not triggerring then you make sure to check if there's no dump occurning in system in tcode ST22.</LI></UL><P>&nbsp;</P><UL><LI><STRONG>Class : </STRONG>There are standard classes for each standard milestone but you might have to change it to custom class due to any reason specific to your needs . In that case ensure to copy the stand. class and on top of it you add your specific code.</LI></UL><P>&nbsp;</P><UL><LI><STRONG>Define Risks : </STRONG>For every milestone there is specific risks associated and corresponding risk class will have the logic to raise risks. Every risk class has a interface and a method via interface IS_RISK_VALID in which we have to write our logic.&nbsp;<UL><LI>There are 2 importing and 1 changing parameter in every risk class:<UL><LI>IV_MILESTONE_ID - Contains the milestone ID&nbsp;</LI><LI>IS_MT_RISK - To raise a risk by passing values in fields&nbsp;<!-- StartFragment --><SPAN>fldlogsmatltrackgriskid</SPAN>&nbsp;,<!-- StartFragment --><SPAN>fldlogsmatltrckgrisktypeid</SPAN></LI><LI>CT_MT_DTLS - 1 single record everytime to validate via logic to see if it valid to raise risk</LI></UL></LI></UL></LI></UL><P><U><STRONG>How milestones are triggerred</STRONG></U>:</P><UL><LI>Milestones are triggerred mostly via events. You can check class&nbsp;CL_FLOG_MANAGEKIT_EVTLISTENER-&gt;local definitions-&gt;method <STRONG>on_itemchanged . </STRONG>You will find most of the events getting triggerred here&nbsp; but if it's not there then you need to ask the functional team what is the underlying document getting generated at the end . If it's material document or PO document then you go to SWE2 and you need to find the relevant event and see the class in it. Example below:</LI></UL><P class="lia-indent-padding-left-120px" style="padding-left : 120px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vimal_0-1775723732579.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395372i7B3E6C9E4C051CAF/image-size/medium?v=v2&amp;px=400" role="button" title="vimal_0-1775723732579.png" alt="vimal_0-1775723732579.png" /></span></P><P><U><STRONG>Common issues faced and solutions</STRONG></U>:</P><UL><LI><STRONG>If milestone is not triggerred -</STRONG><UL><LI>Check in SPRO , supply process for which milestone is triggerred, if filters set is only for specific type of supply process then it will not trigger anything for other than that. You can check it by selecing corresponding milestone and then choosing "<STRONG>Define Supply process</STRONG>" as shown below:</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vimal_1-1775728494151.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395420iB518C052BC4A8A30/image-size/medium?v=v2&amp;px=400" role="button" title="vimal_1-1775728494151.png" alt="vimal_1-1775728494151.png" /></span><P>&nbsp;</P></LI><LI>If the above point is correctly maintained and still it's not triggerred then Check table FLOG_MT_DTLS , If there's related entry for the MO and milestone ? If not then put a debugger in Milestone class on user <STRONG>SAP_WFRT</STRONG> and re-execute the scenerio and if debugger is triggerring then check where it's failing in milestone class.&nbsp;</LI></UL></LI></UL><P>&nbsp;</P><UL><LI><STRONG>If milstone is triggerred but risk is not raised</STRONG>: Check table FLOG_MT_DTLS, if there's related entry for MO &amp; milestone id and if risk id is blank then go to corresponding risk class and put a debugger point with your user id and then go to <STRONG>SE38</STRONG> and execute program&nbsp;<STRONG>FLOG_MT_EXECUTE_RISKS </STRONG>and fill up the selection screen with relevant details of your MO and milestone id and execute. The debugger should reach at your risk class and then check the logic where it's failing and accordingly change the logic if needed.</LI></UL><P>&nbsp;</P><UL><LI><STRONG>Risk raised is at incorrect row</STRONG>: Risk is getting raised at incorrect row because it's Group id(<!-- StartFragment --><SPAN>fldlogsmaterialtrackinggroupid</SPAN> ) is blank. Please check FLOG_MT_DTLS table and field Group id for related risk. Group id field a combination of order no. and row number . If it's blank the risk will be raised on the top row. There is a standard logic for filling this field but if it's failing then you would like to fill it up from your custom risk classes. You will go to table <STRONG>FLOG_SUPLITEM </STRONG>by picking up document id of CT_MT_DTLS and filter on field UUID field of suplitem table and pick up field <STRONG>FLDLOGSSUPLRITMPOITMUNIQUEID </STRONG>and pass it to field<STRONG>&nbsp;<SPAN>fldlogsmaterialtrackinggroupid</SPAN></STRONG>&nbsp;in risk class.&nbsp;<UL><LI>If risks have correct group id then check for an entry which is created for milestone and if it does not have group id then we need to copy the stand. milestone class and create a custom milestone class and update the group id with above mentioned logic . With correct group id , risks and milestones will raise at correct row.</LI></UL></LI></UL><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vimal_0-1775806179886.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395960i625E6B7ECAEAB8C9/image-size/medium?v=v2&amp;px=400" role="button" title="vimal_0-1775806179886.png" alt="vimal_0-1775806179886.png" /></span></P><P>&nbsp;</P><UL><LI>Some important CDS views, Tables for the logic<UL><LI>FLOG_MT_DTLS</LI><LI>FLOG_SUPLITEM</LI><LI><EM>C_FldLogsMngKitIssuedItmTP</EM></LI></UL></LI></UL><P>At the end ,below is the view of each risk and milestone:<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vimal_0-1775730964192.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395476i2B1BD396A8356738/image-size/medium?v=v2&amp;px=400" role="button" title="vimal_0-1775730964192.png" alt="vimal_0-1775730964192.png" /></span></P><P>&nbsp;</P><P>If you have any pointers , please let us know . We will include it here.</P> 2026-04-09T11:58:09.026000+02:00 https://community.sap.com/t5/artificial-intelligence-blogs-posts/how-sap-joule-is-transforming-the-developer-experience/ba-p/14367162 How SAP Joule is Transforming the Developer Experience 2026-04-09T13:17:12.692000+02:00 Smriti_Chandra https://community.sap.com/t5/user/viewprofilepage/user-id/1512188 <P class=""><SPAN>In today’s rapidly evolving tech landscape, being an ABAP developer is no longer just about writing code. To stay relevant and competitive, developers must embrace AI-powered tools that enhance productivity, improve code quality, and accelerate delivery.</SPAN></P><P class=""><SPAN>One such innovation is </SPAN>SAP Joule, an AI assistant designed specifically for SAP developers. Integrated directly into ABAP Development Tools for Eclipse<SPAN>, Joule brings generative AI capabilities into your daily development workflow - without requiring you to switch between tools.</SPAN></P><P><SPAN>Let’s explore how Joule is transforming ABAP development.<BR /><BR /></SPAN></P><H2 id="toc-hId-1793364412"><SPAN>What is SAP Joule for Developers?</SPAN></H2><P class=""><SPAN>SAP Joule is an AI-powered assistant that supports developers throughout the entire development lifecycle - from writing and understanding code to testing, optimization, and even migration.</SPAN></P><P><SPAN>Think of it as a smart coding partner that understands your context and helps you work faster and smarter.</SPAN></P><P><SPAN>&nbsp;</SPAN></P><H2 id="toc-hId-1596850907"><SPAN class=""><SPAN class="">Key features of Joule for Developers</SPAN></SPAN><SPAN class="">&nbsp;:</SPAN></H2><H3 id="toc-hId-1529420121"><STRONG><SPAN>&nbsp; &nbsp;1. Chat and Help feature&nbsp; &nbsp;&nbsp;</SPAN></STRONG></H3><P><SPAN>Joule Chat allows you to interact using simple, natural language.</SPAN></P><UL><LI><SPAN>Ask questions about ABAP concepts</SPAN></LI><LI><SPAN>Get instant help from SAP documentation</SPAN></LI><LI><SPAN>Retrieve context-aware answers based on your work</SPAN></LI></UL><P class=""><SPAN>You can also use commands like:</SPAN></P><UL><LI><SPAN>/help &gt; for assistance</SPAN></LI><LI><SPAN>/explain &gt; to understand code or objects</SPAN></LI></UL><P><SPAN>&nbsp; &nbsp; &nbsp; &nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Joule Chat.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394438i7B01FDC25DD4FEC0/image-size/medium?v=v2&amp;px=400" role="button" title="Joule Chat.png" alt="Joule Chat.png" /></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</SPAN></P><H3 id="toc-hId-1332906616"><SPAN><SPAN class=""><SPAN class=""><STRONG>&nbsp; &nbsp;2. <SPAN class=""><SPAN class="">Code Understanding and Assistance</SPAN></SPAN><SPAN class="">&nbsp;</SPAN></STRONG></SPAN></SPAN></SPAN></H3><P><SPAN>Understanding legacy or complex code is often time-consuming. Joule simplifies this with its </SPAN>Explain<SPAN> feature.</SPAN></P><P class=""><SPAN>It provides clear explanations for:</SPAN></P><UL><LI><SPAN>ABAP Classes</SPAN></LI><LI><SPAN>ABAP Programs</SPAN></LI><LI><SPAN>ATC findings</SPAN></LI><LI><SPAN>CDS artifacts</SPAN></LI></UL><P><SPAN>&nbsp;Example;</SPAN></P><pre class="lia-code-sample language-abap"><code>/explain _view_name​</code></pre><P>&nbsp; &nbsp; &nbsp; &nbsp; Alternatively, Right-click on objects &gt; Joule &gt; Explain&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Explain2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394439i108ECB8634C6385F/image-size/medium?v=v2&amp;px=400" role="button" title="Explain2.png" alt="Explain2.png" /></span></SPAN></P><P>&nbsp;</P><H3 id="toc-hId-1136393111"><SPAN><SPAN class=""><SPAN class=""><STRONG>&nbsp; &nbsp;3. <SPAN class=""><SPAN class="">Predictive Code Completion</SPAN></SPAN></STRONG></SPAN></SPAN></SPAN></H3><P><SPAN>Joule enhances your coding speed with AI-driven suggestions.</SPAN></P><UL><LI><SPAN>Auto-completes code intelligently</SPAN></LI><LI><SPAN>Works for classes, interfaces, and programs</SPAN></LI><LI><SPAN>Accept suggestions instantly using </SPAN>Tab</LI></UL><P>You can even write a requirement as a comment, and Joule will generate the code for you as ghost text.</P><P><SPAN><SPAN class=""><STRONG>&nbsp; &nbsp; &nbsp; &nbsp;Settings</STRONG><STRONG>&nbsp;</STRONG><BR /></SPAN></SPAN>Go to <STRONG>Window &gt; Preferences &gt; Source Code Editors &gt; Code Completion</STRONG>, then review or update your settings. Make sure the "<STRONG>Trigger predictive code completion"</STRONG>&nbsp;option is enabled.</P><P>&nbsp;</P><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="PDCode1.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394444iDBA6580949EB4536/image-size/medium?v=v2&amp;px=400" role="button" title="PDCode1.png" alt="PDCode1.png" /></span></DIV><P>To display predictive suggestions in a dialog optimized for screen readers, go to <STRONG>Window &gt; Preferences &gt; ABAP Development &gt; Accessibility &gt; Predictive Code Completion</STRONG>.</P><P>You can manually trigger suggestions using <STRONG>Alt + J (Windows)</STRONG> or <STRONG>Option + J (Mac)</STRONG>. Automatic triggering can also be turned on or off through the search dialog (<STRONG>Ctrl + 3</STRONG>).</P><P><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="PDCode3.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394442iA633E7F4A728A8AB/image-size/medium?v=v2&amp;px=400" role="button" title="PDCode3.png" alt="PDCode3.png" /></span></P><P>&nbsp;</P><P>To display proposals in a dialog box, enable the "<STRONG>Show Proposals in a dialog box"</STRONG>&nbsp;option.</P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="PDCode2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394443iE7D0A4D96E2A90A3/image-size/medium?v=v2&amp;px=400" role="button" title="PDCode2.png" alt="PDCode2.png" /></span></SPAN></P><P>&nbsp;</P><P>To receive a suggested solution, write your requirement in plain commented text. The proposed solution will appear as ghost text. Press Tab to accept it.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="PDCode5.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394445i7402E42AB91D6C7C/image-size/medium?v=v2&amp;px=400" role="button" title="PDCode5.png" alt="PDCode5.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-939879606"><SPAN><SPAN class=""><SPAN class=""><STRONG>4. <SPAN class=""><SPAN class="">Testing Support</SPAN></SPAN><SPAN class="">&nbsp;</SPAN></STRONG></SPAN></SPAN></SPAN></H3><P class=""><SPAN>Writing unit tests becomes significantly easier with Joule.</SPAN></P><UL><LI><SPAN>Automatically generates ABAP Unit tests</SPAN></LI><LI><SPAN>Supports global and local classes</SPAN></LI><LI><SPAN>Generates test classes for CDS entities</SPAN></LI></UL><P class=""><SPAN>This improves:</SPAN></P><UL><LI><SPAN>Test coverage</SPAN></LI><LI><SPAN>Code reliability</SPAN></LI><LI><SPAN>Developer productivity</SPAN></LI></UL><DIV class=""><P>To create an ABAP Unit test, right-click on the class and choose Joule &gt; Start Chat for ABAP Unit. The Joule perspective will then present recommended next steps.</P></DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UT1.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394457iEF8C107B87698A66/image-size/medium?v=v2&amp;px=400" role="button" title="UT1.png" alt="UT1.png" /></span>&nbsp; &nbsp; &nbsp;</DIV><DIV class="">&nbsp;</DIV><DIV class="">&nbsp;&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UT2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394458i70E621DBB7CE2F63/image-size/medium?v=v2&amp;px=400" role="button" title="UT2.png" alt="UT2.png" /></span></DIV><DIV class="">&nbsp;</DIV><DIV class=""><P>In Joule Chat, click "Add Tests to New Test Class".</P></DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UT3.png" style="width: 285px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394462i924D337880038D8E/image-dimensions/285x356?v=v2" width="285" height="356" role="button" title="UT3.png" alt="UT3.png" /></span></DIV><DIV class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<SPAN>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</SPAN></DIV><DIV class="">&nbsp;</DIV><DIV class=""><SPAN>Joule will suggest ABAP Unit tests, giving you options to </SPAN><STRONG>Apply</STRONG><SPAN>, </SPAN><STRONG>Insert</STRONG><SPAN>, </SPAN><STRONG>Copy</STRONG><SPAN>, </SPAN><STRONG>Refactor</STRONG><SPAN>, or </SPAN><STRONG>Generate Test</STRONG><SPAN>.</SPAN></DIV><DIV class="">&nbsp;</DIV><DIV class="">&nbsp;</DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UT4.png" style="width: 341px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394461iF274853FC58A200E/image-dimensions/341x328?v=v2" width="341" height="328" role="button" title="UT4.png" alt="UT4.png" /></span></DIV><DIV class="">&nbsp;</DIV><H3 id="toc-hId-743366101"><SPAN><SPAN class=""><SPAN class=""><STRONG>&nbsp; 5.&nbsp;</STRONG></SPAN></SPAN></SPAN><STRONG><SPAN>Development&nbsp;</SPAN></STRONG><SPAN>&nbsp;</SPAN></H3><P><SPAN>Joule can help you build applications faster by generating key components.</SPAN></P><H4 id="toc-hId-675935315"><SPAN>RAP Business Logic</SPAN></H4><UL><LI><SPAN>Generates determinations and validations</SPAN></LI><LI><SPAN>Uses simple descriptions to create logic</SPAN></LI></UL><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Rap1.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394475i4E4816FB35273B71/image-size/medium?v=v2&amp;px=400" role="button" title="Rap1.png" alt="Rap1.png" /></span></SPAN></P><P>&nbsp;</P><P>Enter the requirement and specify what each method is expected to perform.</P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="RAP2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394483iEE2D5B65039BD600/image-size/medium?v=v2&amp;px=400" role="button" title="RAP2.png" alt="RAP2.png" /></span></SPAN></P><P>The proposal is generated based on your method description, and you can modify it manually if needed.</P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="RAP3.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394482iD9E0A2D6738E50C2/image-size/medium?v=v2&amp;px=400" role="button" title="RAP3.png" alt="RAP3.png" /></span></SPAN></P><H4 id="toc-hId-479421810"><SPAN>OData UI Services</SPAN></H4><UL><LI><SPAN>Create complete applications from scratch</SPAN></LI><LI><SPAN>Automatically generates:</SPAN><UL><LI><SPAN>Service definitions</SPAN></LI><LI><SPAN>CDS views</SPAN></LI><LI><SPAN>Behavior definitions</SPAN></LI><LI><SPAN>Database tables</SPAN></LI></UL></LI></UL><P><SPAN>This significantly reduces manual effort in building applications.</SPAN></P><P>Steps to create an OData UI application:</P><OL><LI><P>Right-click on the package and select <STRONG>Generate ABAP Repository Objects</STRONG>.</P></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI1.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394691i5DE9455628F9EB90/image-size/medium?v=v2&amp;px=400" role="button" title="UI1.png" alt="UI1.png" /></span></P><P>&nbsp; &nbsp; &nbsp;2. Choose <STRONG>OData UI Service from Scratch</STRONG>.<SPAN>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394692iD769A6CE737EC174/image-size/medium?v=v2&amp;px=400" role="button" title="UI2.png" alt="UI2.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3. In the <STRONG>Configure Generator</STRONG> window, enter a description of your BO in Joule Chat. For example:<SPAN>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI3.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394698i0C2FE5D2A50CBC51/image-size/medium?v=v2&amp;px=400" role="button" title="UI3.png" alt="UI3.png" /></span>&nbsp; &nbsp; &nbsp; &nbsp; 4.&nbsp; &nbsp;Based on your prompt, Joule will suggest the BO entities and fields. If they match your requirements, click <STRONG>Accept</STRONG>. You can also modify them manually or with Joule’s assistance. Once satisfied, click <STRONG>Next</STRONG>.<SPAN>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI4.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394699i5B76D861C948CF17/image-size/medium?v=v2&amp;px=400" role="button" title="UI4.png" alt="UI4.png" /></span></P><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; 5. Review the list of artifacts to be generated, then click <STRONG>Next</STRONG>. Select the Transport Request and click <STRONG>Finish</STRONG>.<SPAN>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI5.png" style="width: 298px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394706iB7093EEE2BA2ED3A/image-size/medium?v=v2&amp;px=400" role="button" title="UI5.png" alt="UI5.png" /></span></P><P>&nbsp;</P><H4 id="toc-hId-282908305"><SPAN>Consume OData</SPAN></H4><P><SPAN>The Consume capability in Joule lets you generate OData requests and corresponding ABAP code via the OData Client Proxy.<BR />You need a service consumption model with a model class, created in ABAP Development Tools for Eclipse using the service metadata.<BR /><BR />Steps:<BR /></SPAN></P><UL><LI>Open the service consumption model of your OData service.</LI><LI>Start Joule chat:<UL><LI>Right-click an object &gt;&nbsp;Joule &gt; Consume, or</LI><LI>Open Joule chat and type /consume.</LI></UL></LI></UL><H3 id="toc-hId--117919288">How It Works</H3><UL><LI><STRONG>Known OData request:</STRONG> Enter it directly (e.g., GET /Travel?$select=ID) and Joule will generate the corresponding ABAP code.</LI><LI><STRONG>Need help creating a request:</STRONG> Describe your goal in plain language, and Joule will generate both the OData request and ABAP code.</LI></UL><P>You can adjust the generated request or code and try again.</P><P>&nbsp;</P><H3 id="toc-hId--314432793"><SPAN><SPAN class=""><SPAN class=""><STRONG>&nbsp; 6.&nbsp;</STRONG></SPAN></SPAN></SPAN><STRONG><SPAN>Migration&nbsp;</SPAN></STRONG><SPAN>&nbsp;</SPAN></H3><P class=""><SPAN>Joule migration assistant helps you:</SPAN></P><UL><LI><SPAN>Understand ATC findings</SPAN></LI><LI><SPAN>Identify obsolete or incompatible code</SPAN></LI><LI><SPAN>Adapt to data model changes</SPAN></LI></UL><P><SPAN>This reduces risk and speeds up migration projects.</SPAN></P><P>&nbsp;</P><P>SAP Joule is more than just a development tool - it’s a game changer for ABAP developers. By integrating AI into everyday workflows, it helps developers write cleaner code, automate repetitive tasks, and quickly understand complex business objects.</P> 2026-04-09T13:17:12.692000+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/custom-sorting-for-virtual-elements-in-rap/ba-p/14367132 Custom Sorting for Virtual Elements in RAP 2026-04-10T00:06:47.289000+02:00 sharathtm https://community.sap.com/t5/user/viewprofilepage/user-id/1874965 <H2 id="toc-hId-1793364319"><STRONG>Introduction</STRONG></H2><P>In the ABAP RESTful Application Programming Model (RAP), virtual elements are essential for displaying computed data that doesn't exist in the database—such as deriving a month or year from a timestamp. However, because these elements are calculated at runtime, they lack standard OData capabilities like server-side sorting and filtering. In this article, we will explore how to overcome these limitations by implementing a <STRONG>SADL exit</STRONG>. We’ll walk through how to enable full sorting and calculation capabilities for virtual elements, ensuring a seamless experience for the end user.</P><H2 id="toc-hId-1596850814">What are Virtual Elements in RAP?</H2><P>In the <STRONG>ABAP RESTful Application Programming Model (RAP)</STRONG>, a virtual element is a field defined in a CDS (Core Data Services) projection view that does not have a corresponding column in the underlying database table.</P><H2 id="toc-hId-1400337309">Real-Time Business Scenario: Sales Period Reporting</H2><P>In many SAP implementations, the business requires reports segmented by <STRONG>Month</STRONG> and <STRONG>Year</STRONG> (e.g., for Monthly Sales Performance). While the underlying database table stores a precise (Created On) date, it does not store the Month or Year as separate columns.</P><H3 id="toc-hId-1332906523">The Problem</H3><P>If we create a Fiori Elements app and want to show "Sales Month" and "Sales Year" as separate columns:</P><OL><LI><P><STRONG>Simple Virtual Elements</STRONG> can calculate these strings (e.g., "January", "2024").</P></LI><LI><P><STRONG>The Failure:</STRONG> When a user tries to sort the "Sales Month" column, the UI will throw an error or do nothing because the OData service doesn't know how to sort a field that doesn't exist in the database.</P></LI></OL><H3 id="toc-hId-1136393018">The Solution</H3><P>By using a <STRONG>SADL Exit</STRONG>, we "map" the virtual Month/Year fields back to the physical Sales date field. This allows the database to perform the sort on the actual date, while the user sees the sorted Month or Year on their screen.</P><H2 id="toc-hId-810796794">Implementation Steps</H2><H4 id="toc-hId-872448727">Step 1: Create a database table</H4><P>Define the physical storage. This is where the raw data lives before any calculations happen.</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Sales table' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #RESTRICTED define table zsales_table { key client : abap.clnt not null; key sales_uuid : sysuuid_x16 not null; sales_id : abap.char(10); sales_date : abap.dats; @Semantics.amount.currencyCode : 'zsales_table.currency' total_amount : abap.curr(15,2); currency : abap.cuky; last_changed_at : timestampl; }</code></pre><H3 id="toc-hId-546852503">Step 2: Create a interface view on top of database table.</H3><P>This layer projects the database fields into a clean, business-oriented structure.</P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.viewEnhancementCategory: [#NONE] @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Interface view for sales table' @Metadata.ignorePropagatedAnnotations: true @ObjectModel.usageType:{ serviceQuality: #X, sizeCategory: #S, dataClass: #MIXED } define root view entity zi_sales_table as select from zsales_table { key sales_uuid as SalesUuid, sales_id as SalesId, sales_date as SalesDate, @Semantics.amount. currencyCode: 'Currency' total_amount as TotalAmount, currency as Currency, last_changed_at as LastChangedAt }</code></pre><H3 id="toc-hId-350338998">&nbsp;Step 3: Create a Consumption view</H3><P>This is where the Virtual Elements are defined. We use annotations to link the UI to the specific ABAP logic for calculation and sorting.</P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Projection view for sales table' @Metadata.ignorePropagatedAnnotations: true define root view entity ZP_SALESPROJ provider contract transactional_query as projection on zi_sales_table { .facet: [{ type: #IDENTIFICATION_REFERENCE, position: 10, label: 'Salestable', targetQualifier: 'GENERAL', purpose: #STANDARD }] .lineItem: [{ position: 10, label: 'Sales Uuid' }] key SalesUuid, .lineItem: [{ position: 20, label: 'Sales Id' }] .identification: [{ position: 20, label: 'Sales Id' }] SalesId, .lineItem: [{ position: 30, label: 'Sales order date' }] .identification: [{ position: 30, label: 'Sales order date', qualifier: 'GENERAL' }] SalesDate, .lineItem: [{ position: 40, label: 'Sales order year' }] .identification: [{ position: 40, label: 'Sales order year', qualifier: 'GENERAL' }] @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_SALES_VE_HANDLER' @ObjectModel.sort.transformedBy: 'ABAP:ZCL_SALES_VE_HANDLER' virtual SalesYear : abap.char(4), .lineItem: [{ position: 50, label: 'Sales order month' }] .identification: [{ position: 50, label: 'Sales order month' , qualifier: 'GENERAL' }] @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_SALES_VE_HANDLER' @ObjectModel.sort.transformedBy: 'ABAP:ZCL_SALES_VE_HANDLER' virtual SalesMonth : abap.char(2), .lineItem: [{ position: 60, label: 'Total amount' }] .identification: [{ position: 60, label: 'Total amount' }] @Semantics.amount.currencyCode: 'Currency' TotalAmount, Currency }</code></pre><H4 id="toc-hId-282908212">Step 5:&nbsp;The Handler Class Logic</H4><P>This class implements two critical interfaces: <U><STRONG>if_sadl_exit_calc_element_read</STRONG></U>&nbsp;for the calculation and <U><STRONG>if_sadl_exit_sort_transform&nbsp;</STRONG></U>&nbsp;to enable sorting.</P><pre class="lia-code-sample language-abap"><code>CLASS zcl_sales_ve_handler DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_sadl_exit_calc_element_read. INTERFACES if_sadl_exit_sort_transform. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_sales_ve_handler IMPLEMENTATION. METHOD if_sadl_exit_calc_element_read~get_calculation_info. IF line_exists( it_requested_calc_elements[ table_line = 'SALESYEAR' ] ) OR line_exists( it_requested_calc_elements[ table_line = 'SALESMONTH' ] ). APPEND 'SALESDATE' TO et_requested_orig_elements. ENDIF. ENDMETHOD. METHOD if_sadl_exit_calc_element_read~calculate. DATA lt_data TYPE TABLE OF zp_salesproj WITH DEFAULT KEY. lt_data = CORRESPONDING #( it_original_data ). LOOP AT lt_data ASSIGNING FIELD-SYMBOL(&lt;fs_row&gt;). &lt;fs_row&gt;-SALESYEAR = &lt;fs_row&gt;-salesdate(4). &lt;fs_row&gt;-SALESMONTH = &lt;fs_row&gt;-salesdate+4(2). ENDLOOP. ct_calculated_data = CORRESPONDING #( lt_data ). ENDMETHOD. METHOD if_sadl_exit_sort_transform~map_element. CASE iv_element. WHEN 'SALESYEAR' OR 'SALESMONTH'. " Map the UI sort request to the database field 'SALESDATE' APPEND VALUE #( name = 'SALESDATE' ) TO et_sort_elements. ENDCASE. ENDMETHOD. ENDCLASS.</code></pre><H3 id="toc-hId--117919381">Result:</H3><P><BR />With the handler class implemented, the <STRONG>Sales order month and Sales order year</STRONG> ( Virtual Elements) now behaves like a standard database fields.<BR /><BR /></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_0-1775541139507.png" style="width: 0px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394078i308E9AD112A3DFDF/image-size/small?v=v2&amp;px=200" width="0" height="0" role="button" title="sharathtm_0-1775541139507.png" alt="sharathtm_0-1775541139507.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_1-1775541190320.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394080i8A95E257B9CF5997/image-dimensions/624x256?v=v2" width="624" height="256" role="button" title="sharathtm_1-1775541190320.png" alt="sharathtm_1-1775541190320.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_0-1775714874405.png" style="width: 599px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395268i96C104E304776015/image-dimensions/599x226?v=v2" width="599" height="226" role="button" title="sharathtm_0-1775714874405.png" alt="sharathtm_0-1775714874405.png" /></span></P><P>&nbsp;</P> 2026-04-10T00:06:47.289000+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/downloading-data-in-different-formats-using-factory-design-pattern/ba-p/14221294 Downloading Data in Different Formats Using Factory Design Pattern 2026-04-10T07:55:27.623000+02:00 Kkgh https://community.sap.com/t5/user/viewprofilepage/user-id/2056751 <P><STRONG>Downloading Data in Different Formats Using Factory Design Pattern</STRONG></P><P>In real projects, users often need the ability to download business data (e.g., sales orders, customer data, or flight bookings) in different formats like TXT, PDF, DOC.</P><P>If we try to achieve this in a single report with IF/ELSE or CASE statements, the code quickly becomes messy and hard to maintain. Every new requirement (e.g., CSV, JSON, XML) would require changing the program logic.</P><P>This is where the Factory Design Pattern helps.</P><H1 id="toc-hId-1631780768">How the Factory Design Pattern Works Here--</H1><OL><LI><STRONG>Interface (ZIF_FILE_DOWNLOADER)</STRONG><OL><LI>Defines the common contract: one method DOWNLOAD_FILE.</LI><LI>Ensures all file downloaders behave the same way from the outside.</LI></OL></LI></OL><OL><LI><STRONG>Concrete Classes (TXT, DOC, PDF, XLSX Downloaders)</STRONG><OL><LI>Each class implements the interface and contains logic specific to that file type.</LI><LI><STRONG>Example<EM>:</EM></STRONG><OL><LI><STRONG>TXT <EM><SPAN>→ </SPAN></EM></STRONG>Uses GUI_DOWNLOAD with ASCII format.</LI><LI><STRONG>DOC <EM><SPAN>→ </SPAN></EM></STRONG>Uses GUI_DOWNLOAD with linefeeds.</LI></OL></LI></OL></LI></OL><UL><LI><STRONG>PDF <EM><SPAN>→ </SPAN></EM></STRONG>Uses CL_APOC_PDF_GENERATOR and binary download.</LI></UL><OL><LI><STRONG>XLSX <EM><SPAN>→ </SPAN></EM></STRONG>Uses CL_FDT_XL_SPREADSHEET to generate Excel.</LI></OL><OL><LI><STRONG>Factory Class (ZCL_FILE_FACTORY)</STRONG><OL><LI>Acts as a central decision-maker.</LI><LI>Based on user selection (TXT, DOC, PDF, XLSX), it instantiates the correct class.</LI><LI>The main program never directly knows which class it is using — it only calls the common method.</LI></OL></LI></OL><OL><LI><STRONG>Report Program (ZDEMO6)</STRONG><OL><LI>Reads user input (p_type).</LI><LI>Calls the factory to get the right downloader object.</LI><LI>Invokes DOWNLOAD_FILE, which internally runs the format-specific logic.</LI></OL></LI></OL><H1 id="toc-hId-1435267263">Flow of Execution--</H1><OL><LI><STRONG><SPAN>User selects file type </SPAN></STRONG><SPAN>on selection screen.</SPAN></LI><LI><STRONG><SPAN>Report calls factory </SPAN></STRONG><SPAN>to get the correct downloader.</SPAN></LI><LI><STRONG><SPAN>Factory returns the right class instance </SPAN></STRONG>(TXT/PDF/DOC/XLSX).</LI><LI><STRONG><SPAN>Report calls DOWNLOAD_FILE </SPAN></STRONG><SPAN>method (same for all).</SPAN></LI><LI><STRONG><SPAN>File gets saved </SPAN></STRONG><SPAN>on the user’s local system in the chosen format.</SPAN></LI></OL><H1 id="toc-hId-1238753758">Benefits of Using Factory Pattern--</H1><P><STRONG>Scalability </STRONG>– Easy to add new file formats without modifying existing code.</P><P><STRONG>Maintainability </STRONG>– Each file logic is isolated in its own class.</P><P><STRONG>Reusability </STRONG>– The same design can be reused in multiple applications (ALV exports, reports, integration).</P><P><STRONG>Clean Code </STRONG>– Avoids long IF/ELSE or CASE blocks.</P><pre class="lia-code-sample language-abap"><code>REPORT zdemo6. *---------------------------------------------------------------------- * Interface for File Downloaders *---------------------------------------------------------------------- INTERFACE zif_file_downloader. METHODS: download_file IMPORTING it_data TYPE STANDARD TABLE. ENDINTERFACE. CLASS zcl_txt_downloader DEFINITION. PUBLIC SECTION. INTERFACES zif_file_downloader. ENDCLASS. *---------------------------------------------------------------------- * TXT File Downloader Implementation *---------------------------------------------------------------------- CLASS zcl_txt_downloader IMPLEMENTATION. METHOD zif_file_downloader~download_file. DATA: lv_filename TYPE string VALUE 'C:\temp\New folder1'. " Download using classic FM GUI_DOWNLOAD CALL FUNCTION 'GUI_DOWNLOAD' EXPORTING filename = lv_filename " Name of file filetype = 'ASC' " File Type (ASC or BIN) write_field_separator = 'X' " Separate Columns by Tabs in Case of ASCII Download confirm_overwrite = 'X' " Overwrite File Only After Confirmation TABLES data_tab = it_data " Transfer table EXCEPTIONS file_write_error = 1 " Cannot write to file no_batch = 2 " Front-End Function Cannot Be Executed in Background gui_refuse_filetransfer = 3 " Incorrect Front End invalid_type = 4 " Invalid value for parameter FILETYPE no_authority = 5 " No Download Authorization unknown_error = 6 header_not_allowed = 7 " Invalid header separator_not_allowed = 8 " Invalid separator filesize_not_allowed = 9 " Invalid file size header_too_long = 10 " The header information is limited to 1023 bytes at present dp_error_create = 11 " Cannot Create Data Provider dp_error_send = 12 " Error Sending Data with DataProvider dp_error_write = 13 " Error Writing Data with DataProvider unknown_dp_error = 14 " Error when calling data provider access_denied = 15 " Access to File Denied dp_out_of_memory = 16 " Not Enough Memory in DataProvider disk_full = 17 " Storage Medium Full dp_timeout = 18 " Timeout of DataProvider file_not_found = 19 " Could not find file dataprovider_exception = 20 " General Exception Error in Data Provider control_flush_error = 21 " Error in Control Framework OTHERS = 22. IF sy-subrc IS INITIAL. WRITE: / 'TXT file downloaded:', lv_filename. ENDIF. ENDMETHOD. ENDCLASS. *---------------------------------------------------------------------- * PDF File Downloader Implementation *---------------------------------------------------------------------- CLASS zcl_pdf_downloader DEFINITION. PUBLIC SECTION. INTERFACES zif_file_downloader. " Implements interface ENDCLASS. CLASS zcl_pdf_downloader IMPLEMENTATION. METHOD zif_file_downloader~download_file. DATA: lv_filename TYPE string VALUE 'C:\temp\output4.pdf', lt_pdf TYPE STANDARD TABLE OF x255. " Generate PDF binary from given data using APOC PDF generator DATA(lo_pdf) = NEW cl_apoc_pdf_generator( ). lo_pdf-&gt;create_pdf( EXPORTING input = it_data RECEIVING pdf_binary_output = DATA(rv_bin) ). " Convert XSTRING PDF to binary table CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' EXPORTING buffer = rv_bin TABLES binary_tab = lt_pdf. " Save as binary file on local machine cl_gui_frontend_services=&gt;gui_download( EXPORTING filename = lv_filename " Name of file filetype = 'BIN' " File type (ASCII, binary ...) confirm_overwrite = 'X' " Overwrite File Only After Confirmation CHANGING data_tab = lt_pdf " Transfer table EXCEPTIONS file_write_error = 1 " Cannot write to file no_batch = 2 " Front-End Function Cannot Be Executed in Backgrnd gui_refuse_filetransfer = 3 " Incorrect Front End invalid_type = 4 " Invalid value for parameter FILETYPE no_authority = 5 " No Download Authorization unknown_error = 6 " Unknown error header_not_allowed = 7 " Invalid header separator_not_allowed = 8 " Invalid separator filesize_not_allowed = 9 " Invalid file size header_too_long = 10 " Header information currently restricted to 1023 bytes dp_error_create = 11 " Cannot create DataProvider dp_error_send = 12 " Error Sending Data with DataProvider dp_error_write = 13 " Error Writing Data with DataProvider unknown_dp_error = 14 " Error when calling data provider access_denied = 15 " Access to File Denied dp_out_of_memory = 16 " Not Enough Memory in DataProvider disk_full = 17 " Storage Medium full dp_timeout = 18 " Timeout of DataProvider file_not_found = 19 " Could not find file dataprovider_exception = 20 " General Exception Error in DataProvider control_flush_error = 21 " Error in Control Framework not_supported_by_gui = 22 " GUI does not support this error_no_gui = 23 " GUI not available OTHERS = 24 ). IF sy-subrc IS INITIAL. WRITE: / 'PDF file downloaded:', lv_filename. ENDIF. ENDMETHOD. ENDCLASS. *---------------------------------------------------------------------- * DOC File Downloader Implementation *---------------------------------------------------------------------- CLASS zcl_doc_downloader DEFINITION. PUBLIC SECTION. INTERFACES zif_file_downloader. ENDCLASS. CLASS zcl_doc_downloader IMPLEMENTATION. METHOD zif_file_downloader~download_file. DATA: lv_filename TYPE string VALUE 'C:\temp\output.doc'. " Download using GUI_DOWNLOAD in ASCII mode CALL FUNCTION 'GUI_DOWNLOAD' EXPORTING filename = lv_filename " Name of file filetype = 'ASC' " File Type (ASC or BIN) write_lf_after_last_line = abap_true " Writes LF even after last line write_field_separator = 'X' confirm_overwrite = 'X' TABLES data_tab = it_data " Transfer table EXCEPTIONS file_write_error = 1 " Cannot write to file no_batch = 2 " Front-End Function Cannot Be Executed in Background gui_refuse_filetransfer = 3 " Incorrect Front End invalid_type = 4 " Invalid value for parameter FILETYPE no_authority = 5 " No Download Authorization unknown_error = 6 header_not_allowed = 7 " Invalid header separator_not_allowed = 8 " Invalid separator filesize_not_allowed = 9 " Invalid file size header_too_long = 10 " The header information is limited to 1023 bytes at present dp_error_create = 11 " Cannot Create Data Provider dp_error_send = 12 " Error Sending Data with DataProvider dp_error_write = 13 " Error Writing Data with DataProvider unknown_dp_error = 14 " Error when calling data provider access_denied = 15 " Access to File Denied dp_out_of_memory = 16 " Not Enough Memory in DataProvider disk_full = 17 " Storage Medium Full dp_timeout = 18 " Timeout of DataProvider file_not_found = 19 " Could not find file dataprovider_exception = 20 " General Exception Error in Data Provider control_flush_error = 21 " Error in Control Framework OTHERS = 22. IF sy-subrc IS INITIAL. WRITE: / 'DOC file downloaded:', lv_filename. ENDIF. ENDMETHOD. ENDCLASS. *---------------------------------------------------------------------- * Factory Class - Returns Correct Downloader Object *---------------------------------------------------------------------- CLASS zcl_file_factory DEFINITION. PUBLIC SECTION. CLASS-METHODS get_downloader IMPORTING iv_type TYPE string RETURNING VALUE(ro_downloader) TYPE REF TO zif_file_downloader. ENDCLASS. CLASS zcl_file_factory IMPLEMENTATION. METHOD get_downloader. " Choose correct class based on file type CASE iv_type. WHEN 'TXT'. CREATE OBJECT ro_downloader TYPE zcl_txt_downloader. WHEN 'PDF'. CREATE OBJECT ro_downloader TYPE zcl_pdf_downloader. WHEN 'DOC'. CREATE OBJECT ro_downloader TYPE zcl_doc_downloader. WHEN OTHERS. MESSAGE 'Invalid format!' TYPE 'E'. ENDCASE. ENDMETHOD. ENDCLASS. INITIALIZATION. *---------------------------------------------------------------------- * Selection Screen *---------------------------------------------------------------------- " Choose format dynamically PARAMETERS: p_type TYPE string DEFAULT 'TXT'. " Options: TXT / PDF / DOC *---------------------------------------------------------------------- * Main Logic *---------------------------------------------------------------------- START-OF-SELECTION. DATA: lo_down TYPE REF TO zif_file_downloader. " Get some sample data from SFLIGHT table SELECT FROM sflight FIELDS * INTO TABLE (lt_data) UP TO 10 ROWS. " Use factory to get correct downloader object lo_down = zcl_file_factory=&gt;get_downloader( iv_type = p_type ). lo_down-&gt;download_file( it_data = lt_data ).</code></pre><P><STRONG>For TEXT:-</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_0-1758197979389.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316416i675B43E8C70FC757/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_0-1758197979389.png" alt="Kkgh_0-1758197979389.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_1-1758197979391.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316417i733D255E3E159C78/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_1-1758197979391.png" alt="Kkgh_1-1758197979391.png" /></span></P><P><STRONG>&nbsp;</STRONG><STRONG>We can see in our folder.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_2-1758197979392.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316418i31F83BF306F1E262/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_2-1758197979392.png" alt="Kkgh_2-1758197979392.png" /></span></P><P><STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_3-1758197979395.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316421i7FDA4914B313746D/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_3-1758197979395.png" alt="Kkgh_3-1758197979395.png" /></span></STRONG></P><P><STRONG>For WORD--</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_4-1758197979397.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316420i29EA7469119F3FDF/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_4-1758197979397.png" alt="Kkgh_4-1758197979397.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_5-1758197979397.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316419i09FAF6FB774DDB05/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_5-1758197979397.png" alt="Kkgh_5-1758197979397.png" /></span></P><P><STRONG>We can see in our folder--</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="Kkgh_6-1758197979398.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316424iCB55F3DC52AA76B6/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_6-1758197979398.png" alt="Kkgh_6-1758197979398.png" /></span></P><P><STRONG><EM><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_7-1758197979402.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316423iF573D670B76E90EA/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_7-1758197979402.png" alt="Kkgh_7-1758197979402.png" /></span></EM></STRONG></P><P><STRONG>For PDF:-</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_8-1758197979403.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316422i159B1FE6F078848F/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_8-1758197979403.png" alt="Kkgh_8-1758197979403.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_9-1758197979404.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316426iD9731BCF7558489C/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_9-1758197979404.png" alt="Kkgh_9-1758197979404.png" /></span></P><P><STRONG>We can see in our folder--</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_0-1758199005009.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316435i31CFD62C0CD95B31/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_0-1758199005009.png" alt="Kkgh_0-1758199005009.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Kkgh_0-1758199250660.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/316438iB6D07F5934A06C64/image-size/large?v=v2&amp;px=999" role="button" title="Kkgh_0-1758199250660.png" alt="Kkgh_0-1758199250660.png" /></span></P><P><STRONG>Conclusion:-</STRONG></P><P>In this blog, we explored how the <STRONG>Factory Design Pattern</STRONG> can be effectively applied in ABAP to download data in different formats such as <STRONG>TEXT, WORD, PDF </STRONG>without tightly coupling the logic to a specific format. By introducing a <STRONG>factory class</STRONG> that decides which concrete formatter to instantiate, we achieve:</P><UL><LI><STRONG>Flexibility</STRONG> – easily add new output formats in the future without modifying existing logic.</LI><LI><STRONG>Reusability</STRONG> – the same factory and interface can be used across multiple applications.</LI><LI><STRONG>Maintainability</STRONG> – reduces redundant code and keeps responsibilities clearly separated.</LI><LI><STRONG>Scalability</STRONG> – supports evolving business needs where multiple consumers may require different file formats.</LI></UL><P>The Factory Design Pattern not only promotes <STRONG>clean code principles</STRONG> but also aligns with <STRONG>object-oriented best practices</STRONG> in ABAP. By leveraging this approach, developers can build solutions that are <STRONG>extensible, testable, and future-proof</STRONG>.</P><P>Thank You.</P> 2026-04-10T07:55:27.623000+02:00