From 60f1ab8a5aedbf0c0b61fa436cf942c692bf013f Mon Sep 17 00:00:00 2001 From: Christopher Graw <119762644+Developer-101-c@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:06:17 +0100 Subject: [PATCH] Added Navigation via ABAP OO Methods (#4) --- CHANGELOG.md | 5 + src/zc_cds_alv_extensionheaders.ddls.asddls | 17 +- ...zc_cds_alv_extensionparameters.ddls.asddls | 14 +- src/zc_cds_alv_navigation.ddls.asddls | 29 +- src/zc_cds_alv_parameters.ddls.asddls | 13 +- src/zc_cds_alv_programextensions.ddls.asddls | 21 ++ src/zc_cds_alv_programextensions.ddls.xml | 12 + src/zc_cds_alv_programs.ddls.asddls | 25 +- src/zc_cds_alv_selectoptions.ddls.asddls | 17 +- src/zcds_alv.msag.xml | 44 +++ src/zcds_alv_n.nrob.xml | 6 +- src/zcds_alv_nav.tabl.xml | 100 +++++++ src/zcds_alv_tables.fugr.xml | 138 +++++++++- src/zcl_cds_alv_base.clas.abap | 11 +- src/zcl_cds_alv_grid_builder.clas.abap | 3 +- src/zcl_cds_alv_navigation.clas.abap | 260 +++++++++++++++--- src/zcl_cds_alv_navigation.clas.xml | 20 ++ src/zi_cds_alv_extensionheaders.ddls.asddls | 13 +- ...zi_cds_alv_extensionheadertext.ddls.asddls | 11 +- ...zi_cds_alv_extensionparameters.ddls.asddls | 7 +- ...zi_cds_alv_extensionparamtexts.ddls.asddls | 7 +- src/zi_cds_alv_navigation.ddls.asddls | 22 +- src/zi_cds_alv_parameters.ddls.asddls | 9 +- src/zi_cds_alv_programextensions.ddls.asddls | 9 +- src/zi_cds_alv_programs.ddls.asddls | 21 +- src/zi_cds_alv_selectoptions.ddls.asddls | 9 +- 26 files changed, 716 insertions(+), 127 deletions(-) create mode 100644 src/zc_cds_alv_programextensions.ddls.asddls create mode 100644 src/zc_cds_alv_programextensions.ddls.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f5363..90e811b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +v 1.1.0 + +- Added Implementation of Intent-Based Navigation via ABAP OO methods. +- Added missing CDS Views and associations for the Report Extension Tables. + v 1.0.3 - Fixed an error in evaluating annotation UI.lineItem.semanticObject in the grid builder class. diff --git a/src/zc_cds_alv_extensionheaders.ddls.asddls b/src/zc_cds_alv_extensionheaders.ddls.asddls index 3db57d4..ecb6300 100644 --- a/src/zc_cds_alv_extensionheaders.ddls.asddls +++ b/src/zc_cds_alv_extensionheaders.ddls.asddls @@ -4,14 +4,27 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Erweiterungen von Reports für CDS-Views' @VDM.viewType: #CONSUMPTION -define view ZC_CDS_ALV_ExtensionHeaders as select from ZI_CDS_ALV_ExtensionHeaders { +define view ZC_CDS_ALV_ExtensionHeaders as select from ZI_CDS_ALV_ExtensionHeaders +association[0..*] to ZC_CDS_ALV_ExtensionParameters as _Parameters on _Parameters.ExtensionName = $projection.ExtensionName +{ + @Consumption.filter.selectionType: #RANGE + @UI.lineItem: [{ position: 10 }] key ExtensionName, + @Consumption.filter.selectionType: #SINGLE + @UI.lineItem: [{ position: 40 }] AlternativeSelection, + @Consumption.filter.selectionType: #SINGLE + @UI.lineItem: [{ position: 60 }] AlternativeDisplay, + @Consumption.semanticObject: 'AbapClass' + @UI.lineItem: [{ position: 30, type: #WITH_INTENT_BASED_NAVIGATION, semanticObjectAction: 'CallEditor' }] ImplementingClass, + @UI.lineItem: [{ position: 20 }] _Text[ 1: Language = $session.system_language ].ExtensionText, + @UI.lineItem: [{ position: 50 }] _Text[ 1: Language = $session.system_language ].SelectionText, + @UI.lineItem: [{ position: 70 }] _Text[ 1: Language = $session.system_language ].DisplayText, /* Associations */ - _Text + _Parameters } diff --git a/src/zc_cds_alv_extensionparameters.ddls.asddls b/src/zc_cds_alv_extensionparameters.ddls.asddls index c898ebe..1d135f2 100644 --- a/src/zc_cds_alv_extensionparameters.ddls.asddls +++ b/src/zc_cds_alv_extensionparameters.ddls.asddls @@ -4,14 +4,24 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Parameter einer Programmerweiterung' @VDM.viewType: #CONSUMPTION -define view ZC_CDS_ALV_ExtensionParameters as select from ZI_CDS_ALV_ExtensionParameters { +define view ZC_CDS_ALV_ExtensionParameters as select from ZI_CDS_ALV_ExtensionParameters +association[1..1] to ZC_CDS_ALV_ExtensionHeaders as _Header on _Header.ExtensionName = $projection.ExtensionName +{ + @Consumption.filter.selectionType: #RANGE + @UI.lineItem: [{ position: 10 }] key ExtensionName, + @UI.lineItem: [{ position: 20 }] key ParameterName, + @UI.lineItem: [{ position: 40 }] DbField, + @UI.lineItem: [{ position: 50 }] HasValueHelp, + @UI.lineItem: [{ position: 60 }] HasHelp, + @UI.lineItem: [{ position: 70 }] AttributeName, + @UI.lineItem: [{ position: 30 }] _Text[ 1: Language = $session.system_language ].ParameterText as ParameterText, /* Associations */ - _Text + _Header } diff --git a/src/zc_cds_alv_navigation.ddls.asddls b/src/zc_cds_alv_navigation.ddls.asddls index 93e17a0..6c42262 100644 --- a/src/zc_cds_alv_navigation.ddls.asddls +++ b/src/zc_cds_alv_navigation.ddls.asddls @@ -5,13 +5,40 @@ @EndUserText.label: 'Intent-Based Navigation' @VDM.viewType: #CONSUMPTION define view ZC_CDS_ALV_Navigation as select from ZI_CDS_ALV_Navigation { + @Consumption.filter.selectionType: #RANGE + @UI.lineItem: [{ position: 10 }] key SemanticObject, + @Consumption.filter.selectionType: #RANGE + @UI.lineItem: [{ position: 20 }] key SemanticAction, + @Consumption.semanticObject: 'FunctionModule' + @UI.lineItem: [{ position: 30, type: #WITH_INTENT_BASED_NAVIGATION, semanticObjectAction: 'Display' }] Function, + @UI.lineItem: [{ position: 40 }] DefaultParameter, + @UI.lineItem: [{ position: 50 }] ConversionExit, + @Consumption.semanticObject: 'BusinessObject' + @UI.lineItem: [{ position: 60, type: #WITH_INTENT_BASED_NAVIGATION, semanticObjectAction: 'Display' }] ObjectType, + @UI.lineItem: [{ position: 70 }] ObjectMethod, + @Consumption.semanticObject: 'TransactionCode' + @UI.lineItem: [{ position: 80, type: #WITH_INTENT_BASED_NAVIGATION, semanticObjectAction: 'Display' }] TransactionCode, - ParameterId + @UI.lineItem: [{ position: 90 }] + ParameterId, + @Consumption.semanticObject: 'AbapClass' + @UI.lineItem: [{ position: 100, type: #WITH_INTENT_BASED_NAVIGATION, semanticObjectAction: 'CallEditor' }] + Class, + @UI.lineItem: [{ position: 110 }] + Method, + @UI.lineItem: [{ position: 120 }] + MethodParameter, + @Consumption.filter.selectionType: #SINGLE + @UI.lineItem: [{ position: 130 }] + MassProcessing, + @Consumption.filter.selectionType: #SINGLE + @UI.lineItem: [{ position: 140 }] + RefreshAfter } diff --git a/src/zc_cds_alv_parameters.ddls.asddls b/src/zc_cds_alv_parameters.ddls.asddls index 511b29e..41a1975 100644 --- a/src/zc_cds_alv_parameters.ddls.asddls +++ b/src/zc_cds_alv_parameters.ddls.asddls @@ -4,9 +4,18 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'PARAMETERS der generierten Programme für CDS-Views' @VDM.viewType: #CONSUMPTION -define view ZC_CDS_ALV_Parameters as select from ZI_CDS_ALV_Parameters { +define view ZC_CDS_ALV_Parameters as select from ZI_CDS_ALV_Parameters +association[1..1] to ZC_CDS_ALV_Programs as _Program on _Program.ProgramName = $projection.ProgramName +{ + @UI.lineItem: [{ position: 10 }] key ProgramName, + @UI.lineItem: [{ position: 20 }] key SelectionName, + @Consumption.filter.selectionType: #RANGE + @Consumption.semanticObject: 'CDSView' + @UI.lineItem: [{ position: 30 }, { type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'ShowContent', label: 'Start Report' }] CdsView, - ParameterName + @UI.lineItem: [{ position: 40 }] + ParameterName, + _Program } diff --git a/src/zc_cds_alv_programextensions.ddls.asddls b/src/zc_cds_alv_programextensions.ddls.asddls new file mode 100644 index 0000000..7e666f8 --- /dev/null +++ b/src/zc_cds_alv_programextensions.ddls.asddls @@ -0,0 +1,21 @@ +@AbapCatalog.sqlViewName: 'ZCCDSALVPROGEXT' +@AbapCatalog.compiler.compareFilter: true +@AbapCatalog.preserveKey: true +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Program Extensions for a CDS View' +@VDM.viewType: #CONSUMPTION +define view ZC_CDS_ALV_ProgramExtensions as select from ZI_CDS_ALV_ProgramExtensions +association[1..1] to ZC_CDS_ALV_Programs as _Program on _Program.CdsView = $projection.CdsView +{ + @Consumption.filter.selectionType: #RANGE + @Consumption.semanticObject: 'CDSView' + @UI.lineItem: [{ position: 10 }, { type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'ShowContent', label: 'Start Report' }] + key CdsView, + @Consumption.filter.selectionType: #RANGE + @UI.lineItem: [{ position: 20 }] + key ExtensionName, + @UI.lineItem: [{ position: 30 }] + Active, + /* Associations */ + _Program +} diff --git a/src/zc_cds_alv_programextensions.ddls.xml b/src/zc_cds_alv_programextensions.ddls.xml new file mode 100644 index 0000000..1dab00f --- /dev/null +++ b/src/zc_cds_alv_programextensions.ddls.xml @@ -0,0 +1,12 @@ + + + + + + ZC_CDS_ALV_PROGRAMEXTENSIONS + E + Program Extensions for a CDS View + + + + diff --git a/src/zc_cds_alv_programs.ddls.asddls b/src/zc_cds_alv_programs.ddls.asddls index d601d5c..778af3e 100644 --- a/src/zc_cds_alv_programs.ddls.asddls +++ b/src/zc_cds_alv_programs.ddls.asddls @@ -3,17 +3,26 @@ @AbapCatalog.preserveKey: true @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Programme zur Anzeige von CDS-Views' -define view ZC_CDS_ALV_Programs as select from ZI_CDS_ALV_Programs { - @UI.lineItem: [{ position: 1 }] +define view ZC_CDS_ALV_Programs as select from ZI_CDS_ALV_Programs +association[0..*] to ZC_CDS_ALV_Parameters as _Parameters on _Parameters.ProgramName = $projection.ProgramName +association[0..*] to ZC_CDS_ALV_SelectOptions as _SelectOptions on _SelectOptions.ProgramName = $projection.ProgramName +association[0..*] to ZC_CDS_ALV_ProgramExtensions as _Extensions on _Extensions.CdsView = $projection.CdsView +{ + @Consumption.filter.selectionType: #RANGE + @Consumption.semanticObject: 'CDSView' + @UI.lineItem: [{ position: 10 }, { type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'ShowContent', label: 'Start Report' }] key CdsView, - @UI.lineItem: [{ position: 2 }] + @UI.lineItem: [{ position: 20 }] ProgramName, - @UI.lineItem: [{ position: 3 }] + @UI.lineItem: [{ position: 30 }] SelectionScreen, - @UI.lineItem: [{ position: 4 }] + @UI.lineItem: [{ position: 40 }] Author, - @UI.lineItem: [{ position: 5 }] + @UI.lineItem: [{ position: 50 }] GeneratedAt, - @UI.lineItem: [{ position: 6 }] - NoGeneration + @UI.lineItem: [{ position: 60 }] + NoGeneration, + _Parameters, + _SelectOptions, + _Extensions } diff --git a/src/zc_cds_alv_selectoptions.ddls.asddls b/src/zc_cds_alv_selectoptions.ddls.asddls index 925230f..5fcca20 100644 --- a/src/zc_cds_alv_selectoptions.ddls.asddls +++ b/src/zc_cds_alv_selectoptions.ddls.asddls @@ -4,13 +4,18 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'SELECT-OPTIONS der generierten Programme für CDS-Views' @VDM.viewType: #CONSUMPTION -define view ZC_CDS_ALV_SelectOptions as select from ZI_CDS_ALV_SelectOptions { - @UI.lineItem: [{ position: 1 }] +define view ZC_CDS_ALV_SelectOptions as select from ZI_CDS_ALV_SelectOptions +association[1..1] to ZC_CDS_ALV_Programs as _Program on _Program.ProgramName = $projection.ProgramName +{ + @UI.lineItem: [{ position: 10 }] key ProgramName, - @UI.lineItem: [{ position: 2 }] + @UI.lineItem: [{ position: 20 }] key SelectionName, - @UI.lineItem: [{ position: 3 }] + @Consumption.filter.selectionType: #RANGE + @Consumption.semanticObject: 'CDSView' + @UI.lineItem: [{ position: 30 }, { type: #FOR_INTENT_BASED_NAVIGATION, semanticObjectAction: 'ShowContent', label: 'Start Report' }] CdsView, - @UI.lineItem: [{ position: 4 }] - FieldName + @UI.lineItem: [{ position: 40 }] + FieldName, + _Program } diff --git a/src/zcds_alv.msag.xml b/src/zcds_alv.msag.xml index 34f77cf..1a79562 100644 --- a/src/zcds_alv.msag.xml +++ b/src/zcds_alv.msag.xml @@ -200,6 +200,30 @@ 032 Empty receiver list &1. + + E + ZCDS_ALV + 033 + Invalid importing parameter &1 for class &2, method &3. + + + E + ZCDS_ALV + 034 + Error occurred in class &1, method &2. + + + E + ZCDS_ALV + 035 + Invalid method &2 in class &1. + + + E + ZCDS_ALV + 036 + Error occurred while creating an instance of class &1. + D @@ -372,6 +396,26 @@ 032 Leere Empfängerliste &1 + + D + 033 + Ungültiger Parameter &1 für Klasse &2, Methode &3. + + + D + 034 + Fehler aufgetreten in Klasse &1, Methode &2. + + + D + 035 + Ungültige Methode &2 für Klasse &1. + + + D + 036 + Fehler aufgetreten bei Instanzerzeugung für Klasse &1. + diff --git a/src/zcds_alv_n.nrob.xml b/src/zcds_alv_n.nrob.xml index 0ee6e32..1a9d970 100644 --- a/src/zcds_alv_n.nrob.xml +++ b/src/zcds_alv_n.nrob.xml @@ -10,10 +10,10 @@ 00000010 - D + E ZCDS_ALV_N - CDS ALV: Laufende Nummer für generierte Programme - CDS ALV + Number Range for generated Reports + Report Number diff --git a/src/zcds_alv_nav.tabl.xml b/src/zcds_alv_nav.tabl.xml index f16ee78..0d08e64 100644 --- a/src/zcds_alv_nav.tabl.xml +++ b/src/zcds_alv_nav.tabl.xml @@ -86,6 +86,26 @@ P E + + CLASS + SEOCLSNAME + 0 + X + E + + + METHOD + SEOMTDNAME + 0 + X + E + + + METHOD_PARAMETER + SEOSCONAME + 0 + E + MASS_PROCESSING ZCDS_ALV_NAV_MASS_PROCESSING @@ -168,6 +188,86 @@ REF + + + CLASS + SEO_CLASSES_INTERFACES + + + METHOD + OO_METHOD_F4 + + + + + CLASS + SEO_CLASSES_INTERFACES + LANGUAGE + 0002 + G + X + SPRAS + SPRAS + LANG + 000001 + SY-LANGU + S + + + CLASS + SEO_CLASSES_INTERFACES + NAME + 0001 + ZCDS_ALV_NAV + CLASS + X + X + SEOCLSNAME + SEOCLSNAME + CHAR + 000030 + + + METHOD + OO_METHOD_F4 + CLSNAME + 0001 + ZCDS_ALV_NAV + CLASS + X + X + SEOCLSNAME + SEOCLSNAME + CHAR + 000030 + + + METHOD + OO_METHOD_F4 + DESCR + 0004 + G + X + SEODESCR + AS4TEXT + CHAR + 000060 + + + METHOD + OO_METHOD_F4 + MTDNAME + 0002 + ZCDS_ALV_NAV + METHOD + X + X + SEOMTDNAME + CHAR61 + CHAR + 000061 + + D diff --git a/src/zcds_alv_tables.fugr.xml b/src/zcds_alv_tables.fugr.xml index 0102f78..79a292c 100644 --- a/src/zcds_alv_tables.fugr.xml +++ b/src/zcds_alv_tables.fugr.xml @@ -277,7 +277,7 @@ N 0001 061 - 246 + 247 @@ -456,14 +456,15 @@ TCTRL_ZCDS_ALV_NAV TEXT *ZCDS_ALV_NAV-OBJECT_TYPE + BOR_Object_Type_____________________________ 001 006 - 040 + 044 015 001 CHAR X - 2 + F N X @@ -472,14 +473,15 @@ TCTRL_ZCDS_ALV_NAV TEXT *ZCDS_ALV_NAV-OBJECT_METHOD + BOR_Method__________________________________ 001 007 - 040 - 032 + 044 + 010 001 CHAR X - V + F N X @@ -519,14 +521,65 @@ TABLE_CTRL TCTRL_ZCDS_ALV_NAV TEXT - *ZCDS_ALV_NAV-MASS_PROCESSING + ZCDS_ALV_NAV-CLASS + Class____ 001 010 - 040 + 009 + 020 + 001 + CHAR + X + F + N + X + + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEXT + ZCDS_ALV_NAV-METHOD + Method________ + 001 + 011 + 014 + 020 + 001 + CHAR + X + F + N + X + + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEXT + ZCDS_ALV_NAV-METHOD_PARAMETER + Method_Parameter + 001 + 012 + 016 030 001 CHAR X + F + N + X + + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEXT + *ZCDS_ALV_NAV-MASS_PROCESSING + 001 + 013 + 040 + 020 + 001 + CHAR + X 1 N X @@ -537,7 +590,7 @@ TEXT *ZCDS_ALV_NAV-REFRESH_AFTER 001 - 011 + 014 020 010 001 @@ -682,10 +735,11 @@ TEMPLATE ZCDS_ALV_NAV-OBJECT_METHOD ________________________________ + X 001 007 032 - 032 + 010 001 CHAR X @@ -731,6 +785,55 @@ X X + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEMPLATE + ZCDS_ALV_NAV-CLASS + X + 001 + 010 + 030 + 020 + 001 + CHAR + X + CLASS + X + X + + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEMPLATE + ZCDS_ALV_NAV-METHOD + X + 001 + 011 + 061 + 020 + 001 + CHAR + X + MTDNAME + X + X + + + TABLE_CTRL + TCTRL_ZCDS_ALV_NAV + TEMPLATE + ZCDS_ALV_NAV-METHOD_PARAMETER + 001 + 012 + 030 + 030 + 001 + CHAR + X + X + X + TABLE_CTRL TCTRL_ZCDS_ALV_NAV @@ -739,9 +842,9 @@ _ L 001 - 010 + 013 001 - 030 + 020 001 CHAR X @@ -756,7 +859,7 @@ CHECK ZCDS_ALV_NAV-REFRESH_AFTER 001 - 011 + 014 001 010 001 @@ -834,6 +937,15 @@ FIELD ZCDS_ALV_NAV-PARAMETER_ID . + + FIELD ZCDS_ALV_NAV-CLASS . + + + FIELD ZCDS_ALV_NAV-METHOD . + + + FIELD ZCDS_ALV_NAV-METHOD_PARAMETER . + FIELD ZCDS_ALV_NAV-MASS_PROCESSING . diff --git a/src/zcl_cds_alv_base.clas.abap b/src/zcl_cds_alv_base.clas.abap index 7db891b..49aec3b 100644 --- a/src/zcl_cds_alv_base.clas.abap +++ b/src/zcl_cds_alv_base.clas.abap @@ -20,11 +20,11 @@ CLASS zcl_cds_alv_base DEFINITION PUBLIC ABSTRACT CREATE PUBLIC. with_url TYPE zcds_alv_field_type VALUE '#WITH_URL', END OF field_type. - DATA description TYPE ddtext . - DATA ddfields TYPE ddfields . - DATA parameter_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_para_anno_val_src_dtel . - DATA element_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_elmnt_anno_val_src_dtel . - DATA entity_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_anno_value . + DATA description TYPE ddtext. + DATA ddfields TYPE ddfields. + DATA parameter_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_para_anno_val_src_dtel. + DATA element_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_elmnt_anno_val_src_dtel. + DATA entity_annotations TYPE cl_dd_ddl_annotation_service=>ty_t_anno_value. DATA ddic_access TYPE REF TO zif_cds_alv_ddic_access. DATA persistence TYPE REF TO zif_cds_alv_persistence. DATA memory TYPE REF TO zif_cds_alv_memory. @@ -39,6 +39,7 @@ CLASS zcl_cds_alv_base DEFINITION PUBLIC ABSTRACT CREATE PUBLIC. i_string TYPE clike RETURNING VALUE(r_string) TYPE string. + PRIVATE SECTION. ENDCLASS. diff --git a/src/zcl_cds_alv_grid_builder.clas.abap b/src/zcl_cds_alv_grid_builder.clas.abap index 01f8cb9..1cff9df 100644 --- a/src/zcl_cds_alv_grid_builder.clas.abap +++ b/src/zcl_cds_alv_grid_builder.clas.abap @@ -79,12 +79,11 @@ CLASS zcl_cds_alv_grid_builder DEFINITION PUBLIC CREATE PUBLIC INHERITING FROM z DATA delete_enabled TYPE xsdboolean. METHODS sort_columns. - ENDCLASS. -CLASS zcl_cds_alv_grid_builder IMPLEMENTATION. +CLASS ZCL_CDS_ALV_GRID_BUILDER IMPLEMENTATION. METHOD build_event_handler. DATA(event_handler) = NEW zcl_cds_alv_grid_event_handler( i_cds_view = cds_view i_alv_grid = alv_grid diff --git a/src/zcl_cds_alv_navigation.clas.abap b/src/zcl_cds_alv_navigation.clas.abap index 2ff3fb0..6ed8a1a 100644 --- a/src/zcl_cds_alv_navigation.clas.abap +++ b/src/zcl_cds_alv_navigation.clas.abap @@ -9,57 +9,74 @@ CLASS zcl_cds_alv_navigation DEFINITION PUBLIC CREATE PUBLIC. PROTECTED SECTION. - PRIVATE SECTION. - CONSTANTS: BEGIN OF mass_processing, +private section. + + constants: + BEGIN OF mass_processing, none TYPE zcds_alv_nav_mass_processing VALUE space, loop TYPE zcds_alv_nav_mass_processing VALUE 'L', table TYPE zcds_alv_nav_mass_processing VALUE 'T', - END OF mass_processing. - - CONSTANTS exit_interface TYPE seoitfname VALUE 'ZIF_CDS_ALV_NAVIGATION'. - - DATA persistence TYPE REF TO zif_cds_alv_persistence. - DATA ddic_access TYPE REF TO zif_cds_alv_ddic_access. - DATA launcher TYPE REF TO zif_cds_alv_report_launcher. - DATA ioc_container TYPE REF TO zif_cds_alv_ioc_container. - DATA navigation_table TYPE zcds_alv_navigation_tab. - DATA navigation_exits TYPE zcds_alv_navigation_exit_tab. - - METHODS ask_for_missing_parameters - IMPORTING i_target_view TYPE ddstrucobjname - CHANGING c_parameter_values TYPE zcds_alv_parameters - RAISING zcx_cds_alv_message. - - METHODS call_bor_method - IMPORTING i_navigation TYPE zcds_alv_nav - i_key_field TYPE fieldname - i_selected_row TYPE any - RAISING zcx_cds_alv_message. - - METHODS call_function_module - IMPORTING i_navigation TYPE zcds_alv_nav - i_key_field TYPE fieldname OPTIONAL - i_selected_row TYPE any OPTIONAL - i_selected_rows TYPE STANDARD TABLE OPTIONAL - RAISING zcx_cds_alv_message. - - METHODS call_transaction - IMPORTING i_navigation TYPE zcds_alv_nav - i_key_field TYPE fieldname - i_selected_row TYPE any - RAISING zcx_cds_alv_message. - - METHODS fill_ioc_container. - - METHODS get_object_from_ioc_container - IMPORTING i_navigation_exit TYPE zcds_alv_navexit - RETURNING VALUE(r_object) TYPE REF TO zif_cds_alv_navigation - RAISING zcx_cds_alv_message. + END OF mass_processing . + constants EXIT_INTERFACE type SEOITFNAME value 'ZIF_CDS_ALV_NAVIGATION' ##NO_TEXT. + data PERSISTENCE type ref to ZIF_CDS_ALV_PERSISTENCE . + data DDIC_ACCESS type ref to ZIF_CDS_ALV_DDIC_ACCESS . + data LAUNCHER type ref to ZIF_CDS_ALV_REPORT_LAUNCHER . + data IOC_CONTAINER type ref to ZIF_CDS_ALV_IOC_CONTAINER . + data NAVIGATION_TABLE type ZCDS_ALV_NAVIGATION_TAB . + data NAVIGATION_EXITS type ZCDS_ALV_NAVIGATION_EXIT_TAB . + + methods ASK_FOR_MISSING_PARAMETERS + importing + !I_TARGET_VIEW type DDSTRUCOBJNAME + changing + !C_PARAMETER_VALUES type ZCDS_ALV_PARAMETERS + raising + ZCX_CDS_ALV_MESSAGE . + methods CALL_BOR_METHOD + importing + !I_NAVIGATION type ZCDS_ALV_NAV + !I_KEY_FIELD type FIELDNAME + !I_SELECTED_ROW type ANY + raising + ZCX_CDS_ALV_MESSAGE . + methods CALL_FUNCTION_MODULE + importing + !I_NAVIGATION type ZCDS_ALV_NAV + !I_KEY_FIELD type FIELDNAME optional + !I_SELECTED_ROW type ANY optional + !I_SELECTED_ROWS type STANDARD TABLE optional + raising + ZCX_CDS_ALV_MESSAGE . + methods CALL_TRANSACTION + importing + !I_NAVIGATION type ZCDS_ALV_NAV + !I_KEY_FIELD type FIELDNAME + !I_SELECTED_ROW type ANY + raising + ZCX_CDS_ALV_MESSAGE . + methods CALL_OO_METHOD + importing + !I_NAVIGATION type ZCDS_ALV_NAV + !I_KEY_FIELD type FIELDNAME optional + !I_SELECTED_ROW type ANY optional + !I_SELECTED_ROWS type STANDARD TABLE optional + raising + ZCX_CDS_ALV_MESSAGE . + methods FILL_IOC_CONTAINER . + methods GET_OBJECT_FROM_IOC_CONTAINER + importing + !I_NAVIGATION_EXIT type ZCDS_ALV_NAVEXIT + returning + value(R_OBJECT) type ref to ZIF_CDS_ALV_NAVIGATION + raising + ZCX_CDS_ALV_MESSAGE . ENDCLASS. -CLASS zcl_cds_alv_navigation IMPLEMENTATION. +CLASS ZCL_CDS_ALV_NAVIGATION IMPLEMENTATION. + + METHOD ask_for_missing_parameters. DATA(dd10bv_tab) = ddic_access->get_parameters_for_cds_view( i_target_view ). @@ -104,6 +121,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDLOOP. ENDMETHOD. + METHOD call_bor_method. DATA objkey TYPE swo_typeid. DATA object TYPE swo_objhnd. @@ -145,6 +163,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDIF. ENDMETHOD. + METHOD call_function_module. DATA exceptions TYPE STANDARD TABLE OF rsexc. DATA exporting TYPE STANDARD TABLE OF rsexp. @@ -243,6 +262,132 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDIF. ENDMETHOD. + + METHOD call_oo_method. + DATA(class_descriptor) = CAST cl_abap_classdescr( cl_abap_typedescr=>describe_by_name( i_navigation-class ) ). + DATA(parameter_type_descriptor) = class_descriptor->get_method_parameter_type( p_method_name = i_navigation-method + p_parameter_name = i_navigation-method_parameter ). + + DATA input TYPE REF TO data. + CREATE DATA input TYPE HANDLE parameter_type_descriptor. + + IF input IS NOT BOUND. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE e033(zcds_alv) WITH i_navigation-method_parameter i_navigation-class i_navigation-method. + ENDIF. + + ASSIGN input->* TO FIELD-SYMBOL(). + + IF i_navigation-conversion_exit IS NOT INITIAL. + DATA(conversion_function) = |CONVERSION_EXIT_{ i_navigation-conversion_exit }_INPUT|. + ENDIF. + + IF i_selected_row IS NOT INITIAL. + ASSIGN COMPONENT i_key_field OF STRUCTURE i_selected_row TO FIELD-SYMBOL(). + = . + + IF conversion_function IS NOT INITIAL. + CALL FUNCTION conversion_function + EXPORTING + input = + IMPORTING + output = . + ENDIF. + + ELSEIF i_selected_rows IS NOT INITIAL. + FIELD-SYMBOLS TYPE ANY TABLE. + + LOOP AT i_selected_rows ASSIGNING FIELD-SYMBOL(). + ASSIGN COMPONENT i_key_field OF STRUCTURE TO . + ASSIGN TO
. + INSERT INTO TABLE
ASSIGNING FIELD-SYMBOL(). + + IF conversion_function IS NOT INITIAL. + CALL FUNCTION conversion_function + EXPORTING + input = + IMPORTING + output = . + ENDIF. + ENDLOOP. + ENDIF. + + READ TABLE class_descriptor->methods INTO DATA(method) WITH KEY name = i_navigation-method. + IF sy-subrc <> 0. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE e035(zcds_alv) WITH i_navigation-class i_navigation-method. + ENDIF. + + DATA(parameter_binding) = VALUE abap_parmbind_tab( + ( name = i_navigation-method_parameter + kind = cl_abap_objectdescr=>exporting + value = input ) ). + + IF method-is_raising_excps IS NOT INITIAL. + DATA(exception_binding) = VALUE abap_excpbind_tab( ( name = `OTHERS` value = 1 ) ). + ENDIF. + + TRY. + CASE method-is_class. + WHEN abap_true. + IF method-is_raising_excps IS NOT INITIAL. + CALL METHOD (i_navigation-class)=>(i_navigation-method) + PARAMETER-TABLE parameter_binding + EXCEPTION-TABLE exception_binding. + IF sy-subrc <> 0. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno + WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. + ENDIF. + ELSE. + TRY. + CALL METHOD (i_navigation-class)=>(i_navigation-method) + PARAMETER-TABLE parameter_binding. + + CATCH cx_root. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno + WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. + ENDTRY. + ENDIF. + + WHEN abap_false. + DATA instance TYPE REF TO object. + CREATE OBJECT instance TYPE (i_navigation-class). + + IF method-is_raising_excps IS NOT INITIAL. + CALL METHOD instance->(i_navigation-method) + PARAMETER-TABLE parameter_binding + EXCEPTION-TABLE exception_binding. + IF sy-subrc <> 0. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno + WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. + ENDIF. + ELSE. + TRY. + CALL METHOD instance->(i_navigation-method) + PARAMETER-TABLE parameter_binding. + + CATCH cx_root. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno + WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. + ENDTRY. + ENDIF. + ENDCASE. + + CATCH cx_sy_create_object_error. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE e036(zcds_alv) WITH i_navigation-class. + + CATCH cx_sy_dyn_call_error. + RAISE EXCEPTION TYPE zcx_cds_alv_message + MESSAGE e034(zcds_alv) WITH i_navigation-class i_navigation-method. + ENDTRY. + ENDMETHOD. + + METHOD call_transaction. ASSIGN COMPONENT i_key_field OF STRUCTURE i_selected_row TO FIELD-SYMBOL(). @@ -254,6 +399,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. WITH AUTHORITY-CHECK AND SKIP FIRST SCREEN. ENDMETHOD. + METHOD constructor. persistence = i_persistence. ddic_access = i_ddic_access. @@ -263,6 +409,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. fill_ioc_container( ). ENDMETHOD. + METHOD fill_ioc_container. ioc_container = NEW zcl_cds_alv_ioc_container( ). LOOP AT navigation_exits INTO DATA(navigation_exit). @@ -282,6 +429,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDLOOP. ENDMETHOD. + METHOD get_object_from_ioc_container. DATA(filters) = VALUE zif_cds_alv_ioc_container=>ty_filters( ( key = 'SEMANTIC_OBJECT' value = i_navigation_exit-semantic_object ) @@ -291,6 +439,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. r_object ?= ioc_container->resolve( i_interface = exit_interface i_filters = filters ). ENDMETHOD. + METHOD zif_cds_alv_navigation~navigate_to_object_mass. e_refresh_after = abap_false. @@ -347,6 +496,13 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. call_transaction( i_navigation = navigation i_key_field = i_key_field i_selected_row = ). + + ELSEIF navigation-class IS NOT INITIAL + AND navigation-method IS NOT INITIAL + AND navigation-method_parameter IS NOT INITIAL. + call_oo_method( i_navigation = navigation + i_key_field = i_key_field + i_selected_row = ). ENDIF. ENDLOOP. @@ -356,6 +512,13 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. call_function_module( i_navigation = navigation i_key_field = i_key_field i_selected_rows = i_selected_rows ). + + ELSEIF navigation-class IS NOT INITIAL + AND navigation-method IS NOT INITIAL + AND navigation-method_parameter IS NOT INITIAL. + call_oo_method( i_navigation = navigation + i_key_field = i_key_field + i_selected_rows = i_selected_rows ). ELSE. RAISE EXCEPTION TYPE zcx_cds_alv_message MESSAGE e004(zcds_alv). ENDIF. @@ -369,6 +532,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDTRY. ENDMETHOD. + METHOD zif_cds_alv_navigation~navigate_to_object_single. e_refresh_after = abap_false. @@ -416,6 +580,13 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. call_transaction( i_navigation = navigation i_key_field = i_key_field i_selected_row = i_selected_row ). + + ELSEIF navigation-class IS NOT INITIAL + AND navigation-method IS NOT INITIAL + AND navigation-method_parameter IS NOT INITIAL. + call_oo_method( i_navigation = navigation + i_key_field = i_key_field + i_selected_row = i_selected_row ). ENDIF. e_refresh_after = navigation-refresh_after. @@ -426,6 +597,7 @@ CLASS zcl_cds_alv_navigation IMPLEMENTATION. ENDTRY. ENDMETHOD. + METHOD zif_cds_alv_navigation~navigate_via_association. DATA(target_view) = ddic_access->get_target_for_association( i_source_view = i_source_view i_association_name = i_association_name ). diff --git a/src/zcl_cds_alv_navigation.clas.xml b/src/zcl_cds_alv_navigation.clas.xml index 68ae068..e933f2e 100644 --- a/src/zcl_cds_alv_navigation.clas.xml +++ b/src/zcl_cds_alv_navigation.clas.xml @@ -11,6 +11,26 @@ X X + + + CALL_OO_METHOD + I_KEY_FIELD + E + Field Name + + + CALL_OO_METHOD + I_NAVIGATION + E + Intent-Based Navigation for the CDS ALV Framework + + + CALL_OO_METHOD + ZCX_CDS_ALV_MESSAGE + E + Ausnahmeklasse für das CDS-ALV Framework + + diff --git a/src/zi_cds_alv_extensionheaders.ddls.asddls b/src/zi_cds_alv_extensionheaders.ddls.asddls index 38836e1..b81d07f 100644 --- a/src/zi_cds_alv_extensionheaders.ddls.asddls +++ b/src/zi_cds_alv_extensionheaders.ddls.asddls @@ -5,10 +5,13 @@ @EndUserText.label: 'Erweiterungen von Reports für CDS-Views' @VDM.viewType: #BASIC define view ZI_CDS_ALV_ExtensionHeaders as select from zcds_alv_exthdr -association[0..*] to ZI_CDS_ALV_ExtensionHeaderText as _Text on _Text.ExtensionName = $projection.ExtensionName { - key extension_name as ExtensionName, +association[0..*] to ZI_CDS_ALV_ExtensionHeaderText as _Text on _Text.ExtensionName = $projection.ExtensionName +association[0..*] to ZI_CDS_ALV_ExtensionParameters as _Parameters on _Parameters.ExtensionName = $projection.ExtensionName +{ + key extension_name as ExtensionName, alternative_selection as AlternativeSelection, - alternative_display as AlternativeDisplay, - implementing_class as ImplementingClass, - _Text + alternative_display as AlternativeDisplay, + implementing_class as ImplementingClass, + _Text, + _Parameters } diff --git a/src/zi_cds_alv_extensionheadertext.ddls.asddls b/src/zi_cds_alv_extensionheadertext.ddls.asddls index 6606953..bc9c23f 100644 --- a/src/zi_cds_alv_extensionheadertext.ddls.asddls +++ b/src/zi_cds_alv_extensionheadertext.ddls.asddls @@ -4,10 +4,11 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Erweiterungen von Reports für CDS-Views (Texte)' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_ExtensionHeaderText as select from zcds_alv_exthdrt { - key spras as Language, +define view ZI_CDS_ALV_ExtensionHeaderText as select from zcds_alv_exthdrt +{ + key spras as Language, key extension_name as ExtensionName, - extension_text as ExtensionText, - selection_text as SelectionText, - display_text as DisplayText + extension_text as ExtensionText, + selection_text as SelectionText, + display_text as DisplayText } diff --git a/src/zi_cds_alv_extensionparameters.ddls.asddls b/src/zi_cds_alv_extensionparameters.ddls.asddls index 4a7b688..11e9859 100644 --- a/src/zi_cds_alv_extensionparameters.ddls.asddls +++ b/src/zi_cds_alv_extensionparameters.ddls.asddls @@ -5,13 +5,16 @@ @EndUserText.label: 'Parameter einer Programmerweiterung' @VDM.viewType: #BASIC define view ZI_CDS_ALV_ExtensionParameters as select from zcds_alv_extpar -association[0..*] to ZI_CDS_ALV_ExtensionParamTexts as _Text on _Text.ExtensionName = $projection.ExtensionName - and _Text.ParameterName = $projection.ParameterName { +association[1..1] to ZI_CDS_ALV_ExtensionHeaders as _Header on _Header.ExtensionName = $projection.ExtensionName +association[0..*] to ZI_CDS_ALV_ExtensionParamTexts as _Text on _Text.ExtensionName = $projection.ExtensionName + and _Text.ParameterName = $projection.ParameterName +{ key extension_name as ExtensionName, key parameter_name as ParameterName, db_field as DbField, has_value_help as HasValueHelp, has_help as HasHelp, attribute_name as AttributeName, + _Header, _Text } diff --git a/src/zi_cds_alv_extensionparamtexts.ddls.asddls b/src/zi_cds_alv_extensionparamtexts.ddls.asddls index a708cec..bff93cd 100644 --- a/src/zi_cds_alv_extensionparamtexts.ddls.asddls +++ b/src/zi_cds_alv_extensionparamtexts.ddls.asddls @@ -4,9 +4,10 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Parametertexte einer Programmerweiterung' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_ExtensionParamTexts as select from zcds_alv_extpart { - key spras as Language, +define view ZI_CDS_ALV_ExtensionParamTexts as select from zcds_alv_extpart +{ + key spras as Language, key extension_name as ExtensionName, key parameter_name as ParameterName, - parameter_text as ParameterText + parameter_text as ParameterText } diff --git a/src/zi_cds_alv_navigation.ddls.asddls b/src/zi_cds_alv_navigation.ddls.asddls index 348984d..863274c 100644 --- a/src/zi_cds_alv_navigation.ddls.asddls +++ b/src/zi_cds_alv_navigation.ddls.asddls @@ -4,14 +4,20 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Intent-Based Navigation' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_Navigation as select from zcds_alv_nav { +define view ZI_CDS_ALV_Navigation as select from zcds_alv_nav +{ key semantic_object as SemanticObject, key semantic_action as SemanticAction, - function as Function, - default_parameter as DefaultParameter, - conversion_exit as ConversionExit, - object_type as ObjectType, - object_method as ObjectMethod, - transaction_code as TransactionCode, - parameter_id as ParameterId + function as Function, + default_parameter as DefaultParameter, + conversion_exit as ConversionExit, + object_type as ObjectType, + object_method as ObjectMethod, + transaction_code as TransactionCode, + parameter_id as ParameterId, + class as Class, + method as Method, + method_parameter as MethodParameter, + mass_processing as MassProcessing, + refresh_after as RefreshAfter } diff --git a/src/zi_cds_alv_parameters.ddls.asddls b/src/zi_cds_alv_parameters.ddls.asddls index 59854e3..1f42c58 100644 --- a/src/zi_cds_alv_parameters.ddls.asddls +++ b/src/zi_cds_alv_parameters.ddls.asddls @@ -4,9 +4,12 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'PARAMETERS der generierten Programme für CDS-Views' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_Parameters as select from zcds_alv_params { +define view ZI_CDS_ALV_Parameters as select from zcds_alv_params +association[1..1] to ZI_CDS_ALV_Programs as _Program on _Program.ProgramName = $projection.ProgramName +{ key progname as ProgramName, key sel_name as SelectionName, - cds_view as CdsView, - parname as ParameterName + cds_view as CdsView, + parname as ParameterName, + _Program } diff --git a/src/zi_cds_alv_programextensions.ddls.asddls b/src/zi_cds_alv_programextensions.ddls.asddls index 115bb0d..59edfeb 100644 --- a/src/zi_cds_alv_programextensions.ddls.asddls +++ b/src/zi_cds_alv_programextensions.ddls.asddls @@ -4,8 +4,11 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Programmerweiterungen für einen CDS-View' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_ProgramExtensions as select from zcds_alv_progext { - key cds_view as CdsView, +define view ZI_CDS_ALV_ProgramExtensions as select from zcds_alv_progext +association[1..1] to ZI_CDS_ALV_Programs as _Program on _Program.CdsView = $projection.CdsView +{ + key cds_view as CdsView, key extension_name as ExtensionName, - active as Active + active as Active, + _Program } diff --git a/src/zi_cds_alv_programs.ddls.asddls b/src/zi_cds_alv_programs.ddls.asddls index 1149938..dc7a514 100644 --- a/src/zi_cds_alv_programs.ddls.asddls +++ b/src/zi_cds_alv_programs.ddls.asddls @@ -4,11 +4,18 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Programme zur Anzeige von CDS-Views' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_Programs as select from zcds_alv_program { - key cds_view as CdsView, - progname as ProgramName, - dynpro as SelectionScreen, - author as Author, - generated_at as GeneratedAt, - no_generation as NoGeneration +define view ZI_CDS_ALV_Programs as select from zcds_alv_program +association[0..*] to ZI_CDS_ALV_Parameters as _Parameters on _Parameters.ProgramName = $projection.ProgramName +association[0..*] to ZI_CDS_ALV_SelectOptions as _SelectOptions on _SelectOptions.ProgramName = $projection.ProgramName +association[0..*] to ZI_CDS_ALV_ProgramExtensions as _Extensions on _Extensions.CdsView = $projection.CdsView +{ + key cds_view as CdsView, + progname as ProgramName, + dynpro as SelectionScreen, + author as Author, + generated_at as GeneratedAt, + no_generation as NoGeneration, + _Parameters, + _SelectOptions, + _Extensions } diff --git a/src/zi_cds_alv_selectoptions.ddls.asddls b/src/zi_cds_alv_selectoptions.ddls.asddls index 56d4c1e..4acd1e0 100644 --- a/src/zi_cds_alv_selectoptions.ddls.asddls +++ b/src/zi_cds_alv_selectoptions.ddls.asddls @@ -4,9 +4,12 @@ @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'SELECT-OPTIONS of generated programs for CDS Views' @VDM.viewType: #BASIC -define view ZI_CDS_ALV_SelectOptions as select from zcds_alv_selopts { +define view ZI_CDS_ALV_SelectOptions as select from zcds_alv_selopts +association[1..1] to ZI_CDS_ALV_Programs as _Program on _Program.ProgramName = $projection.ProgramName +{ key progname as ProgramName, key sel_name as SelectionName, - cds_view as CdsView, - fieldname as FieldName + cds_view as CdsView, + fieldname as FieldName, + _Program }