Showing posts with label SAP S/4HANA. Show all posts
Showing posts with label SAP S/4HANA. Show all posts

Monday, 1 July 2024

SAP Datasphere: Replicating Custom CDS Views from S4 HANA to Azure Data Lake with CDC

Introduction


In this article I will share work experiences of using a custom CDS view on Joining BKPF and BSEG table in S4HANA and consuming it in SAP Datasphere for delta enabled replication (Change Data Capture) to Azure Data Lake Storage Gen2.

SAP Datasphere: Replicating Custom CDS Views from S4 HANA to Azure Data Lake with CDC

Create a Custom CDS View: ADT on Eclipse


Go to ABAP Repository Object and Click on the drop down for Core Data Services and then click on Data Definitions:

Friday, 21 June 2024

How to replicate your Fiori Inbox in Microsoft Teams

Using Looply you can replicate your Fiori Inbox in Teams, and it’s fast and easy.

Putting outstanding workitems in the face of those users who are not logged into SAP Work Zone / Fiori LaunchPad / SAPGUI can accelerate processes and lead to a host of other benefits.

We can build the solution in 4 steps.

[1] Consider the trigger points.


You have options. You might run a background job periodically to update Teams. This is easy to set up, but resource-intensive if you decide to run it every few minutes instead of, say, twice per day.

Wednesday, 12 June 2024

Introducing new type of Data Access Control "Operator and Value" for SAP Datasphere

Row-level security in SAP Datasphere is implemented via Data Access Controls (DACs) to allow a more granular assignment of authorisations and access to data on dedicated views within a Space.

In general DACs are objects which can be created in SAP Datasphere as objects in their own right which control access to data for each user within a Space. Hence, an integral part of a DAC is a list of values a user is allowed to see for a dimension (e.g. 'Sales Units') a user is allowed to see. This list can be maintained  in a local table, a view or even a table function. Each value a user is allowed to see must be represented by one record in this list of authorised values.

Wednesday, 24 April 2024

How to improve the ADT Class Runner with additional Features

What is a Class Runner?


A class runner is a great tool to test code snippets and run code directly from ADT. You can even write a simple log to the console in Eclipse.

What can be improved?


When using multiple systems and complex projects I got annoyed at some point in time, that I don't know from which system the last log was, when it was written by which runner and if the last execution has finished or failed maybe.

Wednesday, 20 March 2024

SAP BW Bridge In SAP Datasphere: Connectivity Between S/4HANA System & BW Bridge

Introduction:


SAP BW bridge is a functional enhancement of SAP Datasphere and enables ABAP-based data extraction and staging capabilities within SAP Datasphere. It provides customers who are running SAP Business Warehouse or SAP BW/4HANA with access to the public cloud as it offers SAP BW capabilities directly in SAP Datasphere.

SAP BW Bridge for SAP Datasphere is a feature that makes certain elements from the on-premise SAP BW system available in the cloud. In order to transfer these elements to SAP Datasphere, SAP also supplies the appropriate conversion tools. SAP BW Bridge is a cost-effective and simple way to switch from an on-premise SAP BW system to SAP Datasphere.

Wednesday, 24 January 2024

Inventory Aging Trend with S/4HANA Embedded Analytics

Inventory aging trend with S/4HANA embedded analytics? Hmm…Sounds like data warehousing  snapshot requirement. Actually S/4HANA inventory data model supports key date concept (with some limitation) making it possible trend analysis.

Example below demonstrates one of possible use cases – month to month comparison showing changes across different aging ranges

Inventory Aging Trend with S/4HANA Embedded Analytics

Monday, 8 January 2024

Encrypted E-mail Attachment Pdf

I am delighted to communicate my enthusiasm regarding the proposed measure to enhance the security of the payroll envelope mail that is slated for transmission within the Human Resources (HR) module. This enhancement involves the implementation of encryption to fortify the confidentiality and integrity of the sensitive information contained in the payroll documentation.

I have employed a third-party tool supplied by ‘VeryPDF‘ to implement PDF encryption with a password.

Specifically, the ‘Encrypt PDF Command Line‘ tool from VeryPDF facilitates the encryption of PDFs with a password through the Windows Command Prompt. We can easily trigger that tool from SAP. It is noteworthy that a trial version is available for testing purposes.

