├── README.md
├── src
└── images
│ ├── cl_abap_behv_aux.png
│ ├── Criticality_in_CDS.png
│ ├── Session_Variables.jpg
│ ├── Enable_LongText_In_CDS.jpg
│ ├── Get_Decision_Note_Comments.jpg
│ ├── Inline_Actions_in_Object_Page_Sections.gif
│ ├── Filter_List_Reports_by_Child_Entity_Fields.gif
│ ├── Grouping_Actions_as_Menu_Button_using_Annotations.mp4
│ └── Enable_Search_on_the_child_entity_fields_in_the_list_report.gif
├── ABAP on HANA
└── Session_Variable.md
├── Workflow
└── Get_Decision_Note_Comments.md
├── CDS
├── Enable_Long_Text.md
├── Filter_List_Reports_by_Child_Entity_Fields.md
├── Enable_Search_on_the_child_entity_fields_in_list_report.md
├── Criticality.abap
├── hide_fields_actions.abap
├── Inline_Actions_in_Object_Page_Sections.md
├── CDS_System_Generate_Series.abap
└── Grouping_Actions_as_Menu_Button_using_Annotations.md
├── ABAP New Syntax
├── range_table.abap
├── segment_function.abap
├── add_leading_zeros_using_string_template(WIDTH).abap
├── CL_ABAP_STRUCT_UTILITIES.abap
├── return_statement.abap
├── step_keyword.abap
├── string_templates.abap
├── Corresponding_with_lookup_table.abap
└── Group_Internal_Table_Data.abap
├── UI5
└── PDF(Base64)_Popup.js
├── Email
├── Validate_Email_address.abap
└── Send_Internal_Table_as_Excel_Attachment.abap
├── ABAP RAP
├── Default_Function_RAP.abap
├── with_full_data.md
├── cl_abap_behv_aux.md
├── static_default _factory_action.abap
├── Show Fields in the Create Popup as Optional in RAP.abap
├── Hide_Fields_Based_on_Other_Field_Value_Immediately.abap
├── Display Message Strip by Default in Object Page.abap
└── Download_Adobe_Form_in_RAP.abap
├── File Handling
├── Create_CSV_File_Using_CL_CSV_FACTORY.abap
└── Read_Excel_data_using_XCO_Libaray.abap
├── ABAP SQL
├── Structure_Indicators.abap
├── STRING_AGG_Function.abap
├── COALESCE_Function.abap
└── window_functions.abap
├── Fiori
└── Construct_FLP_URL.abap
├── JSON
└── JSON_Conversion_in_ABAP.abap
└── ZIP
└── Download_Multiple_Adobe_Form_as_ZIP_file.abap
/README.md:
--------------------------------------------------------------------------------
1 | # ABAP Library
2 | This repository represents my personal ABAP codes
3 |
--------------------------------------------------------------------------------
/src/images/cl_abap_behv_aux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/cl_abap_behv_aux.png
--------------------------------------------------------------------------------
/src/images/Criticality_in_CDS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Criticality_in_CDS.png
--------------------------------------------------------------------------------
/src/images/Session_Variables.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Session_Variables.jpg
--------------------------------------------------------------------------------
/src/images/Enable_LongText_In_CDS.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Enable_LongText_In_CDS.jpg
--------------------------------------------------------------------------------
/src/images/Get_Decision_Note_Comments.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Get_Decision_Note_Comments.jpg
--------------------------------------------------------------------------------
/src/images/Inline_Actions_in_Object_Page_Sections.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Inline_Actions_in_Object_Page_Sections.gif
--------------------------------------------------------------------------------
/src/images/Filter_List_Reports_by_Child_Entity_Fields.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Filter_List_Reports_by_Child_Entity_Fields.gif
--------------------------------------------------------------------------------
/src/images/Grouping_Actions_as_Menu_Button_using_Annotations.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Grouping_Actions_as_Menu_Button_using_Annotations.mp4
--------------------------------------------------------------------------------
/src/images/Enable_Search_on_the_child_entity_fields_in_the_list_report.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bharathi1294/abap_library/HEAD/src/images/Enable_Search_on_the_child_entity_fields_in_the_list_report.gif
--------------------------------------------------------------------------------
/ABAP on HANA/Session_Variable.md:
--------------------------------------------------------------------------------
1 | # Session Variables in ABAP, CDS, AMDP
2 |
3 | In ABAP, we often used session variables. However, what would be their equivalent in AMDP or CDS?
4 | Here's a list of commonly used session variables in ABAP and their equivalent in AMDP/CDS
5 |
6 | 
--------------------------------------------------------------------------------
/Workflow/Get_Decision_Note_Comments.md:
--------------------------------------------------------------------------------
1 | # Get the decision note (approver comments)
2 | Try out this CDS/Class if you need to get the decision note (approver comments) from the work item.
3 |
4 | `1. I_WorkflowTaskResultComment`\
5 | `2. CL_WAPI_DECISION_COMMENT_QUERY`
6 |
7 | Note: If you have this CDS in your system and if you want to retrieve old/completed work item notes, then execute the below report(If required) RSWW_SET_WORKITEM_COMMENTS.
8 |
9 | 
10 |
11 |
--------------------------------------------------------------------------------
/CDS/Enable_Long_Text.md:
--------------------------------------------------------------------------------
1 | # Enable Long Text in CDS
2 | Here's a useful CDS annotation that enables long text/multiline text functionality. If you want to create or display long text fields in your RAP application, you can easily achieve this by using the `@UI.multiLineText` annotation.
3 |
4 | Additionally, if you want to display the long text as a separate tab in your application, you can create a new facet (with type `IDENTIFICATION_REFERENCE` or `FIELDGROUP_REFERENCE`) that references your long text field.
5 |
6 | 
--------------------------------------------------------------------------------
/CDS/Filter_List_Reports_by_Child_Entity_Fields.md:
--------------------------------------------------------------------------------
1 | # Filter List Reports by Child Entity Fields
2 |
3 | Have you ever wanted to filter a list report based on a field from a child entity? For example, filtering travel records by the AirlineID from the associated _Booking entity?
4 |
5 | You can achieve this by adding the following annotation to the root CDS view metadata extensions (e.g., Travel):\
6 |
7 | `@𝗨𝗜.𝘀𝗲𝗹𝗲𝗰𝘁𝗶𝗼𝗻𝗙𝗶𝗲𝗹𝗱: [{ 𝗲𝗹𝗲𝗺𝗲𝗻𝘁: '_𝗕𝗼𝗼𝗸𝗶𝗻𝗴.𝗔𝗶𝗿𝗹𝗶𝗻𝗲𝗜𝗗', 𝗽𝗼𝘀𝗶𝘁𝗶𝗼𝗻: 𝟱𝟬 }]`\
8 | `_𝗕𝗼𝗼𝗸𝗶𝗻𝗴;`
9 |
10 | I tested this in the BTP ABAP Environment, and it works perfectly but only with OData V4.
11 |
12 | 
--------------------------------------------------------------------------------
/ABAP New Syntax/range_table.abap:
--------------------------------------------------------------------------------
1 | "Old way
2 | DATA: lr_salesorder TYPE RANGE OF vbeln.
3 | SELECT vbeln FROM vbak WHERE kunnr = '0000000272' INTO TABLE @DATA(lt_customers_orders).
4 | "Loop
5 | LOOP AT lt_customers_orders INTO DATA(ls_customer_order).
6 | "....
7 | ENDLOOP.
8 | "For
9 | lr_salesorder = VALUE #( FOR ls_order IN lt_customers_orders (
10 | sign = 'I'
11 | option = 'EQ'
12 | low = ls_order-vbeln ) ).
13 |
14 | "New way
15 | SELECT FROM vbak
16 | FIELDS 'I' AS sign,
17 | 'EQ' AS option,
18 | vbeln AS low,
19 | CAST( @space AS CHAR( 10 ) ) AS high
20 | WHERE kunnr = '0000000272'
21 | INTO TABLE @DATA(lr_salesorder).
22 |
23 | "Logic with lr_saleorder
24 |
--------------------------------------------------------------------------------
/UI5/PDF(Base64)_Popup.js:
--------------------------------------------------------------------------------
1 | //Display Base64 PDF in Popup
2 | showPdfPopup: function(Base64Pdf) {
3 | var base64EncodedPDF = Base64Pdf;
4 | var decodedPdfContent = atob(base64EncodedPDF);
5 | var byteArray = new Uint8Array(decodedPdfContent.length);
6 | for (var i = 0; i < decodedPdfContent.length; i++) {
7 | byteArray[i] = decodedPdfContent.charCodeAt(i);
8 | }
9 | var blob = new Blob([byteArray.buffer], {
10 | type: 'application/pdf'
11 | });
12 | var _pdfurl = URL.createObjectURL(blob);
13 | this._PDFViewer = new sap.m.PDFViewer({
14 | title: "Title",
15 | source: _pdfurl,
16 | width:"50%",
17 | showDownloadButton: false
18 | });
19 | jQuery.sap.addUrlWhitelist("blob");
20 |
21 | this._PDFViewer.open();
22 | }
23 |
24 | //Call method
25 | this.showPdfPopup("your base64 string" );
--------------------------------------------------------------------------------
/Email/Validate_Email_address.abap:
--------------------------------------------------------------------------------
1 | * Validates whether a string is a valid mail address (according to RFC 5322 Standard)
2 | CLASS lcl_email DEFINITION.
3 | PUBLIC SECTION.
4 | CLASS-METHODS: validate IMPORTING iv_email TYPE string
5 | RETURNING VALUE(rv_valid) TYPE abap_bool.
6 | ENDCLASS.
7 |
8 | CLASS lcl_email IMPLEMENTATION.
9 | METHOD validate.
10 | TRY.
11 | cl_bcs_email_address=>validate( iv_full_email = iv_email ).
12 | rv_valid = abap_true.
13 | CATCH cx_address_bcs INTO DATA(lx_address).
14 | rv_valid = abap_false.
15 | ENDTRY.
16 | ENDMETHOD.
17 | ENDCLASS.
18 |
19 | * Test the email address
20 | IF lcl_email=>validate( iv_email = 'anyemailaddress@gmail.com' ).
21 | "Valid Email Address
22 | ELSE.
23 | "Invalid Email address
24 | ENDIF.
25 |
--------------------------------------------------------------------------------
/CDS/Enable_Search_on_the_child_entity_fields_in_list_report.md:
--------------------------------------------------------------------------------
1 | # 𝗘𝗻𝗮𝗯𝗹𝗲 𝗦𝗲𝗮𝗿𝗰𝗵 𝗼𝗻 𝗖𝗵𝗶𝗹𝗱 𝗘𝗻𝘁𝗶𝘁𝘆 𝗙𝗶𝗲𝗹𝗱𝘀 𝗶𝗻 𝗟𝗶𝘀𝘁 𝗥𝗲𝗽𝗼𝗿𝘁
2 |
3 | If you want to make fields from an child entity available in the global search(List Report), Just follow these steps to achieve.
4 |
5 | In your Root Entity, mark the exposed child entity with the annotation:\
6 | `@𝗦𝗲𝗮𝗿𝗰𝗵.𝗱𝗲𝗳𝗮𝘂𝗹𝘁𝗦𝗲𝗮𝗿𝗰𝗵𝗘𝗹𝗲𝗺𝗲𝗻𝘁: 𝘁𝗿𝘂𝗲`\
7 | `_𝗕𝗼𝗼𝗸𝗶𝗻𝗴;`
8 |
9 | In the child entity, specify the fields you want to be searchable:\
10 | `@𝗦𝗲𝗮𝗿𝗰𝗵.𝗱𝗲𝗳𝗮𝘂𝗹𝘁𝗦𝗲𝗮𝗿𝗰𝗵𝗘𝗹𝗲𝗺𝗲𝗻𝘁: 𝘁𝗿𝘂𝗲`\
11 | `𝗖𝗮𝗿𝗿𝗶𝗲𝗿𝗡𝗮𝗺𝗲;`
12 |
13 | You can also enhance the search experience by enabling fuzzy search settings. Once this is done, the relevant fields will be included in the global search.
14 |
15 | 
--------------------------------------------------------------------------------
/ABAP RAP/Default_Function_RAP.abap:
--------------------------------------------------------------------------------
1 | "Step 1: Define a default function in your Behavior Definition (BDEF)
2 | define behavior for ZR_ROOT_ENTITY alias Travel
3 | ....
4 | {
5 | ...
6 | create{ default function GetDefaultsForCreate; }
7 |
8 | }
9 |
10 | "Step 2: Implement the logic in the behavior class
11 | METHOD GetDefaultsForCreate.
12 | result = VALUE #( FOR key IN keys (
13 | %cid = key-%cid
14 | %param = VALUE #( CurrencyCode = 'INR'
15 | BeginDate = cl_abap_context_info=>get_system_date( )
16 | OverallStatus = 'O' ) ) ).
17 | ENDMETHOD.
18 |
19 | "Step 3: Use the function in your Projection BDEF(If you defined)
20 | projection;
21 | strict(2);
22 |
23 | define behavior for ZC_ROOT_ENTITY alias Travel
24 | ...
25 | {
26 | ...
27 | use function GetDefaultsForCreate;
28 | }
29 |
30 | "Step 4: That’s it! Now when you try to create a new record, the values will be pre-filled automatically
31 |
--------------------------------------------------------------------------------
/ABAP RAP/with_full_data.md:
--------------------------------------------------------------------------------
1 | The additions `𝘄𝗶𝘁𝗵 𝗮𝗱𝗱𝗶𝘁𝗶𝗼𝗻𝗮𝗹 𝘀𝗮𝘃𝗲` and `𝘄𝗶𝘁𝗵 𝘂𝗻𝗺𝗮𝗻𝗮𝗴𝗲𝗱 𝘀𝗮𝘃𝗲` can be used to enhance or to replace the default save sequence in a managed RAP BO.
2 | Both additions require a reimplementation of the `𝘀𝗮𝘃𝗲_𝗺𝗼𝗱𝗶𝗳𝗶𝗲𝗱` method of the RAP saver class.
3 |
4 | When the `𝘀𝗮𝘃𝗲_𝗺𝗼𝗱𝗶𝗳𝗶𝗲𝗱` method called we will receive only changed fields value in the update method.
5 | In scenarios where all fields, not only changed fields, are required for further processing, the addition `𝘄𝗶𝘁𝗵 𝗳𝘂𝗹𝗹 𝗱𝗮𝘁𝗮` can be used.
6 | By doing this, the RAP BO consumer avoids having to do an extra READ operation.
7 |
8 | `..𝘄𝗶𝘁𝗵 𝗮𝗱𝗱𝗶𝘁𝗶𝗼𝗻𝗮𝗹 𝘀𝗮𝘃𝗲 𝘄𝗶𝘁𝗵 𝗳𝘂𝗹𝗹 𝗱𝗮𝘁𝗮`
9 | `..𝘄𝗶𝘁𝗵 𝘂𝗻𝗺𝗮𝗻𝗮𝗴𝗲𝗱 𝘀𝗮𝘃𝗲 𝘄𝗶𝘁𝗵 𝗳𝘂𝗹𝗹 𝗱𝗮𝘁𝗮`
10 |
11 | Note:
12 | The fields of the component group `%𝗰𝗼𝗻𝘁𝗿𝗼𝗹` are not affected by this. Still, only the changed fields of %𝗰𝗼𝗻𝘁𝗿𝗼𝗹 are flagged.
13 |
14 | For More Info.
15 | https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenbdl_saving.htm
--------------------------------------------------------------------------------
/ABAP RAP/cl_abap_behv_aux.md:
--------------------------------------------------------------------------------
1 | # The usage of the class 𝗰𝗹_𝗮𝗯𝗮𝗽_𝗯𝗲𝗵𝘃_𝗮𝘂𝘅.
2 |
3 | Recently, I came across a scenario I’d like to share. I had a BDEF named `R_SomeName`, and on top of that, I created two projections: one for the `UI (C_SomeName)` and another for the `API (A_SomeName)`.
4 |
5 | Now, here's the interesting part: `R_SomeName` contains some validations and determinations. For the time being, I only want these to execute when the call is coming from the UI, not from the API.
6 |
7 | So, how can we distinguish whether the call originates from the UI or the API? This is where the class `𝗰𝗹_𝗮𝗯𝗮𝗽_𝗯𝗲𝗵𝘃_𝗮𝘂𝘅` comes in handy:
8 |
9 | `𝗰𝗹_𝗮𝗯𝗮𝗽_𝗯𝗲𝗵𝘃_𝗮𝘂𝘅=>𝗴𝗲𝘁_𝗰𝘂𝗿𝗿𝗲𝗻𝘁_𝗰𝗼𝗻𝘁𝗲𝘅𝘁( 𝗜𝗠𝗣𝗢𝗥𝗧𝗜𝗡𝗚 𝗳𝗿𝗼𝗺_𝗽𝗿𝗼𝗷𝗲𝗰𝘁𝗶𝗼𝗻 = 𝗗𝗔𝗧𝗔(𝗹𝘃_𝗽𝗿𝗼𝗷) ).`
10 |
11 | The lv_proj variable will hold the name of the calling projection `C_SomeName` if the call is from the UI or `A_SomeName` if it’s from the API. Based on this, you can conditionally execute logic in the handler class of `R_SomeName`.
12 |
13 | 
--------------------------------------------------------------------------------
/CDS/Criticality.abap:
--------------------------------------------------------------------------------
1 | Highlight Line Items and Columns Based on Criticality
2 | "Step 1: Derive the CriticalityCode Based on OverallStatus
3 | define root view entity ZR_ROOT_ENTITY
4 | {
5 | ...
6 | OverallStatus,
7 | case $projection.OverallStatus
8 | when 'A' then 3 // 3 - Green
9 | when 'X' then 1 // 2 - Red
10 | when 'O' then 2 // 1 - Yellow
11 | else 0 // 0 - Neutral
12 | end as CriticalityCode
13 | }
14 | "Step 2: Expose CriticalityCode in the Projection View
15 | define root view entity ZC_ROOT_ENTITY
16 | provider contract transactional_query
17 | as projection on ZR_ROOT_ENTITY
18 | {
19 | ...
20 | OverallStatus,
21 | CriticalityCode
22 | }
23 | "Step 3: Annotate in Metadata Extension
24 | @UI.lineItem: [{ criticality: 'CriticalityCode' }]
25 | annotate view ZC_ROOT_ENTITY with {
26 | ....
27 | @UI: { lineItem: [{position: 10, importance: #HIGH, criticality: 'CriticalityCode', criticalityRepresentation: #WITH_ICON }] }
28 | OverallStatus;
29 | }
30 |
31 | "Step 4: That's it. see the result - src/images/Criticality_in_CDS.png
--------------------------------------------------------------------------------
/ABAP New Syntax/segment_function.abap:
--------------------------------------------------------------------------------
1 | "Segment - This function returns the occurrence of a segment of the argument text specified by index
2 |
3 | "index: Number of segment
4 | "sep: Substring specified is searched and used as limit
5 | "Hallo
6 | DATA(segment1) = segment( val = `Hallo,world,123` index = 1 sep = `,` ).
7 |
8 | "123
9 | DATA(segment2) = segment( val = `Hallo,world,123` index = -1 sep = `,` ).
10 |
11 | "world
12 | DATA(segment3) = segment( val = `Hallo
world
123` index = 2 sep = `
` ).
13 |
14 | "space: Each individual character is searched and used as limit
15 | DATA(to_be_segmented) = `a/b#c d.e`.
16 |
17 | "b
18 | DATA(segment4) = segment( val = `a/b#c d.e` index = 2 space = `. #/` ).
19 |
20 | DATA segment_tab TYPE string_table.
21 | DO.
22 | TRY.
23 | INSERT segment( val = to_be_segmented
24 | index = sy-index
25 | space = `. #/` ) INTO TABLE segment_tab.
26 | CATCH cx_sy_strg_par_val.
27 | EXIT.
28 | ENDTRY.
29 | ENDDO.
30 |
31 | *Content of segment_tab
32 | *a
33 | *b
34 | *c
35 | *d
36 | *e
--------------------------------------------------------------------------------
/CDS/hide_fields_actions.abap:
--------------------------------------------------------------------------------
1 | "New field in the CDS View
2 | case when EmployeeStatus = 'RETIRED'
3 | then cast( 'X' as abap_boolean preserving type )
4 | else cast( '' as abap_boolean preserving type )
5 | end as HideCourseList
6 |
7 | "Metadata Extensions
8 | "Hide Facet in the Object Page
9 | @UI.facet: [{ type: #LINEITEM_REFERENCE,
10 | position: 20,
11 | id: 'CourseData',
12 | label: 'Courses',
13 | targetElement: '_Courses',
14 | purpose: #STANDARD,
15 | hidden: #(HideCourseList) }
16 |
17 | "Hide Standard Operations in the object page - Avaialble from S4HANA 2023+
18 | @UI.createHidden: #(HideCourseList)
19 | @UI.updateHidden: #(HideCourseList)
20 | @UI.deleteHidden: #(HideCourseList)
21 | annotate entity .....
22 | with
23 |
24 | "Hide Field
25 | @UI.hidden: #(HideCourseList)
26 | field_name;
27 |
28 | "Hide field from Facet Group
29 | @UI.identification: [{ hidden: #(HideCourseList) }]
30 | field_name;
31 |
32 | @UI.fieldGroup: [{ hidden: #(HideCourseList) }]
33 | field_name;
34 |
35 | "Etc,.
36 |
--------------------------------------------------------------------------------
/File Handling/Create_CSV_File_Using_CL_CSV_FACTORY.abap:
--------------------------------------------------------------------------------
1 | SELECT FROM vbak
2 | FIELDS vbeln, vbtyp, erdat
3 | INTO TABLE @DATA(lt_test)
4 | UP TO 10 ROWS.
5 |
6 | "Simple CSV generation with header:
7 | DATA(lv_xstring_v1) = cl_csv_factory=>new_writer(
8 | )->set_delimiter( ';'
9 | )->set_write_header( abap_true
10 | )->write( REF #( lt_test ) ).
11 |
12 | "CSV generation with custom headers and field formatting:
13 | DATA(lv_xstring_v2) = cl_csv_factory=>new_writer(
14 | )->set_delimiter( ';'
15 | )->set_write_header( abap_true
16 | )->write(
17 | itab_ref = REF #( lt_test )
18 | fieldcatalog = VALUE if_csv_field_catalog=>ty_t_fieldcatalog(
19 | ( fieldname = 'VBELN' header_text = |Sales Order| )
20 | ( fieldname = 'VBTYP' header_text = |Sales Document Type| )
21 | ( fieldname = 'ERDAT' header_text = |Created On| format = cl_csv_field_format=>date_iso ) ) ).
22 |
--------------------------------------------------------------------------------
/ABAP New Syntax/add_leading_zeros_using_string_template(WIDTH).abap:
--------------------------------------------------------------------------------
1 | *If you are using string templates(with ALPHA) to add leading zeros, just have a look at the use of the WIDTH keyword.
2 | *It may be useful where we need to add dynamic number of leading zeros for the same input
3 | CLASS lcl_add_leading_zeros DEFINITION
4 | CREATE PUBLIC.
5 | PUBLIC SECTION.
6 | CLASS-METHODS: add_leading_zeros
7 | IMPORTING iv_input TYPE string
8 | iv_length TYPE int4
9 | RETURNING VALUE(rv_output) TYPE string.
10 | ENDCLASS.
11 |
12 | CLASS lcl_add_leading_zeros IMPLEMENTATION.
13 | METHOD add_leading_zeros.
14 | rv_output = |{ iv_input ALPHA = IN WIDTH = iv_length }|.
15 | ENDMETHOD.
16 | ENDCLASS.
17 |
18 | START-OF-SELECTION.
19 | DATA(lv_input) = '123'.
20 | "-> Convert input as a sales order number - VBELN (10)
21 | DATA(lv_so) = lcl_add_leading_zeros=>add_leading_zeros( iv_input = lv_input iv_length = 10 ).
22 | "Output - 0000000123
23 | "-> Convert input as a contract number - RANL (13)
24 | DATA(lv_cn) = lcl_add_leading_zeros=>add_leading_zeros( iv_input = lv_input iv_length = 13 ).
25 | "Output - 0000000000123
26 |
--------------------------------------------------------------------------------
/ABAP SQL/Structure_Indicators.abap:
--------------------------------------------------------------------------------
1 | "𝗔𝗕𝗔𝗣 𝗦𝗤𝗟: 𝗜𝗻𝗱𝗶𝗰𝗮𝘁𝗼𝗿 𝗦𝘁𝗿𝘂𝗰𝘁𝘂𝗿𝗲𝘀
2 | "If you've worked with RAP, you might be familiar with the %𝗰𝗼𝗻𝘁𝗿𝗼𝗹 component group.
3 | "This structure contains all key and data fields as components, represented as flags.
4 | "It is used to determine which fields are provided to Create/Update during CREATE or UPDATE operations using EML.
5 |
6 | "A similar concept exists in ABAP SQL with 𝗦𝗤𝗟 𝗜𝗻𝗱𝗶𝗰𝗮𝘁𝗼𝗿𝘀.
7 | "These indicators are useful for partially updating a database table by setting specific fields.
8 |
9 | * Data structure with additional set indicator
10 | TYPES: ty_sflight TYPE sflight WITH INDICATORS set_ind.
11 | DATA: it_sflight TYPE STANDARD TABLE OF ty_sflight WITH DEFAULT KEY.
12 |
13 | SELECT FROM sflight
14 | FIELDS carrid, connid, fldate, price
15 | WHERE carrid = 'AA'
16 | AND connid = '0017'
17 | AND fldate = '20230929'
18 | INTO CORRESPONDING FIELDS OF TABLE @it_sflight.
19 |
20 | * Update Price
21 | LOOP AT it_sflight ASSIGNING FIELD-SYMBOL().
22 | -price = '100'.
23 | -set_ind-price = '01'.
24 | ENDLOOP.
25 |
26 | * Only update the columns with Set-Indicator='01'
27 | UPDATE sflight FROM TABLE @it_sflight INDICATORS SET STRUCTURE set_ind.
--------------------------------------------------------------------------------
/ABAP New Syntax/CL_ABAP_STRUCT_UTILITIES.abap:
--------------------------------------------------------------------------------
1 | TYPES: BEGIN OF ty_user,
2 | user_id1 TYPE buname,
3 | user_id2 TYPE buname,
4 | user_id3 TYPE buname,
5 | user_id4 TYPE buname,
6 | user_id5 TYPE buname,
7 | END OF ty_user,
8 | BEGIN OF ty_users,
9 | user_id TYPE buname,
10 | END OF ty_users,
11 | tt_users TYPE TABLE OF ty_users WITH EMPTY KEY.
12 |
13 | DATA(ls_user) = VALUE ty_user( user_id1 = 'USER1' user_id2 = 'USER2' user_id3 = '' user_id4 = 'USER4' user_id5 = 'USER5' ).
14 | ASSIGN ls_user TO FIELD-SYMBOL().
15 |
16 | DATA(lt_users) = REDUCE tt_users( INIT _users TYPE tt_users
17 | FOR comp IN cl_abap_struct_utilities=>filled_components( ls_user )
18 | NEXT _users = VALUE #( BASE _users ( user_id = -(comp-name) ) ) ).
19 |
20 | "Other useful methods,
21 | " 1. cl_abap_struct_utilities=>filled_components_c( )
22 | " 2. cl_abap_struct_utilities=>filled_components_x( )
23 |
24 | "https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENCL_ABAP_STRUCT_UTILITIES.html
25 | "https://github.com/SAP-samples/abap-cheat-sheets/blob/main/22_Released_ABAP_Classes.md#information-about-non-initial-structure-components
26 |
--------------------------------------------------------------------------------
/ABAP New Syntax/return_statement.abap:
--------------------------------------------------------------------------------
1 | *In ABAP, the 𝗥𝗘𝗧𝗨𝗥𝗡 statement has been used to exit a procedure, such as a method or a function module.
2 | *Unlike many other programming languages where 𝗿𝗲𝘁𝘂𝗿𝗻 is used to pass a value back from a function, earlier versions of ABAP did not support this functionality.
3 | *However, starting with ABAP 7.58, the 𝗥𝗘𝗧𝗨𝗥𝗡 statement can now be used to return a value directly from a method.
4 | *Note: This applies only to methods that have a returning parameter.
5 | CLASS lcl_demo DEFINITION.
6 | PUBLIC SECTION.
7 | CLASS-METHODS:
8 | return RETURNING VALUE(rv_value) TYPE text100,
9 | return_with_value RETURNING VALUE(rv_value) TYPE text100,
10 | return_structure RETURNING VALUE(rs_vbak) TYPE vbak,
11 | return_table RETURNING VALUE(rt_table) TYPE tt_vbak.
12 | ENDCLASS.
13 |
14 | CLASS lcl_demo IMPLEMENTATION.
15 | METHOD return.
16 | rv_value = 'Something'.
17 | RETURN.
18 | ENDMETHOD.
19 |
20 | METHOD return_with_value.
21 | RETURN 'something'.
22 | ENDMETHOD.
23 |
24 | METHOD return_structure.
25 | RETURN VALUE #( vbeln = '1' erdat = '20231212' ).
26 | ENDMETHOD.
27 |
28 | METHOD return_table.
29 | RETURN VALUE #( ( vbeln = '1' erdat = '20231212' )
30 | ( vbeln = '2' erdat = '20231212' ) ).
31 | ENDMETHOD.
32 | ENDCLASS.
--------------------------------------------------------------------------------
/CDS/Inline_Actions_in_Object_Page_Sections.md:
--------------------------------------------------------------------------------
1 | # 𝗔𝗰𝘁𝗶𝗼𝗻𝘀/𝗜𝗻𝗹𝗶𝗻𝗲 𝗔𝗰𝘁𝗶𝗼𝗻𝘀 𝗶𝗻 𝗢𝗯𝗷𝗲𝗰𝘁 𝗣𝗮𝗴𝗲 𝗦𝗲𝗰𝘁𝗶𝗼𝗻𝘀
2 |
3 | Have you ever faced a scenario where you wanted to add RAP actions specific to a section of the Object Page,not the entire page? If yes, this is for you!
4 |
5 | You can achieve this by leveraging `@𝗨𝗜.𝗳𝗮𝗰𝗲𝘁` and `@𝗨𝗜.𝗳𝗶𝗲𝗹𝗱𝗚𝗿𝗼𝘂𝗽` annotations. It’s also possible to add inline actions using the 𝗶𝗻𝗹𝗶𝗻𝗲: 𝘁𝗿𝘂𝗲 property( available from SAP S/4HANA 2023 and in the latest public cloud versions).
6 |
7 | Use Case Example: A colleague recently had a requirement to add a section-specific action to reset certain data, placing the action inside the relevant section made the UX cleaner and more intuitive.
8 |
9 | `@UI.facet: [ {`\
10 | `label: 'General Information',`\
11 | `id: 'GeneralInfo',`\
12 | `purpose: #STANDARD,`\
13 | `position: 10 ,`\
14 | `type: #FIELDGROUP_REFERENCE,`\
15 | `targetQualifier: 'generalInfo'`\
16 | `} ]`
17 |
18 | `@UI.fieldGroup: [{`\
19 | `qualifier: 'generalInfo',`\
20 | `type: #FOR_ACTION,`\
21 | `position: 10,`\
22 | `dataAction: 'formAction',`\
23 | `inline: true,` //Action will be placed inside the section\
24 | `label: 'Reset Data(Form Action)',`\
25 | `emphasized: true }]`\
26 | `element;`
27 |
28 | 
29 |
--------------------------------------------------------------------------------
/ABAP New Syntax/step_keyword.abap:
--------------------------------------------------------------------------------
1 | "𝗦𝗧𝗘𝗣 𝗞𝗲𝘆𝘄𝗼𝗿𝗱 𝗶𝗻 𝗔𝗕𝗔𝗣
2 | "The 𝗦𝗧𝗘𝗣 keyword in ABAP simplifies working with loops when you want to skip odd or even indices.
3 | "Previously, this was achieved using 𝘀𝘆-𝘁𝗮𝗯𝗶𝘅, but with STEP, you can directly control both the step size and the loop's direction, making the process more straightforward and efficient.
4 | "Here is a small example,
5 |
6 | TYPES: tt_numbers TYPE TABLE OF int8 WITH EMPTY KEY.
7 | DATA(lt_numbers) = VALUE tt_numbers( FOR i = 1 THEN i + 1 WHILE i < 11 ( CONV #( i ) ) ).
8 |
9 | "Step with Positive number -> Forward
10 | LOOP AT lt_numbers INTO DATA(forward_num) STEP 2.
11 | WRITE:/ forward_num.
12 | ENDLOOP.
13 | DATA(lt_step_forward) = VALUE tt_numbers( FOR num in lt_numbers STEP 2 ( num ) ).
14 | "Output -> 1,3,5,7,9
15 |
16 | "Step with Negative Number -> Backword
17 | LOOP at lt_numbers INTO DATA(backword_num) STEP -2.
18 | WRITE:/ backword_num.
19 | ENDLOOP.
20 | DATA(lt_step_backward) = VALUE tt_numbers( FOR num in lt_numbers STEP -2 ( num ) ).
21 | "Output -> 10,8,6,4,2
22 |
23 | "Step with From and To
24 | LOOP AT lt_numbers INTO DATA(from_to_index) FROM 6 STEP -1.
25 | WRITE:/ from_to_index.
26 | ENDLOOP.
27 | DATA(lt_step_from_to) = VALUE tt_numbers( FOR num in lt_numbers FROM 6 STEP -1 ( num ) ).
28 | "Outpu -> 6,5,4,3,2,1
29 |
30 | "Step can be used in
31 | "LINES OF jtab [FROM idx1] [TO idx2] [STEP n] [USING KEY keyname]
32 |
--------------------------------------------------------------------------------
/Fiori/Construct_FLP_URL.abap:
--------------------------------------------------------------------------------
1 | "Are you manually constructing FLP URLs? then try out this class 𝗖𝗟_𝗟𝗦𝗔𝗣𝗜_𝗠𝗔𝗡𝗔𝗚𝗘𝗥 to simplify that.
2 | "You will need it in case you want to
3 |
4 | ".. Launch Fiori apps from GUI.
5 | ".. Generate a Dynamic Fiori URL by using using Semantic Objects, Actions, and Parameters.
6 | ".. Share specific Fiori app links via email.
7 | ".. Call Transaction, etc,.
8 |
9 |
10 | DATA(lo_lsapi) = cl_lsapi_manager=>get_instance( ).
11 |
12 | "Create URL to Access Fiori Apps
13 | DATA(lv_flp_app_url) = cl_lsapi_manager=>create_flp_url(
14 | object = 'MaintenanceObject' "Fiori Intent Semantic Object Value
15 | action = 'listFunctionalLocStructure' "Fiori Intent Action Value
16 | system_alias = 'LOCAL' "SM59 Based System Alias of Fiori Front End Server
17 | parameters = VALUE #( name = 'DY_TPLNR' value = '0001' )
18 | ).
19 |
20 | "Create URL to Access Transaction Code
21 | DATA(lv_tcode_url) = cl_lsapi_manager=>create_flp_url(
22 | system_alias = 'LOCAL' "SM59 Based System Alias of Fiori Frontend Server
23 | parameters = VALUE #( ( name = 'DY_TPLNR' value = '0001' ) ) "Parameters in hash part of URL
24 | transaction = 'IH01' "Transaction Code
25 | ).
26 |
27 | "Ways to OPEN/Navigate to URL
28 | lo_lsapi->navigate(
29 | location = lv_flp_app_url
30 | mode = lo_lsapi->gc_s_navigation_mode-inplace
31 | ).
32 |
33 | cl_lsapi_manager=>open_url( url = lv_tcode_url ).
--------------------------------------------------------------------------------
/ABAP SQL/STRING_AGG_Function.abap:
--------------------------------------------------------------------------------
1 | *In ABAP, the STRING_AGG function is used to concatenate values from multiple rows into a single string, with a specified delimiter.
2 | *Here is a small example, this table have a customer id and course name, want to aggregate all course name for each customer id into a single string, separated by commas.
3 | *this can be easily achieved through STRING_AGG function.
4 | *Note: STRING_AGG concatenates the results of an SQL expression in one line (type SSTRING, length 1333).
5 | *If the string is longer than 1333 characters, an exception (CX_SY_OPEN_SQL_DB) is thrown.
6 | *The limitation to 1333 characters can be bypassed by the function TO_CLOB. This is available in ABAP SQL from ABAP 7.54+.
7 |
8 | TYPES: BEGIN OF ty_employee,
9 | employee_id TYPE pernr_d,
10 | course_name TYPE text100,
11 | END OF ty_employee,
12 | tt_employee TYPE TABLE OF ty_employee WITH EMPTY KEY.
13 |
14 | DATA(lt_employees) = VALUE tt_employee(
15 | ( employee_id = '1' course_name = 'ABAP' )
16 | ( employee_id = '1' course_name = 'UI5' )
17 | ( employee_id = '1' course_name = 'Fiori' )
18 | ( employee_id = '2' course_name = 'ABAP' )
19 | ( employee_id = '2' course_name = 'UI5' ) ).
20 |
21 | SELECT FROM @lt_employees AS employees
22 | FIELDS employee_id,
23 | to_clob( STRING_AGG( course_name, ',' ) ) AS courses
24 | GROUP BY employee_id
25 | INTO TABLE @DATA(lt_emp_courses).
26 |
27 | "Output
28 | *EMPLOYEE_ID COURSES
29 | *00000001 ABAP, UI5, Fiori
30 | *00000002 ABAP, UI5
--------------------------------------------------------------------------------
/CDS/CDS_System_Generate_Series.abap:
--------------------------------------------------------------------------------
1 | "Here are some useful standard CDS system entities for 𝗴𝗲𝗻𝗲𝗿𝗮𝘁𝗶𝗻𝗴 𝘀𝗲𝗿𝗶𝗲𝘀, which can be quite handy in various scenarios:
2 |
3 | "1.SERIES_GENERATE_DATE -> Generate Dates
4 | SELECT * FROM series_generate_date( step = 1,
5 | from_value = '20250101',
6 | to_value = '20250130' )
7 | ORDER BY element_number
8 | INTO TABLE @DATA(date_series_gen).
9 |
10 | "2.SERIES_GENERATE_INTEGER - Generate Integer
11 | SELECT * FROM series_generate_integer( step = 1,
12 | from_value = 1,
13 | to_value = 100 )
14 | ORDER BY element_number
15 | INTO TABLE @DATA(integer_series_gen).
16 |
17 | "3. SERIES_GENERATE_TIME - Generate Time
18 | DATA(time) = cl_demo_date_time=>get_user_time( ).
19 | DATA(seconds_added) = time + 20.
20 |
21 | SELECT * FROM series_generate_time( step = 2,
22 | from_value = @time,
23 | to_value = @seconds_added )
24 | ORDER BY element_number
25 | INTO TABLE @DATA(time_series_gen).
26 |
27 | "4.SERIES_GENERATE_TIMESTAMP - Generate Timestamp
28 | DATA(ts_from) = utclong_current( ).
29 | DATA(ts_to) = utclong_add( val = ts_from seconds = 10 ).
30 |
31 | SELECT * FROM series_generate_timestamp( step = 2,
32 | from_value = @ts_from,
33 | to_value = @ts_to )
34 | ORDER BY element_number
35 | INTO TABLE @DATA(timestamp_series_gen).
36 |
37 |
--------------------------------------------------------------------------------
/ABAP SQL/COALESCE_Function.abap:
--------------------------------------------------------------------------------
1 | *The COALESCE function takes a list of at least two (and up to 255) arguments (arg1, arg2, ..., argn).
2 | *It returns the first non-null value from the list, or the last argument if all are null.
3 |
4 | DATA(lt_salesorders) = VALUE tt_salesorder(
5 | ( salesorder = '1' netvalue = '100.00' customer = 'CUST_1' )
6 | ( salesorder = '2' netvalue = '100.00' customer = 'CUST_2' )
7 | ( salesorder = '3' netvalue = '100.00' customer = 'CUST_3' )
8 | ).
9 |
10 | DATA(lt_customer_one) = VALUE tt_customer(
11 | ( customer = 'CUST_1' customername = 'Customer 1' addressid = 1 )
12 | ).
13 |
14 | DATA(lt_customer_two) = VALUE tt_customer(
15 | ( customer = 'CUST_2' customername = 'Customer 2' addressid = 2 )
16 | ).
17 |
18 | DATA(lt_customer_address) = VALUE tt_customer_address(
19 | ( addressid = 1 address = 'Sitheri, Cuddalore' )
20 | ( addressid = 2 address = 'Velluvadi, Perambalur' )
21 | ).
22 |
23 | SELECT FROM @lt_salesorders AS a
24 | LEFT OUTER JOIN @lt_customer_one AS b ON b~customer = a~customer
25 | LEFT OUTER JOIN @lt_customer_two AS c ON c~customer = a~customer
26 | LEFT OUTER JOIN @lt_customer_address AS d ON d~addressid = COALESCE( b~addressid, c~addressid )
27 | FIELDS a~salesorder,
28 | a~netvalue,
29 | a~customer,
30 | COALESCE( b~customername, c~customername ) AS customername,
31 | d~address AS customeraddress
32 | INTO TABLE @DATA(lt_salesorders_with_customer).
33 |
34 | "Output
35 | *SALESORDER NETVALUE CUSTOMER CUSTOMERNAME CUSTOMERADDRESS
36 | *1 100.0 CUST_1 Customer 1 Sitheri, Cuddalore
37 | *2 100.0 CUST_2 Customer 2 Velluvadi, Perambalur
38 | *3 100.0 CUST_3
--------------------------------------------------------------------------------
/ABAP New Syntax/string_templates.abap:
--------------------------------------------------------------------------------
1 | "String Templates
2 | "ALPHA(IN/OUT)
3 | DATA(lv_vbeln) = CONV vbeln( '1' ).
4 | lv_vbeln = |{ lv_vbeln ALPHA = IN }|. "-> 0000000001
5 | lv_vbeln = |{ lv_vbeln ALPHA = OUT }|. "-> 1
6 |
7 | "WIDTH
8 | DATA(lv_vbeln_with_extra_zeros) = |{ lv_vbeln ALPHA = IN WIDTH = 15 }|. "->000000000000001
9 |
10 | "CURRENCY
11 | DATA(lv_amount) = 123456.
12 | DATA(lv_inr) = |{ lv_amount CURRENCY = 'INR' }|. "1234.56
13 | DATA(lv_omr) = |{ lv_amount CURRENCY = 'OMR' }|. "123.456
14 |
15 | "NUMBER
16 | DATA(lv_number) = 12345678.
17 | DATA(lv_user_specific) = |{ lv_number NUMBER = USER }|. "12.345.678
18 | SET COUNTRY 'US'.
19 | DATA(lv_env) = |{ lv_number NUMBER = ENVIRONMENT }|. "12,345,678
20 |
21 | "DATE -> Same we have for TIME,TIMESTAMP
22 | DATA(lv_date) = sy-datum.
23 | DATA(lv_user_date) = |{ lv_date DATE = USER }|. "20.01.2025
24 | DATA(lv_iso_date) = |{ lv_date DATE = ISO }|. "2025-01-20
25 |
26 | "DECIMAL
27 | DATA(lv_decimal) = CONV f( `1234.456877` ).
28 | DATA(lv_3_decimal) = |{ lv_decimal DECIMALS = 3 }|. "1234.457
29 |
30 | "CASE
31 | DATA(lv_name) = `Bharathi S`.
32 | DATA(lv_uppercase) = |{ lv_name CASE = UPPER }|. "BHARATHI S"
33 | DATA(lv_lowercase) = |{ lv_name CASE = LOWER }|. "bharathi s"
34 |
35 | "SIGN
36 | DATA(lv_sign) = 123.
37 | DATA(lv_plus_sign) = |{ lv_sign SIGN = LEFTPLUS }|. "+123
38 | DATA(lv_right_plus_sign) = |{ lv_sign SIGN = RIGHTPLUS }|. "123+
39 |
40 | "ALIGN
41 | DATA(lv_text) = '1'.
42 | DATA(lv_align_right) = |{ lv_text ALIGN = RIGHT WIDTH = 5 }|." 1
43 |
44 | "PAD
45 | DATA(lv_pad) = |{ lv_text ALIGN = RIGHT WIDTH = 5 PAD = '_' }|."____1
46 |
47 | "https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapcompute_string_format_options.htm
48 |
--------------------------------------------------------------------------------
/ABAP New Syntax/Corresponding_with_lookup_table.abap:
--------------------------------------------------------------------------------
1 | "𝗖𝗢𝗥𝗥𝗘𝗦𝗣𝗢𝗡𝗗𝗜𝗡𝗚 𝘄𝗶𝘁𝗵 𝗹𝗼𝗼𝗸𝘂𝗽 𝘁𝗮𝗯𝗹𝗲.
2 | "The CORRESPONDING operator can be used to create a new data object from a structured data object, such as an internal table or structure, by copying the values of fields with matching names.
3 | "Additionally, the operator can perform a lookup on another internal table to populate specific field values.
4 |
5 | TYPES: BEGIN OF ty_employee,
6 | emp_id TYPE pernr_d,
7 | emp_name TYPE text100,
8 | manager_id TYPE pernr_d,
9 | manager_name TYPE text100,
10 | emp_position TYPE text100,
11 | END OF ty_employee,
12 | tt_employee TYPE TABLE OF ty_employee WITH EMPTY KEY,
13 | BEGIN OF ty_manager,
14 | mgr_id TYPE pernr_d,
15 | mgr_name TYPE text100,
16 | END OF ty_manager.
17 |
18 | DATA lt_managers TYPE HASHED TABLE OF ty_manager WITH UNIQUE KEY mgr_id.
19 | DATA lt_employees TYPE tt_employee.
20 | DATA lt_emp_with_mgr_name TYPE tt_employee.
21 |
22 | "Employee data w/o manager name
23 | lt_employees = VALUE #(
24 | ( emp_id = '1' emp_name = 'Name 1' emp_position = 'DEV_1' manager_id = '1' )
25 | ( emp_id = '2' emp_name = 'Name 2' emp_position = 'DEV_2' manager_id = '2' ) ).
26 |
27 | "Manager data - Lookup Table
28 | lt_managers = VALUE #(
29 | ( mgr_id = '1' mgr_name = 'Manager 1' )
30 | ( mgr_id = '2' mgr_name = 'Manager 2' ) ).
31 |
32 | "Employee data with manager name from lookup table
33 | lt_emp_with_mgr_name = CORRESPONDING #( lt_employees
34 | FROM lt_managers USING manager_id
35 | MAPPING manager_name = mgr_name ).
36 |
37 | "Output
38 | "EMP_ID EMP_NAME MANAGER_ID MANAGER_NAME EMP_POSITION
39 | "00000001 Name 1 00000001 Manager 1 DEV_1
40 | "00000002 Name 2 00000002 Manager 2 DEV_2
--------------------------------------------------------------------------------
/ABAP RAP/static_default _factory_action.abap:
--------------------------------------------------------------------------------
1 | "Step 1 – Define static default factory action in R_* BDEF
2 | define behavior for ZR_ROOT alias ROOT
3 | {
4 | create;
5 | update;
6 | delete;
7 |
8 | static default factory action createCustomer parameter ZD_CustomerData [1];
9 | }
10 | "Here, createCustomer will be triggered instead of the standard create.
11 |
12 | "Step 2 – Create abstract entity for action parameters
13 | @EndUserText.label: 'Customer Data'
14 | define abstract entity ZD_CustomerData
15 | {
16 | @EndUserText.label: 'Customer ID'
17 | CustomerId : int4;
18 |
19 | @EndUserText.label: 'First Name'
20 | FirstName : abap.char(20);
21 |
22 | @EndUserText.label: 'Last Name'
23 | LastName : abap.char(20);
24 | }
25 | "This entity defines the parameters passed to the static action.
26 |
27 | "Step 3 – Implement custom logic in the action handler
28 | METHOD createCustomer.
29 | CHECK keys IS NOT INITIAL.
30 |
31 | MODIFY ENTITIES OF ZR_Root IN LOCAL MODE
32 | ENTITY Root
33 | CREATE FIELDS ( id Fname Lname Age )
34 | WITH VALUE #(
35 | FOR key IN keys (
36 | %cid = key-%cid
37 | %is_draft = key-%param-%is_draft
38 | Id = key-%param-CustomerId
39 | Fname = key-%param-FirstName
40 | Lname = key-%param-LastName
41 | Age = 25
42 | )
43 | )
44 | MAPPED mapped
45 | FAILED failed
46 | REPORTED reported.
47 | ENDMETHOD.
48 | "Here, the incoming parameters are mapped to the entity fields before creation.
49 |
50 | "Step 4 – Expose the action in ZC_* (projection) BDEF
51 | define behavior for ZC_Root alias Root
52 | {
53 | use create;
54 | use update;
55 | use delete;
56 |
57 | use action createCustomer;
58 | }
59 | "This makes the action available in the projection layer.
60 |
61 | "Result
62 | "When the Create button is clicked in the SAP Fiori Elements UI:
63 | "The createCustomer static default factory action is triggered automatically.
64 | "Custom parameter handling and default value logic are executed before entity creation.
65 | "The standard create operation is bypassed (even if enabled).
66 |
--------------------------------------------------------------------------------
/CDS/Grouping_Actions_as_Menu_Button_using_Annotations.md:
--------------------------------------------------------------------------------
1 | # Grouping Actions as Menu Button using Annotations
2 |
3 | While exploring, one annotation caught my eye: `#𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡_𝗚𝗥𝗢𝗨𝗣`. I looked into it further and found that it allows you to group multiple actions under a single menu! This is particularly helpful when you want to group actions either on the List Report or the Object Page.
4 |
5 | For example, here I’ve grouped two actions (acceptTravel and rejectTravel) under a single menu labeled "Change Status":\
6 |
7 | `@𝗨𝗜: {`\
8 | `𝗹𝗶𝗻𝗲𝗜𝘁𝗲𝗺: [`\
9 | `{ 𝗽𝗼𝘀𝗶𝘁𝗶𝗼𝗻: 𝟭𝟬, 𝗶𝗺𝗽𝗼𝗿𝘁𝗮𝗻𝗰𝗲: #𝗛𝗜𝗚𝗛 },`\
10 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡_𝗚𝗥𝗢𝗨𝗣, 𝗹𝗮𝗯𝗲𝗹: '𝗖𝗵𝗮𝗻𝗴𝗲 𝗦𝘁𝗮𝘁𝘂𝘀', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: ``'𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' },`\
11 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡, 𝗱𝗮𝘁𝗮𝗔𝗰𝘁𝗶𝗼𝗻: '𝗮𝗰𝗰𝗲𝗽𝘁𝗧𝗿𝗮𝘃𝗲𝗹', 𝗹𝗮𝗯𝗲𝗹: '𝗔𝗰𝗰𝗲𝗽𝘁 ``𝗧𝗿𝗮𝘃𝗲𝗹', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: '𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' },`\
12 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡, 𝗱𝗮𝘁𝗮𝗔𝗰𝘁𝗶𝗼𝗻: '𝗿𝗲𝗷𝗲𝗰𝘁𝗧𝗿𝗮𝘃𝗲𝗹', 𝗹𝗮𝗯𝗲𝗹: '𝗥𝗲𝗷𝗲𝗰𝘁 ``𝗧𝗿𝗮𝘃𝗲𝗹', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: '𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' }`\
13 | `],`\
14 | `𝗶𝗱𝗲𝗻𝘁𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻: [`\
15 | `{ 𝗽𝗼𝘀𝗶𝘁𝗶𝗼𝗻: 𝟭𝟬, 𝗹𝗮𝗯𝗲𝗹: '𝗧𝗿𝗮𝘃𝗲𝗹 𝗜𝗗' },`\
16 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡_𝗚𝗥𝗢𝗨𝗣, 𝗹𝗮𝗯𝗲𝗹: '𝗖𝗵𝗮𝗻𝗴𝗲 𝗦𝘁𝗮𝘁𝘂𝘀', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: ``'𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' },`\
17 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡, 𝗱𝗮𝘁𝗮𝗔𝗰𝘁𝗶𝗼𝗻: '𝗮𝗰𝗰𝗲𝗽𝘁𝗧𝗿𝗮𝘃𝗲𝗹', 𝗹𝗮𝗯𝗲𝗹: '𝗔𝗰𝗰𝗲𝗽𝘁 ``𝗧𝗿𝗮𝘃𝗲𝗹', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: '𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' },`\
18 | `{ 𝘁𝘆𝗽𝗲: #𝗙𝗢𝗥_𝗔𝗖𝗧𝗜𝗢𝗡, 𝗱𝗮𝘁𝗮𝗔𝗰𝘁𝗶𝗼𝗻: '𝗿𝗲𝗷𝗲𝗰𝘁𝗧𝗿𝗮𝘃𝗲𝗹', 𝗹𝗮𝗯𝗲𝗹: '𝗥𝗲𝗷𝗲𝗰𝘁 ``𝗧𝗿𝗮𝘃𝗲𝗹', 𝗮𝗰𝘁𝗶𝗼𝗻𝗚𝗿𝗼𝘂𝗽𝗜𝗱: '𝗺𝗲𝗻𝘂-𝗖𝗵𝗮𝗻𝗴𝗲𝗦𝘁𝗮𝘁𝘂𝘀' }`\
19 | `]`\
20 | `}`
21 |
22 | Note: I tried this in SAP BTP, ABAP Environment, and it works great! I believe this should also be available in SAP S/4HANA Public Cloud Latest version. For Private Cloud availability, I’ll check and share more once I have the details.
23 |
24 | 
--------------------------------------------------------------------------------
/ABAP RAP/Show Fields in the Create Popup as Optional in RAP.abap:
--------------------------------------------------------------------------------
1 | "Show Fields in the Create Popup as Optional in RAP
2 | "Step 1 : Add temporary fields to show in the create popup. These will later be copied to the actual fields.
3 | define root view entity ZR_ROOT_ENTITY as select from zcustomer {
4 | key id as Id,
5 | fname as Fname,
6 | lname as Lname,
7 |
8 | @EndUserText.label: 'First Name'
9 | $projection.Fname as Fname_D,
10 |
11 | @EndUserText.label: 'Last Name'
12 | $projection.Lname as Lname_D
13 | }
14 |
15 | "Step 2: If you have a projection (C_ view), include the temporary fields but hide them from filters and line items.
16 | define root view entity ZC_ROOT_ENTITY
17 | provider contract transactional_query
18 | as projection on ZR_ROOT_ENTITY {
19 | key Id,
20 | Fname,
21 | Lname,
22 |
23 | @Consumption.filter.hidden: true
24 | @UI.lineItem: [{ hidden: true }]
25 | Fname_D,
26 |
27 | @Consumption.filter.hidden: true
28 | @UI.lineItem: [{ hidden: true }]
29 | Lname_D
30 | }
31 |
32 | "Step 3: Mark the temporary fields as read-only on update. Use a determination to copy their values to the actual fields on create.
33 | define behavior for ZR_ROOT_ENTITY
34 | ...
35 | {
36 | field ( mandatory : create ) Id;
37 |
38 | field ( readonly : update ) Fname_D, Lname_D;
39 |
40 | determination setNames on modify { create; }
41 | }
42 |
43 | "Step 4: Copy temporary field values (Fname_D, Lname_D) to actual fields (Fname, Lname) during creation.
44 | METHOD setNames.
45 | READ ENTITIES OF ZR_ROOT_ENTITY IN LOCAL MODE
46 | ENTITY ZR_ROOT_ENTITY
47 | FIELDS ( Fname_D Lname_D )
48 | WITH CORRESPONDING #( keys )
49 | RESULT DATA(lt_result).
50 |
51 | lt_update = VALUE #( FOR lw IN lt_result (
52 | %tky = lw-%tky
53 | Fname = lw-Fname_D
54 | Lname = lw-Lname_D
55 | %control = VALUE #( Fname = if_abap_behv=>mk-on
56 | Lname = if_abap_behv=>mk-on )
57 | )).
58 |
59 | MODIFY ENTITIES OF ZR_ROOT_ENTITY IN LOCAL MODE
60 | ENTITY ZR_ROOT_ENTITY
61 | UPDATE FROM lt_update
62 | REPORTED DATA(ls_reported)
63 | FAILED DATA(ls_failed).
64 | ENDMETHOD.
65 |
66 | "Step 5: Result On create, popup shows 3 fields: Id (required), Fname_D, and Lname_D (optional).
67 | "After creation, actual fields Fname and Lname are filled and can be edited on the object page.
68 |
--------------------------------------------------------------------------------
/ABAP New Syntax/Group_Internal_Table_Data.abap:
--------------------------------------------------------------------------------
1 | *To group internal table data and process it based on specific fields, older statements like AT NEW and AT END OF within loops were commonly used.
2 | *However, these statements are now obsolete.
3 | *But now, the new ABAP Syntax 𝗟𝗢𝗢𝗣 𝗔𝗧 𝗚𝗥𝗢𝗨𝗣 or 𝗙𝗢𝗥 𝗚𝗥𝗢𝗨𝗣𝗦 𝗢𝗙 used to achieve the same functionality.
4 |
5 | DATA(lt_courses) = VALUE tt_course (
6 | ( employee_id = '1' course_id = '1' course_name = 'ABAP' amount = '1000' )
7 | ( employee_id = '1' course_id = '2' course_name = 'UI5' amount = '2000' )
8 | ( employee_id = '1' course_id = '3' course_name = 'Fiori' amount = '3000' )
9 | ( employee_id = '2' course_id = '1' course_name = 'ABAP' amount = '1000' )
10 | ( employee_id = '2' course_id = '2' course_name = 'UI5' amount = '2000' )
11 | ( employee_id = '2' course_id = '3' course_name = 'Fiori' amount = '3000' )
12 | ( employee_id = '3' course_id = '1' course_name = 'ABAP' amount = '1000' )
13 | ).
14 |
15 | "Loop At Group and For in Group
16 | DATA(lt_employee_w_loop) = VALUE tt_employee( ).
17 |
18 | LOOP AT lt_courses INTO DATA(wa)
19 | GROUP BY ( employee_id = wa-employee_id
20 | size = GROUP SIZE
21 | index = GROUP INDEX )
22 | ASSIGNING FIELD-SYMBOL().
23 |
24 | DATA(ls_employee) = VALUE ty_employee(
25 | employee_id = -employee_id
26 | no_of_courses = -size
27 | total_amount = 0 ).
28 |
29 | "Option 1
30 | LOOP AT GROUP ASSIGNING FIELD-SYMBOL().
31 | ls_employee-total_amount += -amount.
32 | ENDLOOP.
33 |
34 | "Option 2
35 | ls_employee-total_amount = REDUCE #(
36 | INIT amount = 0
37 | FOR IN GROUP
38 | NEXT amount = amount + -amount
39 | ).
40 |
41 | APPEND ls_employee TO lt_employee_w_loop.
42 | ENDLOOP.
43 |
44 | "For in Group
45 | DATA(lt_employee_w_for) = VALUE tt_employee(
46 | FOR GROUPS course OF wa IN lt_courses
47 | GROUP BY ( employee_id = wa-employee_id
48 | size = GROUP SIZE
49 | index = GROUP INDEX )
50 | ( employee_id = course-employee_id
51 | no_of_courses = course-size
52 | total_amount = REDUCE #(
53 | INIT amount = 0
54 | FOR member IN GROUP course
55 | NEXT amount = amount + member-amount
56 | )
57 | )
58 | ).
59 |
60 | "Output
61 | "EMPLOYEE_ID NO_OF_COURSES TOTAL_AMOUNT
62 | "00000001 3 6000
63 | "00000002 3 6000
64 | "00000003 1 1000
--------------------------------------------------------------------------------
/ABAP RAP/Hide_Fields_Based_on_Other_Field_Value_Immediately.abap:
--------------------------------------------------------------------------------
1 | *Use Case: Dynamically Hide Fields Based on EmployeeType Immediately Upon Change*
2 |
3 | "Step 1: Add a Derived Field in the Root Entity ZR_SB_EMP_DATA
4 |
5 | define root view entity ZR_SB_EMP_DATA
6 | as select from zsb_emp_data as EmployeeData
7 | {
8 | ...,
9 | EmployeeType,
10 | case EmployeeType
11 | when 'FT' then cast( 'X' as abap_boolean preserving type )
12 | else cast( '' as abap_boolean preserving type )
13 | end as IsFullTimeEmployee
14 | }
15 |
16 | "This derived field IsFullTimeEmployee is used to control visibility logic based on EmployeeType.
17 |
18 | "Step 2: Expose the Field in Your Projection View
19 |
20 | define root view entity ZC_SB_EMP_DATA
21 | provider contract transactional_query
22 | as projection on ZR_SB_EMP_DATA
23 | {
24 | ...,
25 | EmployeeType,
26 | IsFullTimeEmployee
27 | }
28 |
29 | "Step 3: Apply the Visibility Annotation to Your Target Field. Use the @UI.hidden annotation to conditionally hide the field (e.g., MobileNumber) based on IsFullTimeEmployee.
30 |
31 | annotate view ZC_SB_EMP_DATA with
32 | {
33 | ...,
34 | @UI.hidden: #( IsFullTimeEmployee )
35 | MobileNumber;
36 | }
37 |
38 | "Step 4: Add a Determination in the Root BDEF to Recalculate the Boolean Field on Change, Also declare a side effect to notify the UI of the dependent field update.
39 |
40 | define behavior for ZR_SB_EMP_DATA alias EmployeeData
41 | ...
42 | {
43 | ...
44 | determination setVisibility on modify { field EmployeeType; }
45 | side effects { field EmployeeType affects field IsFullTimeEmployee; }
46 | }
47 |
48 | "Step 5: Implement the Determination Logic to Update IsFullTimeEmployee immediately when EmployeeType changes.
49 |
50 | METHOD setVisibility.
51 | DATA: lt_update TYPE TABLE FOR UPDATE zr_sb_emp_data.
52 |
53 | READ ENTITIES OF zr_sb_emp_data IN LOCAL MODE
54 | ENTITY EmployeeData
55 | FIELDS ( EmployeeType )
56 | WITH CORRESPONDING #( keys )
57 | RESULT DATA(lt_employee_data).
58 |
59 | lt_update = VALUE #( FOR ls_employee IN lt_employee_data (
60 | %tky = ls_employee-%tky
61 | IsFullTimeEmployee = xsdbool( ls_employee-EmployeeType = 'FT' )
62 | %control = VALUE #( IsFullTimeEmployee = if_abap_behv=>mk-on ) ) ).
63 |
64 | MODIFY ENTITIES OF zr_sb_emp_data IN LOCAL MODE
65 | ENTITY EmployeeData
66 | UPDATE FROM lt_update
67 | REPORTED DATA(lt_reported).
68 |
69 | reported = CORRESPONDING #( DEEP lt_reported ).
70 | ENDMETHOD.
71 |
72 | "Step 6: Enable Side Effects in the Projection BDEF
73 |
74 | use side effects;
75 | define behavior for ZC_SB_EMP_DATA alias EmployeeData
76 | {
77 | ...
78 | }
79 |
80 | "Step 7: That’s it! Now, the field (e.g., MobileNumber) will be shown or hidden immediately based on the selected EmployeeType value without requiring a page reload.
81 | "PT - Part Time Employee
82 | "FT - Full Time Employee
83 |
--------------------------------------------------------------------------------
/JSON/JSON_Conversion_in_ABAP.abap:
--------------------------------------------------------------------------------
1 | TYPES: BEGIN OF ty_emp_type,
2 | employeeid TYPE c LENGTH 3,
3 | employeename TYPE c LENGTH 20,
4 | employeeage TYPE c LENGTH 3,
5 | employeemobilenumber TYPE c LENGTH 10,
6 | END OF ty_emp_type,
7 | tt_emp_tab_type TYPE TABLE OF ty_emp_type WITH EMPTY KEY.
8 |
9 | DATA(emp_tab) = VALUE #(
10 | ( employeeid = '1' employeename = 'Bharathi S' employeeage = '24' employeemobilenumber = '1234567890' )
11 | ( employeeid = '2' employeename = 'Siva S' employeeage = '24' employeemobilenumber = '1234567890' )
12 | ( employeeid = '3' employeename = 'Sasi S' employeeage = '24' employeemobilenumber = '1234567890' ) ).
13 |
14 | * Table to JSON
15 | DATA(lv_emp_table_to_json) = /ui2/cl_json=>serialize(
16 | data = emp_tab
17 | format_output = abap_true
18 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case ). "none,low_case,camel_case,extended, user, user_low_case
19 |
20 | * JSON to table (with different column names)
21 | TYPES: BEGIN OF ty_emp_type_map,
22 | empid TYPE c LENGTH 3,
23 | empname TYPE c LENGTH 20,
24 | empage TYPE c LENGTH 3,
25 | empmobnumber TYPE c LENGTH 10,
26 | END OF ty_emp_type_map,
27 | tt_emp_tab_type_map TYPE TABLE OF ty_emp_type_map WITH EMPTY KEY.
28 |
29 | DATA(lt_emp_data_from_json_map) = VALUE tt_emp_tab_type_map( ).
30 | /ui2/cl_json=>deserialize(
31 | EXPORTING
32 | json = lv_emp_table_to_json
33 | name_mappings = VALUE #( ( abap = 'EMPID' json = 'EMPLOYEEID' )
34 | ( abap = 'EMPNAME' json = 'EMPLOYEENAME' )
35 | ( abap = 'EMPAGE' json = 'EMPLOYEEAGE' )
36 | ( abap = 'EMPMOBNUMBER' json = 'EMPLOYEEMOBILENUMBER' ) )
37 | CHANGING
38 | data = lt_emp_data_from_json_map ).
39 |
40 | * JSON to table
41 | DATA(lt_emp_data_from_json) = VALUE tt_emp_tab_type( ).
42 | /ui2/cl_json=>deserialize(
43 | EXPORTING
44 | json = lv_emp_table_to_json
45 | CHANGING
46 | data = lt_emp_data_from_json
47 | ).
48 |
49 | * Conversion Exists
50 | TYPES: BEGIN OF ty_customer_data,
51 | customerId TYPE kunnr,
52 | language TYPE spras,
53 | END OF ty_customer_data.
54 | DATA(ls_sales_data) = VALUE ty_customer_data( language = 'E' customerid = '1' ).
55 | DATA(lv_json_Sales_data) = /ui2/cl_json=>serialize(
56 | data = ls_sales_data
57 | conversion_exits = abap_true ).
58 | "E -> Will be changed into EN
59 |
60 | * Unknown type
61 | DATA(lv_unknown_json) = `[ { "EmployeeId":"1", "EmployeeName":"Saranya S" },` &&
62 | `{ "EmployeeId":"2", "EmployeeName":"Saran S" }]`.
63 | DATA(lr_emp_data) = /ui2/cl_json=>generate( json = lv_unknown_json ).
64 | " This can be accessed by lr_emp_data->*
65 |
--------------------------------------------------------------------------------
/File Handling/Read_Excel_data_using_XCO_Libaray.abap:
--------------------------------------------------------------------------------
1 | DATA: lv_rc TYPE i.
2 | DATA: lt_files TYPE filetable.
3 | DATA: lv_action TYPE i.
4 | DATA: lt_bin_data TYPE w3mimetabtype.
5 |
6 | PARAMETERS: p_file TYPE ibipparms-path OBLIGATORY.
7 |
8 | AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
9 | cl_gui_frontend_services=>file_open_dialog( EXPORTING file_filter = |xlsx (*.xlsx)\|*.xlsx\|{ cl_gui_frontend_services=>filetype_all }|
10 | CHANGING file_table = lt_files
11 | rc = lv_rc
12 | user_action = lv_action ).
13 |
14 | p_file = |{ lt_files[ 1 ]-filename }|.
15 | START-OF-SELECTION.
16 | * Excel upload
17 | cl_gui_frontend_services=>gui_upload( EXPORTING filename = CONV #( p_file )
18 | filetype = 'BIN'
19 | IMPORTING filelength = DATA(lv_filesize)
20 | CHANGING data_tab = lt_bin_data ).
21 |
22 | * Convert Binary Data to XSTRING - We can use CL_BCS_CONVERT to convert the binary data to XSTRING
23 | DATA(lv_excel_data) = cl_bcs_convert=>solix_to_xstring( it_solix = lt_bin_data ).
24 |
25 | * Get the read access to the Excel file using XCO Library
26 | DATA(lo_xl) = xco_cp_xlsx=>document->for_file_content( lv_excel_data )->read_access( ).
27 |
28 | * Read the Excel file
29 | *-> Reading the first sheet
30 | DATA(lo_sheet_by_position) = lo_xl->get_workbook( )->worksheet->at_position( 1 ).
31 | *-> Reading using Sheet name
32 | DATA(lo_sheet_by_name) = lo_xl->get_workbook( )->worksheet->for_name( 'Employees' ).
33 |
34 | IF NOT lo_sheet_by_position->exists( ).
35 | RETURN. "Sheet does not exist
36 | ENDIF.
37 |
38 | * Read all data from the sheet
39 | DATA(lo_sel_pattern_all) = xco_cp_xlsx_selection=>pattern_builder->simple_from_to( )->get_pattern( ).
40 |
41 | * Read data from specific rows and columns
42 | *-> From column(A) to column(C)
43 | DATA(lo_sel_pattern_col) = xco_cp_xlsx_selection=>pattern_builder->simple_from_to(
44 | )->from_column( xco_cp_xlsx=>coordinate->for_alphabetic_value( 'A' )
45 | )->to_column( xco_cp_xlsx=>coordinate->for_alphabetic_value( 'C' )
46 | )->get_pattern( ).
47 | *-> From row(2) to row(5)
48 | DATA(lo_sel_pattern_row) = xco_cp_xlsx_selection=>pattern_builder->simple_from_to(
49 | )->from_row( xco_cp_xlsx=>coordinate->for_numeric_value( 2 )
50 | )->to_row( xco_cp_xlsx=>coordinate->for_numeric_value( 5 )
51 | )->get_pattern( ).
52 | *-> Both Row and Column
53 | DATA(lo_sel_pattern_both) = xco_cp_xlsx_selection=>pattern_builder->simple_from_to(
54 | )->from_row( xco_cp_xlsx=>coordinate->for_numeric_value( 2 )
55 | )->to_row( xco_cp_xlsx=>coordinate->for_numeric_value( 5 )
56 | )->from_column( xco_cp_xlsx=>coordinate->for_alphabetic_value( 'A' )
57 | )->to_column( xco_cp_xlsx=>coordinate->for_alphabetic_value( 'C' )
58 | )->get_pattern( ).
59 |
60 | TYPES: BEGIN OF ty_employee,
61 | employee_id TYPE string,
62 | employee_name TYPE string,
63 | mobile_number TYPE string,
64 | date_of_birth TYPE string,
65 | END OF ty_employee.
66 | DATA: lt_employees TYPE TABLE OF ty_employee WITH EMPTY KEY.
67 |
68 | * Fill the internal table by using the selection patterns
69 | DATA(o_result) = lo_sheet_by_position->select( lo_sel_pattern_all " lo_sel_pattern_col, lo_sel_pattern_row, (lo_sel_pattern_both
70 | )->row_stream(
71 | )->operation->write_to( REF #( lt_employees )
72 | )->set_value_transformation( xco_cp_xlsx_read_access=>value_transformation->string_value
73 | )->execute( ).
74 |
--------------------------------------------------------------------------------
/ABAP RAP/Display Message Strip by Default in Object Page.abap:
--------------------------------------------------------------------------------
1 | "Display Message Strip by Default in Object Page using Instance Features
2 | "Step 1 – Add actions in Metadata Extensions
3 | annotate view YR_TRAVELTP with
4 | {
5 | @UI.identification: [
6 | { type: #FOR_ACTION, label: 'Accept', dataAction: 'AcceptTravel', position: 10 },
7 | { type: #FOR_ACTION, label: 'Reject', dataAction: 'RejectTravel', position: 20 }
8 | ]
9 | ....
10 | }
11 |
12 |
13 | "Step 2 – Update the Behavior Definition (BDEF)
14 | define behavior for YR_TRAVELTP alias Travel
15 | .....
16 | {
17 | .....
18 | update ( features : instance );
19 | field ( features : instance ) OverallStatus;
20 | draft action ( features : instance ) Edit;
21 |
22 | action ( features : instance ) AcceptTravel result [1] $self;
23 | action ( features : instance ) RejectTravel result [1] $self;
24 | ....
25 | }
26 |
27 |
28 | "Step 3 – Implement Logic in the Behavior Implementation (BIL)
29 | METHOD AcceptTravel.
30 | MODIFY ENTITIES OF YR_TRAVELTP IN LOCAL MODE
31 | ENTITY Travel
32 | UPDATE FIELDS ( OverallStatus )
33 | WITH VALUE #( FOR key IN keys ( %tky = key-%tky OverallStatus = 'A' ) ).
34 |
35 | READ ENTITIES OF YR_TRAVELTP IN LOCAL MODE
36 | ENTITY Travel
37 | ALL FIELDS
38 | WITH CORRESPONDING #( keys )
39 | RESULT DATA(travels).
40 |
41 | result = VALUE #( FOR travel IN travels ( %tky = travel-%tky %param = travel ) ).
42 | ENDMETHOD.
43 |
44 | METHOD RejectTravel.
45 | MODIFY ENTITIES OF YR_TRAVELTP IN LOCAL MODE
46 | ENTITY Travel
47 | UPDATE FIELDS ( OverallStatus )
48 | WITH VALUE #( FOR key IN keys ( %tky = key-%tky OverallStatus = 'X' ) ).
49 |
50 | READ ENTITIES OF YR_TRAVELTP IN LOCAL MODE
51 | ENTITY Travel
52 | ALL FIELDS
53 | WITH CORRESPONDING #( keys )
54 | RESULT DATA(travels).
55 |
56 | result = VALUE #( FOR travel IN travels ( %tky = travel-%tky %param = travel ) ).
57 | ENDMETHOD.
58 |
59 | METHOD get_instance_features.
60 | READ ENTITIES OF YR_TRAVELTP IN LOCAL MODE
61 | ENTITY Travel
62 | ALL FIELDS
63 | WITH CORRESPONDING #( keys )
64 | RESULT DATA(travels).
65 |
66 | LOOP AT travels ASSIGNING FIELD-SYMBOL().
67 | reported-travel = VALUE #( BASE reported-travel ( %tky = -%tky %state_area = 'DEFAULT_MESSAGE' ) ).
68 |
69 | IF -EndDate < cl_abap_context_info=>get_system_date( ) AND -EndDate IS NOT INITIAL.
70 | DATA(is_travel_completed) = abap_true.
71 | reported-travel = VALUE #( BASE reported-travel (
72 | %tky = -%tky
73 | %state_area = 'DEFAULT_MESSAGE'
74 | %msg = new_message_with_text(
75 | severity = if_abap_behv_message=>severity-information
76 | text = 'Travel completed' ) ) ).
77 |
78 | ELSEIF -OverallStatus = 'A'.
79 | reported-travel = VALUE #( BASE reported-travel (
80 | %tky = -%tky
81 | %state_area = 'DEFAULT_MESSAGE'
82 | %msg = new_message_with_text(
83 | severity = if_abap_behv_message=>severity-success
84 | text = 'Travel Accepted' ) ) ).
85 |
86 | ELSEIF -OverallStatus = 'X'.
87 | reported-travel = VALUE #( BASE reported-travel (
88 | %tky = -%tky
89 | %state_area = 'DEFAULT_MESSAGE'
90 | %msg = new_message_with_text(
91 | severity = if_abap_behv_message=>severity-error
92 | text = 'Travel Rejected' ) ) ).
93 | ENDIF.
94 |
95 | result = VALUE #( BASE result
96 | ( %tky = -%tky
97 | %update = COND #( WHEN is_travel_completed = abap_true
98 | THEN if_abap_behv=>fc-o-disabled
99 | ELSE if_abap_behv=>fc-o-enabled )
100 | %action = VALUE #(
101 | Edit = COND #( WHEN is_travel_completed = abap_true
102 | THEN if_abap_behv=>fc-o-disabled
103 | ELSE if_abap_behv=>fc-o-enabled )
104 | AcceptTravel = COND #( WHEN is_travel_completed = abap_true OR -OverallStatus = 'A'
105 | THEN if_abap_behv=>fc-o-disabled
106 | ELSE if_abap_behv=>fc-o-enabled )
107 | RejectTravel = COND #( WHEN is_travel_completed = abap_true OR -OverallStatus = 'X'
108 | THEN if_abap_behv=>fc-o-disabled
109 | ELSE if_abap_behv=>fc-o-enabled ) ) ) ).
110 | ENDLOOP.
111 | ENDMETHOD.
112 |
113 | "Step 4 – Expose the actions in the projection BDEF YC_TRAVELTP (if not already exposed)
114 | "Step 5 – Test and See the Result
115 | "When you open the Object Page, the relevant message strip will appear automatically based on the travel status — Completed, Accepted, or Rejected.
116 |
--------------------------------------------------------------------------------
/Email/Send_Internal_Table_as_Excel_Attachment.abap:
--------------------------------------------------------------------------------
1 | CLASS lcl_email_with_excel DEFINITION.
2 | PUBLIC SECTION.
3 | METHODS send_email.
4 |
5 | PRIVATE SECTION.
6 | TYPES: BEGIN OF ty_employee,
7 | emp_id TYPE pernr_d,
8 | emp_name TYPE text100,
9 | manager_id TYPE pernr_d,
10 | manager_name TYPE text100,
11 | emp_position TYPE text100,
12 | END OF ty_employee,
13 | tt_employee TYPE TABLE OF ty_employee WITH EMPTY KEY.
14 |
15 | TYPES: BEGIN OF ty_column,
16 | column_name TYPE text30,
17 | column_text TYPE text40,
18 | END OF ty_column,
19 | tt_columns TYPE TABLE OF ty_column WITH EMPTY KEY.
20 | CLASS-DATA mt_emloyees TYPE tt_employee.
21 | CLASS-DATA mt_columns TYPE tt_columns.
22 |
23 | METHODS load_data.
24 | METHODS convert_itab_to_xls_xstring RETURNING VALUE(rv_xstring) TYPE xstring.
25 | ENDCLASS.
26 |
27 | CLASS lcl_email_with_excel IMPLEMENTATION.
28 | METHOD load_data.
29 | mt_emloyees = VALUE #( ( emp_id = '1' emp_name = 'Name 1' emp_position = 'DEV_1' manager_id = '1' manager_name = 'Manager 1' )
30 | ( emp_id = '2' emp_name = 'Name 2' emp_position = 'DEV_2' manager_id = '2' manager_name = 'Manager 2' ) ).
31 |
32 | mt_columns = VALUE #( ( column_name = 'EMP_ID' column_text = 'Employee ID' )
33 | ( column_name = 'EMP_NAME' column_text = 'Employee Name' )
34 | ( column_name = 'EMP_POSITION' column_text = 'Employee Position' )
35 | ( column_name = 'MANAGER_ID' column_text = 'Manager ID' )
36 | ( column_name = 'MANAGER_NAME' column_text = 'Manager Name' ) ).
37 | ENDMETHOD.
38 |
39 | METHOD convert_itab_to_xls_xstring.
40 | TRY.
41 | cl_salv_table=>factory(
42 | EXPORTING
43 | list_display = abap_false
44 | IMPORTING
45 | r_salv_table = DATA(lo_salv_table)
46 | CHANGING
47 | t_table = mt_emloyees ).
48 |
49 | LOOP AT mt_columns ASSIGNING FIELD-SYMBOL().
50 | DATA(lo_column) = lo_salv_table->get_columns( )->get_column( -column_name ).
51 | lo_column->set_long_text( -column_text ).
52 | lo_column->set_medium_text( CONV #( -column_text ) ).
53 | lo_column->set_short_text( CONV #( -column_text ) ).
54 | ENDLOOP.
55 |
56 | DATA(lt_fcat) = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
57 | r_columns = lo_salv_table->get_columns( )
58 | r_aggregations = lo_salv_table->get_aggregations( ) ).
59 | CATCH cx_salv_msg INTO DATA(lx_mail).
60 | MESSAGE lx_mail TYPE 'E'.
61 | ENDTRY.
62 |
63 | "Option - 1
64 | "rv_xstring = lo_salv_table->to_xml( xml_type = if_salv_bs_xml=>c_type_xlsx ).
65 | "RETURN.
66 |
67 | "Option - 2
68 | cl_salv_bs_lex=>export_from_result_data_table(
69 | EXPORTING
70 | is_format = if_salv_bs_lex_format=>mc_format_xlsx
71 | ir_result_data_table = cl_salv_ex_util=>factory_result_data_table(
72 | r_data = REF #( mt_emloyees )
73 | t_fieldcatalog = lt_fcat )
74 | IMPORTING
75 | er_result_file = rv_xstring ).
76 | ENDMETHOD.
77 |
78 | METHOD send_email.
79 |
80 | TRY.
81 | load_data( ).
82 |
83 | DATA(lo_mail) = cl_bcs=>create_persistent( ).
84 | DATA(lo_sender_address) = cl_cam_address_bcs=>create_internet_address(
85 | i_address_string = CONV #( 'sender@gmail.com' ) ).
86 | lo_mail->set_sender( lo_sender_address ).
87 |
88 | DATA(recipient_address) = cl_cam_address_bcs=>create_internet_address(
89 | i_address_string = CONV #( 'receiver@gmail.com' ) ).
90 | lo_mail->add_recipient( i_recipient = recipient_address ).
91 |
92 | DATA(lo_document) = cl_document_bcs=>create_document(
93 | i_type = 'htm'
94 | i_subject = `Excel Attachment`
95 | i_text = VALUE #( ( CONV #( 'Excel Attachment' ) ) )
96 | i_sender = lo_sender_address ).
97 |
98 | DATA(lv_excel_data) = convert_itab_to_xls_xstring( ).
99 | lo_document->add_attachment(
100 | i_attachment_type = 'XLS'
101 | i_attachment_subject = 'Employee Table'
102 | i_attachment_size = CONV #( xstrlen( lv_excel_data ) )
103 | i_att_content_hex = cl_bcs_convert=>xstring_to_solix( lv_excel_data ) ).
104 |
105 | lo_mail->set_document( lo_document ).
106 |
107 | lo_mail->set_send_immediately( abap_true ).
108 |
109 | DATA(lv_send_success) = lo_mail->send( ).
110 |
111 | COMMIT WORK.
112 |
113 | CATCH cx_send_req_bcs cx_address_bcs cx_document_bcs INTO DATA(lx_mail).
114 | MESSAGE lx_mail TYPE 'E'.
115 | ENDTRY.
116 | ENDMETHOD.
117 | ENDCLASS.
118 |
119 | START-OF-SELECTION.
120 | DATA(lo_mail) = NEW lcl_email_with_excel( ).
121 | lo_mail->send_email( ).
--------------------------------------------------------------------------------
/ZIP/Download_Multiple_Adobe_Form_as_ZIP_file.abap:
--------------------------------------------------------------------------------
1 | CLASS lcl_sb_zip DEFINITION
2 | CREATE PUBLIC .
3 | PUBLIC SECTION.
4 | TYPES:
5 | tt_customerid TYPE TABLE OF s_customer WITH EMPTY KEY .
6 | METHODS get_form
7 | IMPORTING
8 | !iv_customer_id TYPE s_customer
9 | RETURNING
10 | VALUE(rv_pdf) TYPE fpcontent .
11 | METHODS build_zip
12 | IMPORTING VALUE(it_customers_id) TYPE tt_customerid
13 | RETURNING VALUE(rv_zip_file) TYPE xstring.
14 | METHODS download_zip IMPORTING VALUE(iv_zip_file) TYPE xstring.
15 | METHODS send_email IMPORTING VALUE(iv_zip_file) TYPE xstring.
16 | PROTECTED SECTION.
17 | PRIVATE SECTION.
18 | METHODS get_customer_data
19 | IMPORTING
20 | !iv_customer_id TYPE s_customer
21 | EXPORTING
22 | !customer_detail TYPE scustom
23 | !bookings TYPE ty_bookings
24 | !connections TYPE ty_connections .
25 | ENDCLASS.
26 |
27 | CLASS lcl_sb_zip IMPLEMENTATION.
28 | METHOD get_customer_data.
29 |
30 | SELECT SINGLE FROM scustom
31 | FIELDS *
32 | WHERE id = @iv_customer_id
33 | INTO @customer_detail.
34 | SELECT FROM bookings
35 | FIELDS *
36 | WHERE customid = @iv_customer_id
37 | INTO TABLE @bookings.
38 | IF lines( bookings ) > 0.
39 | SELECT * FROM spfli INTO TABLE @connections
40 | FOR ALL ENTRIES IN @bookings
41 | WHERE carrid = @bookings-carrid
42 | AND connid = @bookings-connid.
43 | ENDIF.
44 |
45 | ENDMETHOD.
46 |
47 | METHOD get_form.
48 |
49 | DATA(lv_form_name) = CONV tdsfname( 'FP_TEST_03' ).
50 | DATA(lv_form_fm_name) = VALUE rs38l_fnam( ).
51 | DATA(ls_docparams) = VALUE sfpdocparams( ).
52 | DATA(ls_outputparams) = VALUE sfpoutputparams( ).
53 | DATA(ls_formoutput) = VALUE fpformoutput( ).
54 | * Get data
55 | get_customer_data(
56 | EXPORTING
57 | iv_customer_id = iv_customer_id
58 | IMPORTING
59 | customer_detail = DATA(customer)
60 | bookings = DATA(bookings)
61 | connections = DATA(connections) ).
62 | * get name of the generated function module
63 | TRY.
64 | CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
65 | EXPORTING
66 | i_name = lv_form_name
67 | IMPORTING
68 | e_funcname = lv_form_fm_name.
69 | CATCH cx_fp_api INTO DATA(lx_fp_api).
70 | MESSAGE ID lx_fp_api->msgid TYPE lx_fp_api->msgty
71 | NUMBER lx_fp_api->msgno
72 | WITH lx_fp_api->msgv1 lx_fp_api->msgv2
73 | lx_fp_api->msgv3 lx_fp_api->msgv4.
74 | RETURN.
75 | ENDTRY.
76 | * Set output parameters and open spool job
77 | ls_outputparams-nodialog = 'X'. " no print preview
78 | ls_outputparams-getpdf = 'X'. " request PDF
79 | CALL FUNCTION 'FP_JOB_OPEN'
80 | CHANGING
81 | ie_outputparams = ls_outputparams
82 | EXCEPTIONS
83 | cancel = 1
84 | usage_error = 2
85 | system_error = 3
86 | internal_error = 4
87 | OTHERS = 5.
88 | IF sy-subrc <> 0.
89 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
90 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
91 | RETURN.
92 | ENDIF.
93 | * Now call the generated function module
94 | CALL FUNCTION lv_form_fm_name
95 | EXPORTING
96 | /1bcdwb/docparams = ls_docparams
97 | customer = customer
98 | bookings = bookings
99 | connections = connections
100 | IMPORTING
101 | /1bcdwb/formoutput = ls_formoutput
102 | EXCEPTIONS
103 | usage_error = 1
104 | system_error = 2
105 | internal_error = 3
106 | OTHERS = 4.
107 | IF sy-subrc <> 0.
108 | RETURN.
109 | ENDIF.
110 | * Close spool job
111 | CALL FUNCTION 'FP_JOB_CLOSE'
112 | EXCEPTIONS
113 | usage_error = 1
114 | system_error = 2
115 | internal_error = 3
116 | OTHERS = 4.
117 | IF sy-subrc <> 0.
118 | RETURN.
119 | ENDIF.
120 | rv_pdf = ls_formoutput-pdf.
121 | ENDMETHOD.
122 |
123 | METHOD build_zip.
124 | DATA(lo_zip) = NEW cl_abap_zip( ).
125 | LOOP AT it_customers_id ASSIGNING FIELD-SYMBOL().
126 | lo_zip->add( name = |{ }.pdf|
127 | content = get_form( ) ).
128 | ENDLOOP.
129 | rv_zip_file = lo_zip->save( ).
130 | ENDMETHOD.
131 |
132 | METHOD download_zip.
133 | DATA(lv_file_path) = VALUE string( ).
134 | DATA(lv_file_name) = VALUE string( ).
135 | DATA(lv_path) = VALUE string( ).
136 | DATA(lv_user_action) = VALUE i( ).
137 |
138 | cl_gui_frontend_services=>file_save_dialog(
139 | EXPORTING
140 | default_extension = 'zip'
141 | CHANGING
142 | fullpath = lv_file_path
143 | filename = lv_file_name
144 | path = lv_path
145 | user_action = lv_user_action
146 | EXCEPTIONS
147 | cntl_error = 1
148 | error_no_gui = 2
149 | not_supported_by_gui = 3
150 | invalid_default_file_name = 4
151 | OTHERS = 5 ).
152 |
153 | IF lv_user_action <> cl_gui_frontend_services=>action_ok.
154 | RETURN.
155 | ENDIF.
156 |
157 | DATA(lt_binary_tab) = VALUE solix_tab( ).
158 |
159 | lt_binary_tab = cl_bcs_convert=>xstring_to_solix( iv_zip_file ).
160 |
161 | CALL METHOD cl_gui_frontend_services=>gui_download
162 | EXPORTING
163 | filename = lv_file_path
164 | filetype = 'BIN'
165 | CHANGING
166 | data_tab = lt_binary_tab
167 | EXCEPTIONS
168 | file_write_error = 1
169 | no_batch = 2
170 | gui_refuse_filetransfer = 3
171 | invalid_type = 4
172 | no_authority = 5
173 | unknown_error = 6
174 | header_not_allowed = 7
175 | separator_not_allowed = 8
176 | filesize_not_allowed = 9
177 | header_too_long = 10
178 | dp_error_create = 11
179 | dp_error_send = 12
180 | dp_error_write = 13
181 | unknown_dp_error = 14
182 | access_denied = 15
183 | dp_out_of_memory = 16
184 | disk_full = 17
185 | dp_timeout = 18
186 | file_not_found = 19
187 | dataprovider_exception = 20
188 | control_flush_error = 21
189 | not_supported_by_gui = 22
190 | error_no_gui = 23
191 | OTHERS = 24.
192 | ENDMETHOD.
193 |
194 | METHOD send_email.
195 | TRY.
196 | DATA(lo_mail) = cl_bcs=>create_persistent( ).
197 | DATA(lo_sender_address) = cl_cam_address_bcs=>create_internet_address(
198 | i_address_string = CONV #( 'sender@gmail.com' ) ).
199 | lo_mail->set_sender( lo_sender_address ).
200 |
201 | DATA(recipient_address) = cl_cam_address_bcs=>create_internet_address(
202 | i_address_string = CONV #( 'receiver@gmail.com' ) ).
203 | lo_mail->add_recipient( i_recipient = recipient_address ).
204 |
205 | DATA(lo_document) = cl_document_bcs=>create_document(
206 | i_type = 'htm'
207 | i_subject = `ZIP File Attachment`
208 | i_text = VALUE #( ( CONV #( 'ZIP File Attachment' ) ) )
209 | i_sender = lo_sender_address ).
210 |
211 | lo_document->add_attachment( i_attachment_type = 'ZIP'
212 | i_attachment_subject = 'Zip_File'
213 | i_attachment_size = CONV #( xstrlen( iv_zip_file ) )
214 | i_att_content_hex = cl_bcs_convert=>xstring_to_solix( iv_zip_file ) ).
215 | lo_mail->set_document( lo_document ).
216 |
217 | lo_mail->set_send_immediately( abap_true ).
218 | DATA(lv_send_success) = lo_mail->send( ).
219 | COMMIT WORK.
220 | CATCH cx_send_req_bcs cx_address_bcs cx_document_bcs INTO DATA(lx_mail).
221 | MESSAGE lx_mail TYPE 'E'.
222 | ENDTRY.
223 | ENDMETHOD.
224 |
225 | ENDCLASS.
226 |
227 | START-OF-SELECTION.
228 | DATA(lo_zip) = NEW lcl_sb_zip( ).
229 | DATA(lv_zip_data) = lo_zip->build_zip( it_customers_id = VALUE #( ( CONV #( 00000001 ) )
230 | ( CONV #( 00000002 ) ) ) ).
231 | lo_zip->download_zip( lv_zip_data ).
232 | lo_zip->send_email( lv_zip_data ).
--------------------------------------------------------------------------------
/ABAP SQL/window_functions.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_sql_window_functions DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 | PUBLIC SECTION.
6 | INTERFACES if_oo_adt_classrun .
7 | TYPES: BEGIN OF ty_students,
8 | student_id TYPE int4,
9 | student_name TYPE c LENGTH 40,
10 | dep_name TYPE c LENGTH 40,
11 | score TYPE int4,
12 | END OF ty_students.
13 | DATA: lt_students TYPE TABLE OF ty_students WITH DEFAULT KEY.
14 | METHODS: constructor.
15 | PROTECTED SECTION.
16 | PRIVATE SECTION.
17 | ENDCLASS.
18 |
19 | CLASS zcl_sql_window_functions IMPLEMENTATION.
20 | METHOD constructor.
21 | lt_students = VALUE #( ( student_id = 1 student_name = 'Bharathi S' dep_name = 'IT' score = 90 )
22 | ( student_id = 2 student_name = 'Dhakshan' dep_name = 'CSE' score = 87 )
23 | ( student_id = 3 student_name = 'Shroy' dep_name = 'EEE' score = 95 )
24 | ( student_id = 4 student_name = 'Bhuvi' dep_name = 'EEE' score = 78 )
25 | ( student_id = 5 student_name = 'Thara' dep_name = 'IT' score = 85 )
26 | ( student_id = 6 student_name = 'Anish' dep_name = 'EEE' score = 95 )
27 | ( student_id = 7 student_name = 'Aravind' dep_name = 'MECH' score = 91 )
28 | ( student_id = 8 student_name = 'Mohan' dep_name = 'CSE' score = 82 )
29 | ( student_id = 9 student_name = 'Saurabh' dep_name = 'IT' score = 92 )
30 | ( student_id = 10 student_name = 'Rohan' dep_name = 'CSE' score = 65 )
31 | ( student_id = 11 student_name = 'Surya' dep_name = 'MECH' score = 72 )
32 | ( student_id = 12 student_name = 'Boopalan' dep_name = 'MECH' score = 67 )
33 | ( student_id = 13 student_name = 'Shasank' dep_name = 'CSE' score = 75 )
34 | ( student_id = 14 student_name = 'Kaviya' dep_name = 'EEE' score = 90 ) ).
35 | ENDMETHOD.
36 |
37 | METHOD if_oo_adt_classrun~main.
38 | SELECT FROM @lt_students AS lt_students
39 | FIELDS student_id,
40 | student_name,
41 | dep_name,
42 | score,
43 |
44 | " note: If partition by is not mentioned whole data will be considered as a single result set
45 | SUM( score ) OVER( ) AS total_score,
46 | MAX( score ) OVER( ) AS maximum_score,
47 | MIN( score ) OVER( ) AS mininum_score,
48 | CAST( AVG( score ) OVER( ) AS INT4 ) AS average_score,
49 |
50 | SUM( score ) OVER( PARTITION BY dep_name ORDER BY dep_name ASCENDING ) AS dep_total_score,
51 | MIN( score ) OVER( PARTITION BY dep_name ORDER BY dep_name ASCENDING ) AS dep_min_score,
52 | MAX( score ) OVER( PARTITION BY dep_name ORDER BY dep_name ASCENDING ) AS dep_max_score,
53 | CAST( AVG( score ) OVER( PARTITION BY dep_name ORDER BY dep_name ASCENDING ) AS INT4 ) AS dep_avg_score,
54 |
55 | ROW_NUMBER( ) OVER( ORDER BY student_name ) AS name_serial_number,
56 | RANK( ) OVER( PARTITION BY dep_name ORDER BY score DESCENDING ) AS dep_wise_rank_with_gaps,
57 | DENSE_RANK( ) OVER( PARTITION BY dep_name ORDER BY score DESCENDING ) AS dep_wise_rank_wo_gaps,
58 |
59 | LAG( score ) OVER( PARTITION BY dep_name ORDER BY score ) AS prev_score_by_dept,
60 | LEAD( score ) OVER( PARTITION BY dep_name ORDER BY score ) AS next_score_by_dept,
61 |
62 | SUM( score ) OVER( ORDER BY student_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sum,
63 | SUM( score ) OVER( ORDER BY student_id ) AS running_sum,
64 |
65 | FIRST_VALUE( student_id ) OVER( PARTITION BY dep_name ORDER BY score DESCENDING ) AS top_perfomer_dep_wise,
66 | LAST_VALUE( student_id ) OVER( PARTITION BY dep_name ORDER BY score DESCENDING ) AS low_perfomer_dep_wise,
67 |
68 | NTILE( 3 ) OVER( ORDER BY score ) AS group_students_by_3_levels
69 |
70 | ORDER BY dep_name, score DESCENDING
71 | INTO TABLE @DATA(lt_result)
72 | .
73 | out->write( lt_result ).
74 | ENDMETHOD.
75 | ENDCLASS.
76 |
77 |
78 | " Output
79 | *STUDENT_ID STUDENT_NAME DEP_NAME SCORE TOTAL_SCORE MAXIMUM_SCORE MININUM_SCORE AVERAGE_SCORE DEP_TOTAL_SCORE DEP_MIN_SCORE DEP_MAX_SCORE DEP_AVG_SCORE NAME_SERIAL_NUMBER DEP_WISE_RANK_WITH_GAPS DEP_WISE_RANK_WO_GAPS PREV_SCORE_BY_DEPT NEXT_SCORE_BY_DEPT CUMULATIVE_SUM RUNNING_SUM TOP_PERFOMER_DEP_WISE LOW_PERFOMER_DEP_WISE GROUP_STUDENTS_BY_3_LEVELS
80 | *2 Dhakshan CSE 87 1164 95 65 83 309 65 87 77 6 1 1 82 0 177 177 2 2 2
81 | *8 Mohan CSE 82 1164 95 65 83 309 65 87 77 8 2 2 75 87 703 703 2 8 2
82 | *13 Shasank CSE 75 1164 95 65 83 309 65 87 77 11 3 3 65 82 1074 1074 2 13 1
83 | *10 Rohan CSE 65 1164 95 65 83 309 65 87 77 9 4 4 0 75 860 860 2 10 1
84 | *3 Shroy EEE 95 1164 95 65 83 358 78 95 89 12 1 1 95 0 272 272 6 3 3
85 | *6 Anish EEE 95 1164 95 65 83 358 78 95 89 1 1 1 90 95 530 530 6 3 3
86 | *14 Kaviya EEE 90 1164 95 65 83 358 78 95 89 7 3 2 78 95 1164 1164 6 14 2
87 | *4 Bhuvi EEE 78 1164 95 65 83 358 78 95 89 4 4 3 0 90 350 350 6 4 1
88 | *9 Saurabh IT 92 1164 95 65 83 267 85 92 89 10 1 1 90 0 795 795 9 9 3
89 | *1 Bharathi S IT 90 1164 95 65 83 267 85 92 89 3 2 2 85 92 90 90 9 1 2
90 | *5 Thara IT 85 1164 95 65 83 267 85 92 89 14 3 3 0 90 435 435 9 5 2
91 | *7 Aravind MECH 91 1164 95 65 83 230 67 91 76 2 1 1 72 0 621 621 7 7 3
92 | *11 Surya MECH 72 1164 95 65 83 230 67 91 76 13 2 2 67 91 932 932 7 11 1
93 | *12 Boopalan MECH 67 1164 95 65 83 230 67 91 76 5 3 3 0 72 999 999 7 12 1
--------------------------------------------------------------------------------
/ABAP RAP/Download_Adobe_Form_in_RAP.abap:
--------------------------------------------------------------------------------
1 | "D𝗼𝘄𝗻𝗹𝗼𝗮𝗱𝗶𝗻𝗴 𝗔𝗱𝗼𝗯𝗲 𝗳𝗼𝗿𝗺𝘀 𝗼𝗿 𝗮𝗻𝘆 𝗳𝗶𝗹𝗲𝘀 𝗶𝗻 𝗥𝗔𝗣.
2 | "if you’ve tried this before, you might have noticed that methods like 𝗚𝗨𝗜_𝗗𝗢𝗪𝗡𝗟𝗢𝗔𝗗 or 𝗰𝗹_𝗴𝘂𝗶_𝗳𝗿𝗼𝗻𝘁𝗲𝗻𝗱_𝘀𝗲𝗿𝘃𝗶𝗰𝗲𝘀=>𝗴𝘂𝗶_𝗱𝗼𝘄𝗻𝗹𝗼𝗮𝗱 don’t work in RAP.
3 | "So, what’s the alternative? This can be achieved using streams (file upload) in RAP, combined with some additional logic.
4 | "Here are the two approaches I followed in my example:
5 |
6 | "1. 𝗖𝗿𝗲𝗮𝘁𝗲 𝗮𝗻 𝗮𝗰𝘁𝗶𝗼𝗻 to populate your stream fields with form data.
7 | "2. Use a 𝘃𝗶𝗿𝘁𝘂𝗮𝗹 𝗲𝗹𝗲𝗺𝗲𝗻𝘁 to fill your stream fields (not recommended, as it may trigger your Adobe form method multiple times).
8 | "Note: Ensure that your stream fields (attachment fields) are set to read-only,since it's getting filled through our logic. For the below Example I’ve created on OdataV4 – UI
9 |
10 | "1. Create a Table
11 | @EndUserText.label : 'Employee DATA'
12 | @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
13 | @AbapCatalog.tableCategory : #TRANSPARENT
14 | @AbapCatalog.deliveryClass : #A
15 | @AbapCatalog.dataMaintenance : #RESTRICTED
16 | define table zsb_emp_file_det {
17 |
18 | key client : abap.clnt not null;
19 | key employeeid : pernr_d not null;
20 | employeename : text100;
21 | attachment : /dmo/attachment;
22 | mimetype : /dmo/mime_type;
23 | filename : /dmo/filename;
24 | local_created_by : abp_creation_user;
25 | local_created_at : abp_creation_tstmpl;
26 | local_last_changed_by : abp_locinst_lastchange_user;
27 | local_last_changed_at : abp_locinst_lastchange_tstmpl;
28 | last_changed_at : abp_lastchange_tstmpl;
29 | }
30 |
31 |
32 | "2. Create a Root Entity
33 | @AccessControl.authorizationCheck: #CHECK
34 | @Metadata.allowExtensions: true
35 | @EndUserText.label: '###GENERATED Core Data Service Entity'
36 | @ObjectModel.sapObjectNodeType.name: 'Zsb_Emp_File_DET'
37 | define root view entity ZR_SB_EMP_FILE_DET
38 | as select from zsb_emp_file_det
39 | {
40 | key employeeid as Employeeid,
41 | employeename as Employeename,
42 | @Semantics.largeObject:{ fileName: 'Filename',mimeType: 'Mimetype',contentDispositionPreference: #ATTACHMENT }
43 | attachment as Attachment,
44 | @Semantics.mimeType: true
45 | mimetype as Mimetype,
46 | filename as Filename,
47 | @Semantics.user.createdBy: true
48 | local_created_by as LocalCreatedBy,
49 | @Semantics.systemDateTime.createdAt: true
50 | local_created_at as LocalCreatedAt,
51 | @Semantics.user.localInstanceLastChangedBy: true
52 | local_last_changed_by as LocalLastChangedBy,
53 | @Semantics.systemDateTime.localInstanceLastChangedAt: true
54 | local_last_changed_at as LocalLastChangedAt,
55 | @Semantics.systemDateTime.lastChangedAt: true
56 | last_changed_at as LastChangedAt
57 |
58 | }
59 |
60 | "3. Create a Projection View
61 | @ObjectModel.sapObjectNodeType.name: 'Zsb_Emp_File_DET'
62 | define root view entity ZC_SB_EMP_FILE_DET
63 | provider contract transactional_query
64 | as projection on ZR_SB_EMP_FILE_DET
65 | {
66 | key Employeeid,
67 | Employeename,
68 | LocalCreatedBy,
69 | LocalCreatedAt,
70 | LocalLastChangedBy,
71 | LocalLastChangedAt,
72 | LastChangedAt,
73 |
74 | Attachment,
75 | Mimetype,
76 | Filename,
77 |
78 | @Semantics.largeObject:{ fileName: 'vfilename', mimeType: 'vmimetype', contentDispositionPreference: #ATTACHMENT }
79 | @ObjectModel.virtualElement: true
80 | @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_FILE_VIRTUAL'
81 | virtual vattachment : /dmo/attachment,
82 |
83 | @ObjectModel.virtualElement: true
84 | @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_FILE_VIRTUAL'
85 | @Semantics.mimeType: true
86 | virtual vmimetype : /dmo/mime_type,
87 |
88 | @ObjectModel.virtualElement: true
89 | @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_FILE_VIRTUAL'
90 | virtual vfilename : /dmo/filename
91 |
92 | }
93 |
94 | "4. Metadata Extensions
95 | @Metadata.layer: #CORE
96 | @UI.headerInfo.title.type: #STANDARD
97 | @UI.headerInfo.title.value: 'Employeeid'
98 | @UI.headerInfo.description.type: #STANDARD
99 | @UI.headerInfo.description.value: 'Employeeid'
100 | annotate view ZC_SB_EMP_FILE_DET with
101 | {
102 | @UI.facet: [ {
103 | label: 'General Information',
104 | id: 'GeneralInfo',
105 | purpose: #STANDARD,
106 | position: 10 ,
107 | type: #IDENTIFICATION_REFERENCE
108 | } ]
109 | @UI.identification: [ { position: 10,label: 'Employee Id' },
110 | { type: #FOR_ACTION, dataAction: 'downloadForm', label: 'Download Adobe Form' } ]
111 | @UI.lineItem: [ { position: 10,label: 'Employee Id' } ]
112 | @UI.selectionField: [ { position: 10 } ]
113 | Employeeid;
114 |
115 | @UI.identification: [ { position: 20, label :'Employee Name' } ]
116 | @UI.lineItem: [ { position: 20, label: 'Employee Name' } ]
117 | Employeename;
118 |
119 | @UI.identification: [ { position: 30, label: 'Attachment(Based on Action)' } ]
120 | Attachment;
121 |
122 | @UI.identification: [ { position: 30, label: 'Attachment(Based on Virtual Element)' } ]
123 | vattachment;
124 |
125 | @UI.hidden: true
126 | Mimetype;
127 | @UI.hidden: true
128 | Filename;
129 | }
130 |
131 |
132 | "5. Behaviour Defination
133 | managed implementation in class ZBP_R_SB_EMP_FILE_DET unique;
134 | strict ( 2 );
135 | with draft;
136 | define behavior for ZR_SB_EMP_FILE_DET alias ZrSbEmpFileDet
137 | persistent table ZSB_EMP_FILE_DET
138 | draft table ZSB_EMP_FLE_DT_D
139 | etag master LocalLastChangedAt
140 | lock master total etag LastChangedAt
141 | authorization master( global )
142 |
143 | {
144 |
145 | field( mandatory : create, readonly : update ) Employeeid;
146 | field ( readonly )
147 | LocalCreatedBy,
148 | LocalCreatedAt,
149 | LocalLastChangedBy,
150 | LocalLastChangedAt,
151 | LastChangedAt;
152 |
153 | field ( readonly ) Attachment;
154 | action downloadForm result [0..1] $self;
155 |
156 | create;
157 | update;
158 | delete;
159 |
160 | draft action Activate optimized;
161 | draft action Discard;
162 | draft action Edit;
163 | draft action Resume;
164 | draft determine action Prepare;
165 |
166 | mapping for ZSB_EMP_FILE_DET
167 | {
168 | Employeeid = employeeid;
169 | Employeename = employeename;
170 | Attachment = attachment;
171 | Mimetype = mimetype;
172 | Filename = filename;
173 | LocalCreatedBy = local_created_by;
174 | LocalCreatedAt = local_created_at;
175 | LocalLastChangedBy = local_last_changed_by;
176 | LocalLastChangedAt = local_last_changed_at;
177 | LastChangedAt = last_changed_at;
178 | }
179 | }
180 |
181 | "6. Behaviour Implementation - Action code
182 | METHOD downloadForm.
183 |
184 | DATA: lt_update TYPE TABLE FOR UPDATE zr_sb_emp_file_det.
185 |
186 | lt_update = VALUE #( for key in keys (
187 | %tky = key-%tky
188 | Attachment = NEW ZCL_SB_FORM( )->get_form( key-Employeeid ) "This logic added in the below
189 | Filename = |Adobe_Form.pdf|
190 | Mimetype = 'APPLICATION/PDF'
191 | %control = VALUE #( Attachment = if_abap_behv=>mk-on
192 | Filename = if_abap_behv=>mk-on
193 | Mimetype = if_abap_behv=>mk-on )
194 | ) ).
195 |
196 | MODIFY ENTITIES OF zr_sb_emp_file_det IN LOCAL MODE
197 | ENTITY ZrSbEmpFileDet
198 | UPDATE FROM lt_update
199 | REPORTED DATA(lt_update_reported)
200 | FAILED DATA(lt_update_failed).
201 |
202 | READ ENTITIES OF zr_sb_emp_file_det IN LOCAL MODE
203 | ENTITY ZrSbEmpFileDet
204 | ALL FIELDS WITH CORRESPONDING #( keys )
205 | RESULT DATA(lt_result).
206 |
207 | result = VALUE #( for ls_result in lt_result (
208 | %tky = ls_result-%tky
209 | %param = CORRESPONDING #( ls_result ) ) ).
210 |
211 | ENDMETHOD.
212 |
213 | "7. Behaviour Projection
214 | projection;
215 | strict ( 2 );
216 | use draft;
217 | define behavior for ZC_SB_EMP_FILE_DET alias ZcSbEmpFileDet
218 | use etag
219 |
220 | {
221 | use create;
222 | use update;
223 | use delete;
224 |
225 | use action downloadForm;
226 |
227 | use action Edit;
228 | use action Activate;
229 | use action Discard;
230 | use action Resume;
231 | use action Prepare;
232 | }
233 |
234 | "8. Service Definition and Service Binding
235 | @EndUserText: {
236 | label: 'Service Definition for ZC_SB_EMP_FILE_DET'
237 | }
238 | @ObjectModel: {
239 | leadingEntity: {
240 | name: 'ZC_SB_EMP_FILE_DET'
241 | }
242 | }
243 | define service ZUI_SB_EMP_FILE_DET_O4 {
244 | expose ZC_SB_EMP_FILE_DET;
245 | }
246 | * Create a service binding with OData V4 - UI
247 |
248 | "9. Vitrual Element calculation Class -
249 | CLASS zcl_file_virtual DEFINITION
250 | PUBLIC
251 | FINAL
252 | CREATE PUBLIC.
253 |
254 | PUBLIC SECTION.
255 |
256 | INTERFACES if_sadl_exit .
257 | INTERFACES if_sadl_exit_calc_element_read .
258 | PROTECTED SECTION.
259 | PRIVATE SECTION.
260 | ENDCLASS.
261 |
262 |
263 | CLASS zcl_file_virtual IMPLEMENTATION.
264 | METHOD if_sadl_exit_calc_element_read~calculate.
265 | DATA : lt_emp_data TYPE TABLE OF zc_sb_emp_file_det.
266 | lt_emp_data = CORRESPONDING #( it_original_data ).
267 |
268 | LOOP AT lt_emp_data ASSIGNING FIELD-SYMBOL().
269 | -vattachment = NEW ZCL_SB_FORM( )->get_form( -Employeeid ). "This logic added in the below
270 | -vfilename = |Adobe_Form.pdf|.
271 | -vmimetype = 'APPLICATION/PDF' .
272 | ENDLOOP.
273 |
274 | ct_calculated_data = CORRESPONDING #( lt_emp_data ).
275 | ENDMETHOD.
276 |
277 |
278 | METHOD if_sadl_exit_calc_element_read~get_calculation_info.
279 | ENDMETHOD.
280 | ENDCLASS.
281 |
282 | "Code to get Adobe form as Xstring:
283 |
284 | CLASS zcl_sb_form DEFINITION
285 | PUBLIC
286 | CREATE PUBLIC .
287 | PUBLIC SECTION.
288 | METHODS get_form
289 | IMPORTING
290 | !iv_customer_id TYPE s_customer
291 | RETURNING
292 | VALUE(rv_pdf) TYPE fpcontent .
293 | PROTECTED SECTION.
294 | PRIVATE SECTION.
295 | METHODS get_customer_data
296 | IMPORTING
297 | !iv_customer_id TYPE s_customer
298 | EXPORTING
299 | !customer_detail TYPE scustom
300 | !bookings TYPE ty_bookings
301 | !connections TYPE ty_connections .
302 | ENDCLASS.
303 |
304 |
305 |
306 | CLASS zcl_sb_form IMPLEMENTATION.
307 |
308 |
309 | METHOD get_customer_data.
310 |
311 | SELECT SINGLE FROM scustom
312 | FIELDS *
313 | WHERE id = @iv_customer_id
314 | INTO @customer_detail.
315 | SELECT FROM bookings
316 | FIELDS *
317 | WHERE customid = @iv_customer_id
318 | INTO TABLE @bookings.
319 | IF lines( bookings ) > 0.
320 | SELECT * FROM spfli INTO TABLE @connections
321 | FOR ALL ENTRIES IN @bookings
322 | WHERE carrid = @bookings-carrid
323 | AND connid = @bookings-connid.
324 | ENDIF.
325 |
326 | ENDMETHOD.
327 |
328 |
329 | METHOD get_form.
330 |
331 | DATA(lv_form_name) = CONV tdsfname( 'FP_TEST_03' ).
332 | DATA(lv_form_fm_name) = VALUE rs38l_fnam( ).
333 | DATA(ls_docparams) = VALUE sfpdocparams( ).
334 | DATA(ls_outputparams) = VALUE sfpoutputparams( ).
335 | DATA(ls_formoutput) = VALUE fpformoutput( ).
336 | * Get data
337 | get_customer_data(
338 | EXPORTING
339 | iv_customer_id = iv_customer_id
340 | IMPORTING
341 | customer_detail = DATA(customer)
342 | bookings = DATA(bookings)
343 | connections = DATA(connections) ).
344 | * get name of the generated function module
345 | TRY.
346 | CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
347 | EXPORTING
348 | i_name = lv_form_name
349 | IMPORTING
350 | e_funcname = lv_form_fm_name.
351 | CATCH cx_fp_api INTO DATA(lx_fp_api).
352 | MESSAGE ID lx_fp_api->msgid TYPE lx_fp_api->msgty
353 | NUMBER lx_fp_api->msgno
354 | WITH lx_fp_api->msgv1 lx_fp_api->msgv2
355 | lx_fp_api->msgv3 lx_fp_api->msgv4.
356 | RETURN.
357 | ENDTRY.
358 | * Set output parameters and open spool job
359 | ls_outputparams-nodialog = 'X'. " no print preview
360 | ls_outputparams-getpdf = 'X'. " request PDF
361 | CALL FUNCTION 'FP_JOB_OPEN'
362 | CHANGING
363 | ie_outputparams = ls_outputparams
364 | EXCEPTIONS
365 | cancel = 1
366 | usage_error = 2
367 | system_error = 3
368 | internal_error = 4
369 | OTHERS = 5.
370 | IF sy-subrc <> 0.
371 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
372 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
373 | RETURN.
374 | ENDIF.
375 | * Now call the generated function module
376 | CALL FUNCTION lv_form_fm_name
377 | EXPORTING
378 | /1bcdwb/docparams = ls_docparams
379 | customer = customer
380 | bookings = bookings
381 | connections = connections
382 | IMPORTING
383 | /1bcdwb/formoutput = ls_formoutput
384 | EXCEPTIONS
385 | usage_error = 1
386 | system_error = 2
387 | internal_error = 3
388 | OTHERS = 4.
389 | IF sy-subrc <> 0.
390 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
391 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
392 | RETURN.
393 | ENDIF.
394 | * Close spool job
395 | CALL FUNCTION 'FP_JOB_CLOSE'
396 | EXCEPTIONS
397 | usage_error = 1
398 | system_error = 2
399 | internal_error = 3
400 | OTHERS = 4.
401 | IF sy-subrc <> 0.
402 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
403 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
404 | RETURN.
405 | ENDIF.
406 | rv_pdf = ls_formoutput-pdf.
407 | ENDMETHOD.
408 | ENDCLASS.
--------------------------------------------------------------------------------