Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
vonglan
Active Participant
1,307
To speed up the creation of new basic CDS views, based on existing tables, I came up with this little report which I would like to share.

You start it with a table name, e.g. vttk (table from SAP standard for which currently no CDS view is delivered by SAP, as far as I found out), and then the report yields something like:
@AbapCatalog.sqlViewName: 'Z?IShipmentHeade'
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Shipment Header'
@VDM.viewType: #BASIC
define view Z?_I_ShipmentHeader as select from VTTK {
key tknum as ShipmentNumber, // Shipment Number
vbtyp as SDDocumentCateg, // SD document category
shtyp as ShipmentType, // Shipment type
tplst as TransportPlanningPt, // Transportation planning point
ernam as CreatedBy, // Name of Person Who Created the Object
erdat as CreatedOn, // Date on Which Record Was Created

...

pkstk as HandlingUnits, // Shipment Contains Handling Units
@Semantics.unitOfMeasure: true
dtmeg as WeightUnit, // Unit of Weight for Transportation Planning
@Semantics.unitOfMeasure: true
dtmev as VolumeUnit, // Volume Unit for Transportation Planning
@Semantics.quantity.unitOfMeasure: 'UoMDistance'
distz as Distance, // Distance

...

Update 26.04.2022:

I improved the code

  • bugfixes (e.g. comma was missing after field names)

  • header (you might have to adapt this for the conventions in your company; we replace the "?" with a "module character" like "V")

  • annotations for currency and unit fields


Here is the improved code:
REPORT zs_create_cds_from_table.

PARAMETERS: p_tabl TYPE tabname.

CLASS lcl_app DEFINITION FINAL.
PUBLIC SECTION.
CLASS-METHODS:
main.
TYPES: BEGIN OF tp,
fieldname TYPE dd03l-fieldname,
keyflag TYPE dd03l-keyflag,
datatype TYPE dd03l-datatype,
reftable TYPE dd03l-reftable,
reffield TYPE dd03l-reffield,
ddtext TYPE dd04t-ddtext,
reptext TYPE dd04t-reptext,
scrtext_s TYPE dd04t-scrtext_s,
scrtext_m TYPE dd04t-scrtext_m,
scrtext_l TYPE dd04t-scrtext_l,
END OF tp,
ttp TYPE STANDARD TABLE OF tp WITH EMPTY KEY.
PRIVATE SECTION.
CLASS-METHODS get_fieldname
IMPORTING
i_wa TYPE REF TO lcl_app=>tp
RETURNING VALUE(r) TYPE string.
ENDCLASS.

CLASS lcl_app IMPLEMENTATION.

METHOD main.
DATA it TYPE ttp.
SELECT
FROM dd03l AS fields
INNER JOIN dd04t AS texts
ON texts~ddlanguage = 'E'
AND texts~rollname = fields~rollname
FIELDS * " fieldname, keyflag, ddtext, reptext, scrtext_s, scrtext_m, scrtext_l
WHERE tabname = @p_tabl
AND fields~rollname <> 'MANDT'
AND fields~as4local = 'A'
AND fields~as4vers = '0000'
AND texts~as4local = 'A'
AND texts~as4vers = '0000'
ORDER BY position
INTO CORRESPONDING FIELDS OF TABLE @it.
ASSERT sy-subrc = 0.

SELECT SINGLE ddtext
FROM dd02t
WHERE tabname = @p_tabl
AND ddlanguage = 'E'
AND as4local = 'A'
AND as4vers = '0000'
INTO @DATA(description).
ASSERT sy-subrc = 0.

DATA(cds_name) = |Z?_I_{ replace( val = description sub = ` ` with = '' occ = 0 ) }|.
DATA(view_name) = CONV viewname16( |Z?I{ replace( val = description sub = ` ` with = '' occ = 0 ) }| ).

WRITE / |@AbapCatalog.sqlViewName: '{ view_name }'|.
WRITE / |@AccessControl.authorizationCheck: #CHECK|.
WRITE / |@EndUserText.label: 'Shipment Header'|.
WRITE / |@VDM.viewType: #BASIC|.
WRITE / |define view { cds_name } as select from { p_tabl } \{|.

LOOP AT it REFERENCE INTO DATA(wa).
CASE wa->datatype.
WHEN 'CUKY'.
WRITE / | @Semantics.currencyCode: true|.
WHEN 'UNIT'.
WRITE / | @Semantics.unitOfMeasure: true|.
WHEN 'QUAN' OR 'CURR'.
IF wa->reftable = p_tabl AND line_exists( it[ fieldname = wa->reffield ] ).
DATA(unit_field) = REF #( it[ fieldname = wa->reffield ] ).
DATA(cds_unit_field) = get_fieldname( unit_field ).
ELSE.
cds_unit_field = '???'.
ENDIF.
WRITE / | @Semantics.{ COND #( WHEN wa->datatype = 'QUAN' THEN 'quantity.unitOfMeasure'
ELSE 'amount.currencyCode' ) }: '{ cds_unit_field }'|.
ENDCASE.
DATA(tab_fieldname_with_key) = COND #( WHEN wa->keyflag = abap_true THEN `key ` ELSE '' ) && to_lower( wa->fieldname ).
DATA(cds_fieldname_with_comma) = get_fieldname( wa ) && COND #( WHEN sy-tabix = lines( it ) THEN '' ELSE ',' ).
WRITE / | { tab_fieldname_with_key WIDTH = 20 } as { cds_fieldname_with_comma WIDTH = 32 } // { wa->ddtext }|.
ENDLOOP.

WRITE / |\}|.
ENDMETHOD.


METHOD get_fieldname.
DATA t TYPE string.
IF i_wa->scrtext_l IS NOT INITIAL.
t = i_wa->scrtext_l.
ELSEIF i_wa->scrtext_m IS NOT INITIAL.
t = i_wa->scrtext_m.
ELSEIF i_wa->reptext IS NOT INITIAL.
t = i_wa->reptext.
ELSEIF i_wa->scrtext_s IS NOT INITIAL.
t = i_wa->scrtext_s.
ELSE.
r = |TODO: find name! // { i_wa->ddtext }|.
RETURN.
ENDIF.
DATA(new_word) = abap_true.
DO strlen( t ) TIMES.
DATA(offset) = sy-index - 1.
DATA(c) = t+offset(1).
IF c CA | .-,_/()'"|.
new_word = abap_true.
CONTINUE.
ENDIF.
IF c >= 'A' AND c <= 'Z'.
new_word = abap_true.
ENDIF.
IF new_word = abap_true.
r = r && to_upper( c ).
new_word = abap_false.
ELSE.
r = r && to_lower( c ).
ENDIF.
ENDDO.
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
lcl_app=>main( ).

 
Labels in this area