Tuesday, 5 December 2023

Alternative option for IMPORT/ EXPORT using Shared Memory SHMA approach.

Motivation:-


In this blog you will learn how to use shared memory as alternative option of ABAP Memory(Import/Export).

Business Scenario:- Many of times we need Import & Export at the time of SAP Enhancement or other requirements so Here use of shared memory which is also alternate option of Import/ Export and as per SAP standard guideline this approach is highly recommended.

Monday, 6 November 2023

Customer Aging and Supplier Aging Reports at the Line Item Level using Analytical Query in S/4HANA Cloud, Public Edition

Introduction


Functional consultant or a business key user can effortlessly generate supplier and customer aging reports using the Custom Analytical Queries App for the scenarios outlined below.

Scenario – Accounts Payable Aging:

Your client requires a supplier aging report that displays the aging at different levels: Supplier level, Reconciliation G/L level, Supplier Region level, and Profit Center level. Additionally, they would like the option to access the aging information at the accounting document level in the same report.

Friday, 20 October 2023

S/4HANA Multi Level BOM Unboxed: Navigating BOM Hierarchy: A Recursive Adventure – Part1

Introduction


Greetings, fellow SAP enthusiasts! Today, we’re diving into the intricate world of Bill of Materials (BOM) and tackling a challenging yet fascinating user requirement. Our mission? To develop a Report that navigates through the recursive nature of BOM data, providing users with a comprehensive view of the hierarchy.

The Challenge


The provided scenario outlines a case requirement wherein the described approach can be employed whenever recursion is necessary, contingent upon external specifications.

Our user wants to start with a material and a specific field, the serial number, from the STPO table. The goal is to traverse through the BOM data, then explore related tables (STKO, EQST, EQUI) to finally present a detailed hierarchy of BOM and its related Composite Equipment’s info like materials and serial numbers.

Wednesday, 18 October 2023

Writing ABAP UNIT using test double framework(DOC)

Let’s begin with an example.Below method has one function module dependency and one method external method dependency.The Class having this method is CUT(Code Under Test).The aim of the ABAP unit is to validate the code residing in this method,not to validate the code of the dependent function module / other method.

SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Prep, SAP ABAP Preparation, SAP ABAP Guides, SAP ABAP Learning, SAP ABAP Certification

Friday, 13 October 2023

SAP ABAP RAP: Custom Entities with compositions relationship in a Fiori Elements App

Introduction:


ABAP Restful Application Programming is an efficient and cloud-compatible development model that enables rapid creation of Fiori apps.

This programming model facilitates both Managed and Unmanaged Implementation approaches, although the core data source must originate from a CDS view or a table within the same system in both scenarios. However, the non-key fields can be calculated on the fly using virtual elements.

When retrieving data from a remote source through an API or performing complex calculations, managing CDS view entities becomes challenging. Further complexities arise when compositions  are involved.

Saturday, 7 October 2023

FSCM Workflow – Credit Limit Approval Alternative

SAP ABAP Career, SAP ABAP Skills, SAP ABAP Prep, SAP ABAP Preparation, SAP ABAP Certification, SAP ABAP Tutorial and Materials

Sometimes SAP standard does not meet all requirements and that’s where the “Custom Code” comes in…

Friday, 29 September 2023

Upload transport files from SAP

Introduction


This blog is useful consultants/Admins/functional folks who can’t not have access to operating system to transfer cofiles and data files

This blog describes detailed steps “How to upload and download cofiles/data files directly from SAP” pretty useful. You don’t need to have access to OS.

How to Do: Download and upload Co-files/Data files (Transports) directly from SAP

Thursday, 31 August 2023

Designing Custom Tree Screen Using Report Program

REPORT ysk_modulepool_tree.

INCLUDE ymodulepool_tree_top.  “data declaration
INCLUDE ymodulepool_tree_cl1.  “class declaration
INCLUDE ymodulepool_tree_o01.  “PBO Modules
INCLUDE ymodulepool_tree_i01.  “PAI Modules
INCLUDE ymodulepool_tree_f01.  “Form Routines

START-OF-SELECTION.

CREATE OBJECT g_application.
SET SCREEN 100.

1. Draw one screen name as 100 and create a custom control name as YCONTROL.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Guides, SAP ABAP Learning

2. In the same screen create one more custom control and name as ZPP_CONTOL.

SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Guides, SAP ABAP Learning

*&———————————————————————*
*& Include          YMODULEPOOL_TREE_TOP
*&———————————————————————*

class lcl_application DEFINITION DEFERRED.

class cl_gui_cfw DEFINITION load.

DATA: g_application TYPE REF TO lcl_application,
g_custom_container TYPE REF TO cl_gui_custom_container,
g_tree TYPE REF TO cl_simple_tree_model,
g_ok_code TYPE sy-ucomm.

* Fields on Dynpro 500
DATA: g_event(30),
g_node_key(30) TYPE c.
*——————————————————–
******Data Declarations For Insert Image on Screen.***********
CONSTANTS: cntl_true  TYPE i VALUE 1,
cntl_false TYPE i VALUE 0.
DATA:
h_picture       TYPE REF TO cl_gui_picture,
h_pic_container TYPE REF TO cl_gui_custom_container.
DATA: graphic_size TYPE i.

DATA: BEGIN OF graphic_table OCCURS 0,
line(255) TYPE x,
END OF graphic_table.
DATA: graphic_url(255),
graphic_refresh(1),
g_result    LIKE cntl_true.


*&———————————————————————*
*& Include          YMODULEPOOL_TREE_CL1
*&———————————————————————*

CLASS lcl_application DEFINITION.

PUBLIC SECTION.
METHODS:
handle_node_double_click
FOR EVENT node_double_click
OF cl_simple_tree_model
IMPORTING node_key.
ENDCLASS.                    “lcl_application DEFINITION

CLASS lcl_application IMPLEMENTATION.

METHOD handle_node_double_click.
g_event = ‘NODE_DOUBLE_CLICK’.
g_node_key = node_key.

IF g_node_key EQ ‘Vendor Sampling'(001).
CALL TRANSACTION ‘ZQM_VNSMPL’.
ELSEIF g_node_key EQ ‘Trim Audit'(003).
CALL TRANSACTION ‘ZQM_TRIM’.
ELSEIF g_node_key EQ ‘Out Source'(004).
CALL TRANSACTION ‘ZQM_OUTSOURCE’.“
ELSEIF g_node_key EQ ‘Final Goods'(005).
CALL TRANSACTION ‘ZQM_FG_FINAL’..
ELSEIF g_node_key EQ ‘Inspection’.
CALL TRANSACTION ‘ZQM_FINISHGOODS’.“
ELSEIF g_node_key EQ ‘Fout Source’.
CALL TRANSACTION ‘ZFOUTSOURCE’.
ELSEIF g_node_key EQ ‘Finish goods’.
CALL TRANSACTION ‘ZQM_FINISHGOODS’.
ELSEIF g_node_key EQ ‘FVNSMPL’.
CALL TRANSACTION ‘ZFVNSMPL’.“‘
ELSEIF g_node_key EQ ‘VNSMPL’.
CALL TRANSACTION ‘ZVNSMPL’.
ELSEIF g_node_key EQ ‘TRIMAUDIT’.
CALL TRANSACTION ‘ZTRIMAUDIT’.
ELSEIF g_node_key EQ ‘FINAL INS’.
CALL TRANSACTION ‘ZQM_FINAL_INS’.
ELSEIF g_node_key EQ ‘ZQM_TRIM’.
CALL TRANSACTION   ‘ZQM_TRIM’.
ELSEIF g_node_key EQ ‘ZTRIMAUDIT’.
CALL TRANSACTION ‘ZTRIMAUDIT’.
ELSEIF g_node_key EQ ‘ZQM_OUTSOURCE’.
CALL TRANSACTION ‘ZQM_FINISHED’.
ELSEIF g_node_key EQ ‘ZQM_INSPECTION’.
CALL TRANSACTION ‘ZQM_FINISHGOODS’.
ELSEIF g_node_key EQ ‘ZFOUTSOURCE’.
CALL TRANSACTION ‘ZQM_FINAL_INS’.
ELSEIF g_node_key EQ ‘ZQM_FG_FINAL’.
CALL TRANSACTION ‘ZQM_FG_FINAL’.
ELSEIF g_node_key EQ ‘ZQM_FINISHGOODS’.
CALL TRANSACTION ‘ZQM_INSPECTION’.
ELSEIF g_node_key EQ ‘ZQM_FINAL_INS’.
CALL TRANSACTION ‘ZFOUTSOURCE’.
ELSEIF g_node_key EQ ‘ZQM_TRIMADOBE’.
CALL TRANSACTION ‘ZQM_TRIMADOBE’.
ENDIF.
ENDMETHOD.                    “handle_node_double_click
ENDCLASS.                    “lcl_application IMPLEMENTATION

*&———————————————————————*
*& Include          YMODULEPOOL_TREE_O01
*&———————————————————————*
*&———————————————————————*
*& Module STATUS_0100 OUTPUT
*&———————————————————————*
*&
*&———————————————————————*
MODULE status_0100 OUTPUT.
SET PF-STATUS ‘YTREE’.
SET TITLEBAR ‘YTREET’.
IF g_tree IS INITIAL.
PERFORM create_and_init_tree. “calling subroutine
ENDIF.

* ———————————-THIS LOGIC FOR WALLPAPER IMAGE —————
DATA: l_graphic_xstr TYPE xstring,
l_graphic_conv TYPE i,
l_graphic_offs TYPE i.

CALL METHOD cl_ssf_xsf_utilities=>get_bds_graphic_as_bmp
EXPORTING
p_object  = ‘GRAPHICS’
p_name    = ‘MCFL’ “IMAGE NAME – Image name from SE78
p_id      = ‘BMAP’
p_btype   = ‘BCOL’  “(BMON = black&white, BCOL = colour)
RECEIVING
p_bmp     = l_graphic_xstr
EXCEPTIONS
not_found = 1
OTHERS    = 2.

graphic_size = XSTRLEN( l_graphic_xstr ).
CHECK graphic_size > 0.

l_graphic_conv = graphic_size.
l_graphic_offs = 0.

WHILE l_graphic_conv > 255.
graphic_table-line = l_graphic_xstr+l_graphic_offs(255).
APPEND graphic_table.
l_graphic_offs = l_graphic_offs + 255.
l_graphic_conv = l_graphic_conv – 255.
ENDWHILE.

graphic_table-line = l_graphic_xstr+l_graphic_offs(l_graphic_conv).
APPEND graphic_table.

CALL FUNCTION ‘DP_CREATE_URL’
EXPORTING
type                 = ‘image’                    “#EC NOTEXT
subtype              = cndp_sap_tab_unknown ” ‘X-UNKNOWN’
size                 = graphic_size

lifetime             = cndp_lifetime_transaction  “‘T’
TABLES
data                 = graphic_table
CHANGING
url                  = graphic_url
EXCEPTIONS
dp_invalid_parameter = 1
dp_error_put_table   = 2
dp_error_general     = 3
OTHERS               = 4 .
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
EXIT.
ENDIF.

CREATE OBJECT h_pic_container
EXPORTING container_name =  ‘ZPP_CONTROL’.
CREATE OBJECT h_picture EXPORTING parent = h_pic_container.

CALL METHOD h_picture->load_picture_from_url
EXPORTING
url    = graphic_url
IMPORTING
RESULT = g_result.

————————————-END CODE OF IMAGE —————————-
ENDMODULE.


*&———————————————————————*
*& Include          YMODULEPOOL_TREE_I01
*&———————————————————————*
*&———————————————————————*
*&      Module  USER_COMMAND_0100  INPUT
*&———————————————————————*
*       text
*———————————————————————-*
MODULE user_command_0100 INPUT.
DATA: return_code TYPE i.
* CL_GUI_CFW=>DISPATCH must be called if events are registered
* that trigger PAI
* this method calls the event handler method of an event
CALL METHOD cl_gui_cfw=>dispatch
IMPORTING return_code = return_code.
IF return_code <> cl_gui_cfw=>rc_noevent.
” a control event occured => exit PAI
*    CLEAR g_ok_code.
EXIT.
ENDIF.

CASE SY-UCOMM.   “g_ok_code.
WHEN ‘BACK’.                       ” Finish program
IF NOT g_custom_container IS INITIAL.

“Destroy tree container (destroys contained tree control, too)
CALL METHOD g_custom_container->free
EXCEPTIONS
cntl_system_error = 1
cntl_error        = 2.
IF sy-subrc <> 0.
**          MESSAGE a000.
ENDIF.
CLEAR g_custom_container.
CLEAR g_tree.
ENDIF.
LEAVE PROGRAM.
WHEN ‘EXIT’.
LEAVE TO SCREEN 0.
WHEN ‘CANCEL’.
LEAVE TO SCREEN 0.
ENDCASE.
* CAUTION: Clear ok code!
CLEAR g_ok_code.
ENDMODULE.

*&———————————————————————*
*& Include          YMODULEPOOL_TREE_F01
*&———————————————————————*
*&———————————————————————*
*& Form create_and_init_tree
*&———————————————————————*
*& text
*&———————————————————————*
*& –>  p1        text
*& <–  p2        text
*&———————————————————————*
FORM create_and_init_tree .” defined form logic
DATA: event  TYPE cntl_simple_event,
events TYPE cntl_simple_events.

* Create a simple tree model instance
CREATE OBJECT g_tree
EXPORTING
node_selection_mode         = cl_simple_tree_model=>node_sel_mode_single
EXCEPTIONS
illegal_node_selection_mode = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

* Create a container for the tree control
CREATE OBJECT g_custom_container
EXPORTING      ” The container is linked to the custom control with the
” name ‘TREE_CONTAINER’ on the Dynpro
container_name              = ‘YCONTROL’ “custom container name

EXCEPTIONS
cntl_error                        = 1
cntl_system_error           = 2
create_error                   = 3
lifetime_error                 = 4
lifetime_dynpro_dynpro_link = 5.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

* create the view (control) of the tree model

CALL METHOD g_tree->create_tree_control
EXPORTING
parent                       = g_custom_container
EXCEPTIONS
lifetime_error               = 1
cntl_system_error            = 2
create_error                 = 3
failed                       = 4
tree_control_already_created = 5.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

* define the events which will be passed to the backend
” node double click
event-eventid = cl_simple_tree_model=>eventid_node_double_click.
event-appl_event = ‘X’.              ” process PAI if event occurs
APPEND event TO events.

CALL METHOD g_tree->set_registered_events
EXPORTING
events                    = events
EXCEPTIONS
illegal_event_combination = 1
unknown_event             = 2.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

* assign event handlers in the application class to each desired event
SET HANDLER g_application->handle_node_double_click FOR g_tree.

* add nodes to the tree model
PERFORM add_nodes.

* expand the root node
CALL METHOD g_tree->expand_node
EXPORTING
node_key       = ‘PP’                                 “#EC NOTEXT
EXCEPTIONS

node_not_found = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.
ENDFORM.
*&———————————————————————*
*& Form add_nodes
*&———————————————————————*
*& text
*&———————————————————————*
*& –>  p1        text
*& <–  p2        text
*&———————————————————————*
FORM add_nodes .
* Node with key ‘Root’
CALL METHOD g_tree->add_node
EXPORTING
node_key = ‘PP’                                       “#EC NOTEXT
isfolder = ‘X’
text     = ‘Quality Management’                       “#EC NOTEXT
EXCEPTIONS
OTHERS   = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

*————————— Vendor Sampling ————————*
CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘Vendor Sampling1’                             “#EC NOTEXT
relative_node_key = ‘PP’
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘X’
text              = ‘Vendor Sampling’
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

* Node with key Vendor Sampling
CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘Vendor Sampling’
relative_node_key = ‘Vendor Sampling1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Create Vendor Sampling Inspection’

“#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘FVNSMPL’
relative_node_key = ‘Vendor Sampling1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Print Form’           “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘VNSMPL’
relative_node_key = ‘Vendor Sampling1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Report’           “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

*&———->Trim Audit Inspection
CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_TRIM1’                             “#EC NOTEXT
relative_node_key = ‘PP’
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘X’
text              = ‘Trim Audit Inspection’
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.

ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_TRIM’
relative_node_key = ‘ZQM_TRIM1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Create Trim Audit Inspection’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZTRIMAUDIT’
relative_node_key = ‘ZQM_TRIM1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Report’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_TRIMADOBE’
relative_node_key = ‘ZQM_TRIM1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Print Form’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

*&————->  Outsource Goods Inspection
CALL METHOD g_tree->add_node
EXPORTING

node_key          = ‘ZQM_OUTSOURCE1’                             “#EC NOTEXT
relative_node_key = ‘PP’
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘X’
text              = ‘Outsource Goods Inspection’
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_OUTSOURCE’
relative_node_key = ‘ZQM_OUTSOURCE1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Create Outsource Goods Inspection’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_INSPECTION’
relative_node_key = ‘ZQM_OUTSOURCE1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Report’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZFOUTSOURCE’
relative_node_key = ‘ZQM_OUTSOURCE1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Print Form’

C NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

*&————->Finished Goods Inspection
CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_FG_FINAL1’                             “#EC NOTEXT
relative_node_key = ‘PP’
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘X’
text              = ‘Finished Goods Inspection
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_FG_FINAL’
relative_node_key = ‘ZQM_FG_FINAL1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Create Finished Goods Inspection’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_FINISHGOODS’
relative_node_key = ‘ZQM_FG_FINAL1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Report’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.

CALL METHOD g_tree->add_node
EXPORTING
node_key          = ‘ZQM_FINAL_INS’
relative_node_key = ‘ZQM_FG_FINAL1’                             “#EC NOTEXT
relationship      = cl_simple_tree_model=>relat_last_child
isfolder          = ‘ ‘
image             = ‘@0Y@’
text              = ‘Print Form’            “#EC NOTEXT
EXCEPTIONS
OTHERS            = 1.
IF sy-subrc <> 0.
**    MESSAGE a001.
ENDIF.
ENDFORM.

Output:


SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Guides, SAP ABAP Learning

Monday, 28 August 2023

Tutorial. How to create custom PIVB ALV report based on a CDS with parameters

This post is about a simple tutorial how to create own ALV PIVB report based on data from own custom CDS with input parameters.

What is PIVB reports?


PIVB reports allows you to generate reports (totals or items report) and add analytics (i.e. columns) to the report on the fly. While adding columns – system recalculates the data in the report, i.e. the number of rows may changes. In simple words, it works in the same way as the PivotTable mechanism in MS Excel. For example, you can see standard SAP reports such as FAGLL03H, FBL1H, etc.

These reports can be identified by the presence of a sidebar on the right (it can be moved to the left), and the new layout mechanism for working with reports, which allows you to generate a set of columns on the fly (ad-hoc).

An example of a report (FAGLL03h):

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

How to create own PIVB report


Here’s a simple step-by-step guide how to create a PIVB report

CDS with data

You need a table or CDS with data for the report. In the example below, I will use Z CDS (based on ACDOCA) with input parameters (fiscal year and start date):

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

Create a custom report

Create a custom program for the report (for example, you can use the RFPIVB_EX_SFLIGHT_01 report as a reference). In the program, specify selection screen:

REPORT zfi_glrep_items_pivb.
TABLES: zvfi_acdoc_i.

SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE TEXT-001.
  SELECT-OPTIONS: so_rldnr FOR zvfi_acdoc_i-rldnr NO INTERVALS DEFAULT '0L',
                  so_bukrs FOR zvfi_acdoc_i-rbukrs MEMORY ID buk,
                  so_gjahr FOR zvfi_acdoc_i-gjahr OBLIGATORY no-EXTENSION NO INTERVALS DEFAULT sy-datum+0(4),
                  so_budat FOR zvfi_acdoc_i-budat OBLIGATORY NO-EXTENSION,
                  so_racct FOR zvfi_acdoc_i-racct,
                  so_KTOKS FOR zvfi_acdoc_i-ktoks,
                  so_LOKKT FOR zvfi_acdoc_i-lokkt,
                  so_koart FOR zvfi_acdoc_i-koart.
SELECTION-SCREEN END OF BLOCK bl1.

SELECTION-SCREEN BEGIN OF BLOCK bl2 WITH FRAME TITLE TEXT-002.
  PARAMETERS: p_sb AS CHECKBOX.
  PARAMETERS: p_disvar TYPE  slis_vari MODIF ID p_d.
SELECTION-SCREEN END OF BLOCK bl2.

Add processing of the layouts (field P_DISVAR) search help:

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_disvar.
* service FM PIVB_F4
  CALL FUNCTION 'PIVB_F4'
    EXPORTING
      i_report_catalog  = con_catalog
      i_report_scenario = con_scenario
    IMPORTING
      e_layout          = p_disvar
      e_result_status   = g_result_status
      e_layout_name     = g_layout_name
    CHANGING
      ct_field          = gt_column
    EXCEPTIONS
      error_message     = 4.
  IF sy-subrc = 4.
    "Do nothing, same error will be also raised during execution
    "(and is not possible raise messages in F4 Help event)
  ENDIF.

* update screen with description of the selected layout
  IF g_result_status = if_pivb_c_f4=>result_field.
    MESSAGE i014(pivb) INTO g_txt.
    g_layout_name = g_txt.
    MESSAGE i013(pivb) INTO g_txt.
    PERFORM update_screen.
  ELSEIF g_result_status = if_pivb_c_f4=>result_layout.
    MESSAGE i012(pivb) INTO g_txt.
    PERFORM update_screen.
  ENDIF.


FORM update_screen.
  DATA:
    ls_dynpfield TYPE dynpread,
    lt_dynpfield TYPE TABLE OF dynpread.

  CLEAR: lt_dynpfield[], ls_dynpfield.

  ls_dynpfield-fieldname = 'P_DISVAR'.
  ls_dynpfield-fieldvalue = p_disvar.
  APPEND ls_dynpfield TO lt_dynpfield.

  CALL FUNCTION 'DYNP_VALUES_UPDATE'
    EXPORTING
      dyname     = sy-repid
      dynumb     = sy-dynnr
    TABLES
      dynpfields = lt_dynpfield.
ENDFORM.

PIVB ALV layouts search help, with ad-hoc functionality, looks like:

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

And at the main part of the report – add a transfer data from the selection screen to the PIVB functionality (via FM PIVB_CONV_RANGE_TO_SELTAB)

* convert the entered values into standard PIVB format
  PERFORM convert_to_seltab USING 'RBUKRS' so_bukrs[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'RLDNR' so_rldnr[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'BUDAT' so_budat[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'RACCT' so_racct[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'KTOKS' so_KTOKS[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'LOKKT' so_LOKKT[]  CHANGING gt_seltab.
  PERFORM convert_to_seltab USING 'KOART' so_koart[]  CHANGING gt_seltab.

FORM convert_to_seltab USING
                         us_fname   TYPE rsdstabs-prim_fname
                         fs_table   TYPE ANY TABLE
                       CHANGING
                         ct_seltab  TYPE rsds_frange_t.
  CALL FUNCTION 'PIVB_CONV_RANGE_TO_SELTAB'
    EXPORTING
      i_fname   = us_fname
      it_table  = fs_table
    CHANGING
      ct_seltab = ct_seltab.
ENDFORM.

Let’s declare constants with the name of the report, they will need to be registered in the PIVB customizing tables and in the BAdI PIVB implementation, it will be further at post

CONSTANTS con_catalog         TYPE pivb_report_catalog  VALUE 'ZVFI_ACDOC_I'.
CONSTANTS con_scenario        TYPE pivb_report_scenario VALUE 'ZVFI'.

And call the main FM PIVB_CONV_RANGE_TO_SELTAB to retrieve data and show the PIVB ALV report

* call the main PIVB FM with all necessary parameters
  CALL FUNCTION 'PIVB_SELECT_AND_DISPLAY'
    EXPORTING
      i_report_catalog     = con_catalog
      i_report_scenario    = con_scenario
      it_seltab            = gt_seltab
      i_layout             = p_disvar
      it_column_visibility = gt_column
      it_param             = lt_par.

Thats it with the report. But, also, customizing and PIVB BAdI implementation needed.

Customizing

There are 4 main customizing tables:

◉ PIVB_CATALOG Report catalogs
◉ PIVB_FEATURE Pivot Browser features
◉ PIVB_FIELD Fieldcatalog data
◉ PIVB_FIELDMAP Field Mapping

For a simple example, it is enough to define our report only in PIVB_CATALOG (via SM30):

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

Implement PIVB BAdI


Next, let’s create an implementation of the PIVB enhancement point (se18/19), there is a standard template of implementation – SAP_SFLIGHT_01. Let’s create own implementation and specify the values from PIVB_CATALOG customizing into the BAdI implementation filter:

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

For a simple report, it’s only need to implement the IF_EX_PIVB~SELECT method in which I override the data selection mechanism for example, it will be like this:

method if_ex_pivb~select.
  data lt_trange                  type rsds_trange.
  data lt_trange_and              type pivb_trange_t.
  data lt_select                  type standard table of string.
  data lt_group_by                type standard table of string.
  data lt_group_by_checked        type standard table of string.
  data lt_field_mapping           type pivb_fieldmap_short_t.
  data l_column                   type string.
  data l_tabname                  type tabname.
  data oref                       type ref to cx_root.
  data lt_where                   type rsds_where_tab.
  field-symbols <fs_item>         type any.
  constants lc_tabname            type tabname  value 'ZVFI_ACDOC_I'.
  constants lc_devclass           type devclass value 'ZFI_DEV'. "package of the table

  me->get_security_metadata( i_report_catalog = i_report_catalog ).

  call function 'PIVB_SQL_GET_CLAUSE'
    exporting
      i_report_catalog            = i_report_catalog
      i_report_scenario           = i_report_scenario
      it_seltab                   = it_seltab
      it_and_seltab               = it_and_seltab
      it_column                   = it_column
      it_column_metadata          = it_column_metadata
      i_tabname                   = lc_tabname
      it_table_sec                = me->mt_secure_whitelist
      ut_fieldmap                 = lt_field_mapping
      I_STRICT_MODE               = 'X'
    importing
      et_select                   = lt_select
      et_group_by                 = lt_group_by
      et_trange                   = lt_trange[]
      et_trange_and               = lt_trange_and[].

  LOOP AT lt_select ASSIGNING FIELD-SYMBOL(<sel>).
    CHECK <sel>+0(4) = 'SUM('.
    REPLACE '(' in <sel> WITH `( `.
    REPLACE ')' in <sel> WITH ' )'.
  ENDLOOP.

**********************************************************************
  call function 'PIVB_CONV_RANGE_TO_WHERE'
    exporting
      it_trange           = lt_trange[]
      it_trange_and       = lt_trange_and[]
    importing
      et_where            = lt_where[].

* GROUP BY
  loop at lt_group_by into l_column.
    append l_column to lt_group_by_checked.
  endloop.
  free lt_group_by.

* DO SELECT
***********************************************************************
  DATA: st_date TYPE dats,
        fy TYPE gjahr.
  LOOP AT CT_PARAM ASSIGNING FIELD-SYMBOL(<fs_p>).
    CASE <fs_p>-PARAMNAME.
      WHEN 'ST_DATE'.
        st_date = <fs_p>-CUSTOM.
      WHEN 'FY'.
        fy = <fs_p>-CUSTOM.
      WHEN OTHERS.
    ENDCASE.
  ENDLOOP.
  try.
    select (lt_select)
      from ZVFI_ACDOC_ITEMS( st_date = @st_date,
                             fy = @fy )
      where (lt_where)
      group by (lt_group_by_checked)
      into corresponding fields of TABLE @ct_outtab.
  catch cx_sy_open_sql_db into oref.
    data: l_txt type string.
    l_txt = oref->get_text( ) ##MG_MISSING.
    message e017(pivb) with lc_tabname l_txt space space raising sql_error.
  endtry ##MG_MISSING.
endmethod.

Please note that to use the new query syntax, you need to set the parameter I_STRICT_MODE = ‘X’ and slightly adjust the functionality for filling the internal table lt_select (add spaces to the dynamic parameters of the query).

In the IF_EX_PIVB~GRID_METADATA_CHANGE method, you can change the ALV display parameters (fieldcatalog), for example, set own column header texts, colors, display options, as follows:

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning

Activate the implementation of the enhancement, activate report etc. Everything done!

How it works


Adding columns to PIVB report:

SAP ABAP Certification, SAP ABAP Certification, SAP ABAP Career, SAP ABAP Skills, SAP ABAP Job, SAP ABAP Learning