SAP CDS开发环境

Install ABAP Development Tools (ADT) and abapGit Plugin | Tutorials for SAP Developers

Create an ABAP Project in ABAP Development Tools (ADT)

CDS 代码资料

ABAP Keyword Documentation

About ABAP Programming Model for SAP Fiori(CDS UI 注解)

SAP Help Portal

增强或扩展CDS视图 | 优通SAP

1.CDS 开发学习

BOPF是业务对象处理框架(Business Object Processing Framework,以下简称BOPF),SAP有很多标准的BOPF.

整体的CDS结构一般做三层,类似于BW,分别是抽取层(View),转换层(Basic),输出层(Consumption),分别对Basis层和Consumption层搭建BOPF框架,Consumption层暴露给Fiori使用

1.1 S/4 三层架构(VDM View types

1.2层级

1.3约定俗成的命名规则

1.4数据抽取层代码(+转换层):

CDS转换层是主要的逻辑处理部分,抽取层基本不对数据处理,为转换层搭建BOPF框架,激活之后就会产生对应的BOPF(T-code:BOBX) ,这里没有做区分,之后对BOPF这块详解

@AbapCatalog.sqlViewName: 'ZDDL_I_EXEMPTION'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '豁免主控室抽取层BASIC'@ObjectModel: { compositionRoot: true,modelCategory: #BUSINESS_OBJECT,transactionalProcessingEnabled: true,representativeKey: 'exemption_id',draftEnabled: true,createEnabled: true,updateEnabled: true,deleteEnabled: true,semanticKey: ['exemption_id'],writeDraftPersistence: 'ZACT_EXEMPTION_D' }//@VDM.viewType: #BASIC
define view ZACT_I_EXEMPTIONas select from Satc_Ci_Exempt_Dvassociation [1..*] to YACT_I_SATC_EX_CHLOG    as _ex_chlog    on  $projection.exemption_id = _ex_chlog.ExemptionIdassociation [1..1] to ZACT_I_SATC_AC_CONTACTS as _ac_contacts on  $projection.objtype     = _ac_contacts.objectand $projection.objname     = _ac_contacts.obj_nameand $projection.ds_group_id = _ac_contacts.system_group
{@ObjectModel.readOnly: truekey exemption_id,check_scope,chkclass,chkcode,Satc_Ci_Exempt_Dv.object_scope as object_scope,objname,objtype,Satc_Ci_Exempt_Dv.subobjname   as subobjname,subobjtype,checksum,valid_until,@UI: {lineItem: [ { position: 10, importance: #HIGH } ],selectionField: [ { position: 10 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 10, importance: #HIGH }]}state,prev_state,applicant,appl_last,reason,appl_comment,approver,appr_last,appr_comment,notification_request,last_changed,deleted,exemption_crc,back_pack,xx_hint,data_source_id,ds_group_id,cast( '' as charg_d ) as charg,_ac_contacts.package_name,
//      _ac_contacts.changed_on,@ObjectModel.association: {type: [#TO_COMPOSITION_CHILD]}_ex_chlog,_ac_contacts
}
//where
//      SerialNumberProfile = '' and //Serial Number ILs to display in LR from 1911CE
//  _ex_chlog.deleted != 'X' //非删除状态

说明:

  1. cast( ( _eket.menge – _eket.wemng ) as obmng ) as OBMNG,第一个as obmng,表示数据结果数据元素为obmng,第二个表示生成的视图字段名为obmng
  2. @Semantics.quantity.unitOfMeasure: ‘meins’ 表示下面的字段数量单位为meins
  3. sum(wemng)   as wemng 汇总明细字段
  4. ------------------------------------------------------------------------------------------
  5. transactionalProcessingEnabled: true, 表示生成BOPF
  6. draftEnabled: true,表示BOPF使用草稿功能,
  7. writeDraftPersistence: ‘ZACT_EXEMPTION_D’表示草稿数据表为ZACT_EXEMPTION_D
  8. 此CDS使用了明细CDS:YACT_I_SATC_EX_CHLOG,所以不能独立激活,需要与后面的一步的CDS一起激活
  9. @ObjectModel.association.type: [#TO_COMPOSITION_CHILD]表示后面的对像为字node对像。

1.5数据消费层代码

CDS 输出层 VIEW指消费层,同样要搭建BOPF框架,但不会产生BOPF对象,这一层主要是把CDS发布成ODATA服务暴露给Fiori调用

@AbapCatalog.sqlViewName: 'ZDDL_C_EXEMPTION'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '豁免主控室输出层consumption'
@VDM.viewType: #CONSUMPTION@Metadata.allowExtensions: true@ObjectModel: { compositionRoot: true,transactionalProcessingDelegated: true,createEnabled: true,updateEnabled: true,deleteEnabled: true,semanticKey: ['exemption_id'],representativeKey: 'exemption_id',draftEnabled: true}@OData.publish: truedefine view ZACT_C_EXEMPTIONas select from ZACT_I_EXEMPTION as _exemption//association [0..1] to YACT_REASION        as _reason         on  $projection.reason = _reason.ReasonCode//association [0..1] to YACT_SATC_EX_CHLOG  as _ex_chlog       on  $projection.exemption_id = _ex_chlog.ExemptionId//  association [0..1] to YACT_SATC_CI_CF_P_E as _satc_ci_cf_p_e on  $projection.chkcode = _satc_ci_cf_p_e.message_idassociation [1..*] to YACT_SATC_EX_CHLOG      as _ex_chlog    on  $projection.exemption_id = _ex_chlog.ExemptionId
//  association [0..1] to ZACT_C_SATC_AC_CONTACTS as _ac_contacts on  $projection.objtype     = _ac_contacts.object
//                                                                and $projection.objname     = _ac_contacts.obj_name
//                                                                and $projection.ds_group_id = _ac_contacts.system_group//association [0..*] to tadir               as _tadir          on  $projection.objtype = _tadir.object//and $projection.objname = _tadir.obj_name//YACT_SATC_AC_RESULTH
{//免除标示key exemption_id,//检查范围check_scope,//类/接口chkclass,//消息代码chkcode,//对象范围object_scope,//对象名称objname,//对象类型objtype,//接口组件subobjname,//对象类型subobjtype,//身份checksum,//过期日期valid_until,@ObjectModel.mandatory: true//免除状态state,//审批状态prev_state,//申请人applicant,//更改日期(申请人)appl_last,//免除原因reason,//理由appl_comment,//审批人approver,//更改日期(审批者)appr_last,//理由appr_comment,//通知请求notification_request,//更改日期last_changed,//删除标识 布尔变量(X = 真,空格 = 假)deleted,//INT4exemption_crc,//Serialisierte Datenback_pack,//XX_HINTxx_hint,//对象提供者data_source_id,//系统组ds_group_id,_exemption.package_name,//@ObjectModel.readOnly//_reason.ReasonText                                     as reason_text,//      @ObjectModel.readOnly//      _satc_ci_cf_p_e.test_title                             as test_title,//      @ObjectModel.readOnly//      _satc_ci_cf_p_e.msg_title                              as msg_title,//      @ObjectModel.readOnly//      cast( case when _tadir.devclass is not null then coalesce( _ac_contacts.package_name, _tadir.devclass ) else '' end as abap.char( 100 ) ) as package_name,//      @ObjectModel.readOnly//      coalesce( _ac_contacts.author, _tadir.author )         as author,//_tadir,//_ac_contacts,//      _satc_ci_cf_p_e,/* Associations *///      @ObjectModel: {//           association: {//               type: [#TO_COMPOSITION_CHILD]//           }//       }//_ex_chlog,//_reason@ObjectModel.association: {type: [#TO_COMPOSITION_CHILD]}_ex_chlog
}

说明

  1. 激活需要与后面明细的视图一起同时才能激活。
  2. @OData.publish: true,用于生成ODATA服务,但此服务生成后没有激活,如要直接使用此服务的话,可使用事务码/N/IWFND/MAINT_SERVICE在其中添加服务,来添加此服务,或者直接在SEGW中已有的项目中添加此服务。
  3. updateEnabled: true,设置可以修改,用于修改收货数量,
  4. deleteEnabled: true,设置可以删除数据,如不做增强的话,默认为删除修改的数据,也就是删除草稿内容。
  5. deleteEnabled: true,使用草案
  6. association [0..1] to C_MM_SupplierValueHelp,是连接到供应商的搜索帮助,在后面字段中注释了的LIFNR中,就会使用此CDS
  7. @Consumption: { valueHelp: ‘_SupplierValueHelp’,filter.mandatory: true }此用于在屏幕中生成一个带必输入的供应商查询条件,可以打开此注释,测试。
  8. @ObjectModel.association.type: [#TO_COMPOSITION_CHILD]用于指定后面的为字节点

1.6元数据扩展层

@Metadata.layer: #CUSTOMER@UI: {headerInfo: {typeName: '豁免主控室 typeName',typeNamePlural: '豁免主控室 typeNamePlural',title: { type: #STANDARD, label: '豁免主控室 title label', value: 'exemption_id' }}
}
@UI.presentationVariant: [{sortOrder: [{ by: 'last_changed', direction: #ASC }]
}]
annotate view ZACT_C_EXEMPTION with
{@UI.facet: [{label: 'Header data',id: 'Header',type: #COLLECTION},{label: 'FIELDGROUP_REFERENCE HeaderInfo',id : 'HeaderData',parentId : 'Header',type : #FIELDGROUP_REFERENCE,targetQualifier : 'HeaderInfo'},{label: '_ex_chlog',purpose: #STANDARD,id: '_ex_chlog',type: #LINEITEM_REFERENCE,targetElement: '_ex_chlog'}]@UI: {lineItem: [ -- Action Lineitem  { type: #FOR_ACTION, dataAction: 'BOPF:exemption', label: '审批d' }//,{ position: 1, importance: #HIGH ,type: #FOR_ACTION,dataAction: 'BOPF:exemption1',label: '审批1'}//,{ type: #FOR_ACTION, dataAction: 'BOPF:exemption',label: 'Set CITY_TO' } ],identification: [{type: #FOR_ACTION,position: 10,dataAction: 'BOPF:exemption',label: '审批' }//,{type: #FOR_ACTION,position: 2,dataAction: 'BOPF:prov',label: '审批2' }]}exemption_id;@UI: {lineItem: [ { position: 1, importance: #HIGH ,type: #FOR_ACTION,dataAction: 'BOPF:exemption1',label: '审批1'}//,{ type: #FOR_ACTION, position: 2,dataAction: 'BOPF:exemption1',label: 'Set CITY_TO' } ],selectionField: [ { position: 1 } ],identification: [{position: 1//,dataAction: 'BOPF:SET_CITY1',label: '审批', type: #FOR_ACTION}//,{type: #FOR_ACTION,position: 2,dataAction: 'BOPF:prov',label: '审批' }],fieldGroup: [{ qualifier: 'HeaderInfo', position: 1, importance: #HIGH }]}//审批人approver;@UI: {lineItem: [ { position: 20, importance: #HIGH } ],selectionField: [ { position: 20 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 20, importance: #HIGH }]}//申请人applicant;@UI: {lineItem: [ { position: 21} ],identification: [{position: 21}],fieldGroup: [{ qualifier: 'HeaderInfo', position: 21, importance: #HIGH }]}//申请人appl_comment;@UI: {lineItem: [ { position: 30, importance: #HIGH ,label:'对象联系人'} ],selectionField: [ { position: 30 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 30, importance: #HIGH }]}//对象提供者data_source_id;@UI: {lineItem: [ { position: 40, importance: #HIGH ,label:'审批状态'} ],selectionField: [ { position: 40 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 40, importance: #HIGH ,label:'审批状态'}]}//审批状态prev_state;@UI: {lineItem: [ { position: 50, importance: #HIGH } ],selectionField: [ { position: 50 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 50, importance: #HIGH }]}//免除状态state;@UI: {lineItem: [ { position: 60, importance: #HIGH } ],selectionField: [ { position: 60 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 60, importance: #HIGH }]}//更改日期(申请人)appl_last;@UI: {lineItem: [ { position: 70, importance: #HIGH } ],selectionField: [ { position: 70 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 70, importance: #HIGH }]}//更改日期(审批者)appr_last;@UI: {lineItem: [ { position: 80, importance: #HIGH } ],selectionField: [ { position: 80 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 80, importance: #HIGH }]}//过期日期valid_until;@UI: {//lineItem: [ { position: 90, importance: #HIGH } ],selectionField: [ { position: 90 } ],//      identification:[ { position: 20, importance: #HIGH } ],fieldGroup: [{ qualifier: 'HeaderInfo', position: 90, importance: #HIGH }]}//免除原因reason;//  @UI: {//  lineItem: [ { position: 110, importance: #HIGH } ]//  }////  reason_text;@UI: {lineItem: [ { position: 110, importance: #HIGH } ]//,//fieldGroup: [{ qualifier: 'HeaderInfo', position: 100, importance: #HIGH }]}package_name;//  @UI: {//  lineItem: [ { position: 120, importance: #HIGH } ]//  }////  test_title;//  @UI: {//  lineItem: [ { position: 130, importance: #HIGH } ]//  }////  msg_title;////  @UI: {//  lineItem: [ { position: 140, importance: #HIGH } ]//  }////  package_name;//  @UI: {//  lineItem: [ { position: 150, importance: #HIGH } ]//  }//  author;
}

说明:

  1. 在headerInfo中指定很多的抬头信息,具体的内容还在测试中。
  2. @Search.searchable: true //指定主页可以有搜索框,
  3. @Search:{defaultSearchElement: true,fuzzinessThreshold: 0.8}//主页可搜索框可搜索字段,在这里指定的0.8是一个模糊搜索的一个度量,最大是1,由于供应商有前导0,所以用此方法来避免输入供应商前导0来查询。
  4. lineItem,指定在列表中显示的信息,
  5. fieldGroup指定在对像页(细节页)时抬头显示的信息。

其他代码块

@AbapCatalog.sqlViewName: 'YACT_LAST_CHLOG'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'YACT_LAST_SATC_EX_CHLOG'define view YACT_LAST_SATC_EX_CHLOGas select from satc_ci_ex_chlog
{key exemption_id      as ExemptionId,max ( timestamp ) as Timestamp}
group byexemption_id
@AbapCatalog.sqlViewName: 'YACT_I_CHLOG'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'YACT_LAST_SATC_EX_CHLOG Basis'@ObjectModel: {updateEnabled: true,createEnabled: true,deleteEnabled: true,semanticKey: ['ExemptionId', 'Timestamp'],representativeKey: 'Timestamp',writeDraftPersistence: 'ZSD_I_CHLOG_D'}define view YACT_I_SATC_EX_CHLOGas select from YACT_LAST_SATC_EX_CHLOG as _chlogmaxinner join   satc_ci_ex_chlog        as _ChlogInfo on  _chlogmax.ExemptionId = _ChlogInfo.exemption_idand _chlogmax.Timestamp   = _ChlogInfo.timestampassociation [1..1] to ZACT_I_EXEMPTION as _exemption on $projection.ExemptionId = _exemption.exemption_id
{key _chlogmax.ExemptionId   as ExemptionId,key _chlogmax.Timestamp     as Timestamp,_ChlogInfo.check_scope  as check_scope,_ChlogInfo.chkclass     as chkclass,_ChlogInfo.chkcode      as chkcode,_ChlogInfo.object_scope as object_scope,_ChlogInfo.objname      as objname,_ChlogInfo.objtype      as objtype,_ChlogInfo.subobjname   as subobjname,_ChlogInfo.subobjtype   as subobjtype,_ChlogInfo.checksum     as checksum,_ChlogInfo.valid_until  as valid_until,_ChlogInfo.state        as state,_ChlogInfo.applicant    as applicant,_ChlogInfo.appl_last    as appl_last,_ChlogInfo.reason       as reason,_ChlogInfo.appl_comment as appl_comment,_ChlogInfo.approver     as approver,_ChlogInfo.appr_last    as appr_last,_ChlogInfo.appr_comment as appr_comment,_ChlogInfo.deleted      as deleted,@ObjectModel.association: {type: [#TO_COMPOSITION_PARENT, #TO_COMPOSITION_ROOT]}_exemption
}
where_ChlogInfo.deleted != 'X' //非删除状态
@AbapCatalog.sqlViewName: 'YACT_SATC_CHLOG'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'YACT检查satc_ci_ex_chlog'
@UI.headerInfo: {typeName: '详情',typeNamePlural: '计划行',title: { type: #STANDARD, label: '豁免主控室详情'}
//    description: {value: 'DefectText'}
}@VDM.viewType: #CONSUMPTION@ObjectModel: { updateEnabled: true,createEnabled: true,deleteEnabled: true,semanticKey: ['ExemptionId', 'Timestamp'],representativeKey: 'Timestamp' }define view YACT_SATC_EX_CHLOGas select from YACT_I_SATC_EX_CHLOG as _ChlogInfo association [1..1] to ZACT_C_EXEMPTION as _exemption on $projection.ExemptionId = _exemption.exemption_id
{
@UI.facet: [{label: 'item data',id: 'item',type: #COLLECTION},{label: 'item HeaderInfo',id : 'item HeaderData',parentId : 'item',type : #FIELDGROUP_REFERENCE,targetQualifier : 'HeaderInfo1'}]@ObjectModel.readOnly: true@UI: {lineItem: [ { position: 10, importance: #HIGH}],selectionField: [ { position: 10 } ],fieldGroup: [{ qualifier: 'HeaderInfo1', position: 10, importance: #HIGH }]}key _ChlogInfo.ExemptionId  as ExemptionId,key _ChlogInfo.Timestamp    as Timestamp,_ChlogInfo.check_scope  as CheckScope,_ChlogInfo.chkclass     as Chkclass,@UI: {lineItem: [ { position: 30, importance: #HIGH } ],selectionField: [ { position: 30 } ],identification:[ { position: 30 } ],fieldGroup: [{ qualifier: 'HeaderInfo1', position: 30, importance: #HIGH }]}_ChlogInfo.chkcode      as Chkcode,_ChlogInfo.object_scope as ObjectScope,@UI: {lineItem:[ { position: 20, importance: #HIGH} ],selectionField:[ { position: 20 } ],identification:[ { position: 20 } ],fieldGroup: [{ qualifier: 'HeaderInfo1', position: 20, importance: #HIGH }]}_ChlogInfo.objname      as Objname,_ChlogInfo.objtype      as Objtype,_ChlogInfo.subobjname   as Subobjname,_ChlogInfo.subobjtype   as Subobjtype,_ChlogInfo.checksum     as Checksum,_ChlogInfo.valid_until  as ValidUntil,_ChlogInfo.state        as State,_ChlogInfo.applicant    as Applicant,_ChlogInfo.appl_last    as ApplLast,_ChlogInfo.reason       as Reason,_ChlogInfo.appl_comment as ApplComment,_ChlogInfo.approver     as Approver,_ChlogInfo.appr_last    as ApprLast,_ChlogInfo.appr_comment as ApprComment,_ChlogInfo.deleted      as Deleted,//Assocation      @ObjectModel.association: {type: [#TO_COMPOSITION_PARENT, #TO_COMPOSITION_ROOT]}_exemption
}
@AbapCatalog.sqlViewName: 'ZDDL_I_CONTACTS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '豁免主控室 satc_ac_contacts'//@VDM.viewType: #CONSUMPTION
//@ObjectModel: { updateEnabled: true,
//                createEnabled: true,
//                deleteEnabled: true,
//                semanticKey: ['object', 'obj_name','system_group'],
//                representativeKey: 'object',
//                writeDraftPersistence: 'ZSD_CONTACTS_D' }define view ZACT_I_SATC_AC_CONTACTS as select from satc_ac_contacts
//association [1..1] to ZACT_I_EXEMPTION    as _exemption    on  $projection.object     = _exemption.objtype
//                                                               and $projection.obj_name     = _exemption.objname
//                                                               and $projection.system_group = _exemption.ds_group_id
{key object,key obj_name,key system_group,author,@ObjectModel.readOnlypackage_name,changed_on,xx_hint
//    _exemption}

总结

  1. 当修改了CDS后,特别是BOPF后,如一些功能发现不正常,可以考虑删除BOPF及及相关的所有类,表,重新激活CDS来生成BOPF及相关内容。
  2. 当修改CDS,及注释后,在前端没反映出修改的内容,可以重新生成ODATA,或者SEGW重生对应的项目,同时使用事务码:/n/IWFND/CACHE_CLEANUP清除缓存。
  3. 由于做CDS时,我们一开始经常什么变更字段,表等,或者需求的变化,而CDS会自动生成很多东西,特别是BOPF的相关的东西,很多会自动生成,但由于CDS的变更,特别是字段的这些变更能够自动更新,所以会导致各种错误,这里的解决法办,可能是删除相关自动生成的对像,如你准确知道应该要删除什么对像那可直接删除,但事实中我们总是判断不了要删除那些自动生成的对像,所以我都是删除所有自动生成的对像,为此我们最好把一个业务相关的CDS创建到一个包里,这里可能会更方便删除。
  4. 在主从视图关联激活时,需要两个视图同时一起激活。
  5. 在激活时,最好当前显示的只是需要激活的对像,不然,激活时会判断已打开的是否能激活(就算没选中也会去激活),这样报错不一定是你当前对像的报错。

2.激活和增强

2.1 Eclipse中直接开发

数据消费层加入注解@OData.publish: true ,然后直接激活服务(见2.4)

2.1.1 绑定action

通过注解的dataAction把ID绑定到一个名为'exemption'的Action上,按钮名称为'审批d'

@UI: {lineItem: [-- Action Lineitem{ type: #FOR_ACTION, dataAction: 'BOPF:exemption', label: '审批d' }]}exemption_id;#如果写法为:dataAction: 'exemption',需要为cds 创建Behavior Definition,并定义actionaction ( features: instance ) exemption result [1] $self;#在特定字段发生变化并保存时触发校验逻辑,字段名称维护在大括号内。validation validateExemption on save { field exemption_id; }validation validateDates on save { field begin_date, end_date; }

在bopf中增加方法

class ZCL_ACT_A_EXEMPTION definitionpublicinheriting from /BOBF/CL_LIB_A_SUPERCL_SIMPLEfinalcreate public .public section.methods /BOBF/IF_FRW_ACTION~EXECUTEredefinition .
protected section.
private section.
ENDCLASS.CLASS ZCL_ACT_A_EXEMPTION IMPLEMENTATION.method /BOBF/IF_FRW_ACTION~EXECUTE.
DATA(lt_data) = VALUE ZTACT_I_EXEMPTION1( ).DATA: ls_msg       TYPE symsg,lv_dummy_msg TYPE string."Read UI clicked sale orderio_read->retrieve(EXPORTINGiv_node                 =  is_ctx-node_key   " BO Node Nameit_key                  =  it_key            " BO KeyIMPORTINGet_data                 =  lt_data ).   " Data Return Structure"Assuming single instance for a actioneo_message = /bobf/cl_frw_factory=>get_message( ) .LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<fs_data>).<fs_data>-OBJNAME = 'TEST'.IF <fs_data>-PREV_STATE <> 'APPR'."Now update the BO instanceio_modify->update(EXPORTINGiv_node           = is_ctx-node_key    " Nodeiv_key            = <fs_data>-key    " Keyiv_root_key       = <fs_data>-root_key     " NodeIDis_data           = REF #( <fs_data>-node_data )    " Datait_changed_fields = VALUE #(( zif_z_i_fly_c=>sc_node_attribute-zz_i_fly-cityto ) )).ls_msg = VALUE #( msgty = 'S' msgid = '00' msgno = '001'msgv1 = |{ <fs_data>-EXEMPTION_ID }/{ <fs_data>-PREV_STATE }| msgv2 = '成功' ).eo_message->add_message(EXPORTINGis_msg       =  ls_msg   " Structure of Message Variablesiv_node      =  is_ctx-node_key   " Node Nameiv_key       =  <fs_data>-key   " Key
*                   iv_lifetime  =  /bobf/cm_frw=>co_lifetime_state).ELSE.ls_msg = VALUE #( msgty = 'E' msgid = '00' msgno = '001'msgv1 = |{ <fs_data>-EXEMPTION_ID }/{ <fs_data>-PREV_STATE }| msgv2 = '失败' ).eo_message->add_message(EXPORTINGis_msg       =  ls_msg   " Structure of Message Variablesiv_node      =  is_ctx-node_key   " Node Nameiv_key       =  <fs_data>-key   " Key
*           iv_lifetime  =  /bobf/cm_frw=>co_lifetime_state).APPEND VALUE #( key = <fs_DATA>-key ) TO et_failed_key .ENDIF.ENDLOOP.
*    IF <fs_data>-carrid = 'AA'.
**      MESSAGE S000(zyk_cm_bus_plan) WITH 'THIS IS ANOTHER!' INTO lv_dummy_msg.
**      MOVE-CORRESPONDING sy TO ls_msg.
**       eo_message->add_message(
**         EXPORTING
**           is_msg       =  ls_msg   " Structure of Message Variables
**           iv_node      =  is_ctx-node_key   " Node Name
**           iv_key       =  <fs_DATA>-key   " Key
***           iv_lifetime  =  /bobf/cm_frw=>co_lifetime_state
**           ).
**       APPEND VALUE #( key = <fs_DATA>-key ) TO et_failed_key .
*    ENDIF.
*    IF eo_message IS BOUND .
*      eo_message = /bobf/cl_frw_factory=>get_message( ) .
*    ENDIF.endmethod.
ENDCLASS.

2.1.2 效果展示

2.2 BOPF方式

找到转换层生成的BOPF(TCODE:BOBF/BOBX)

2.2.1 BOPF里面ACTION的实现

2.2.2使用(tcode:BOBT)测试ACTION

2.2.3 BOPF里面Validations的实现

Validations和action类似需要创建实施类,Trigger Action勾选Action就会触发校验

2.2.4 BOPF里面Query的实现

2.2.5 激活oData服务(见2.4)

2.3 事务码SEGW创建ODATA 服务

2.3.1 事务码SEGW创建ODATA 服务

登陆SAP GUI 后,使用事务码SEGW,创建一个SAP Gateway Service Builder,在此定义为了ZTEST.

创建成功后,就生成了一个ODATA工程对像ZTEST,此工程中可引入多个表,或者多个定义的CDS,下面以引入前文创建的CDS为例。

2.3.2 引入CDS到ODATA中

在ZTEST工程下,“Odata Model”上点击右键,选择Reference->Data source,

在其中输入前文中创建的DDL Source名字:ZTEST01(与CDS同名)。

点击完成后,生成如图的CDS-Entity exposures

激活ODATA项目工程,点击“Generate Runtime Objects”,此步骤,一定要先选择工程项目(ZTEST),否则激活时会报错的。成功后如图。

2.3.3 激活oData服务(见2.4)

2.3.4对ODATA进行增强

激活过后可以看到Runtime那里可以展开了

选择DPC_EXT

DPC:data provider class CRUD的地方
MPC:modle provider class 数据提供的地方

进去后,下拉找到get_entityset

双击get_entityset,进入到方法内部,然后把里面的代码复制

然后返回到上一页面,选择get_entityset,点击左上角更改,然后点击重新定义方法

进入方法体后,把里面的替换为上面复制的

然后添加写上自己的代码,最后激活

(为什么需要这样重新定义方法,而不是在上一步进入get_entityset里面后直接去点击更改,然后写代码 ?第一种:点击重新定义方法,这个方法就会变色,见下图,很容易看出来这个方法做了增强。第二种:如果在get_entityset方法体里面直接点击更改,然后写代码,这个方法是不会变色的,看不出来对哪个方法做了增强。两种除了这个差别,两者最终能实现的的效果其实都一样)

2.4激活ODATA服务

运行事务码:/IWFND/MAINT_SERVICE 打开激活服务功能,如运行此事务码报错:“用户不能再登陆”,如图。可以在此事务码前面加/n,也就是:/N/IWFND/MAINT_SERVICE 来打开,或者直接在SE93中打开,或者把此事务码添加到收藏菜单中,就不会报错了。

打开后,点击添加服务

在此输入系统别名:LOCAL,技术服务名称,输入前面SEGW创建的工程名:ZTEST*(或者CDS名称),找到


然后返回上一页面,找到自己的服务ZTEST_SRV服务,选择,并点击“添加所选服务”。

输入开发包,点击确认保存,

2.5删除服务

先删除“系统别名”,然后再删除“ Internet 通信框架 ”,最后就能正常的删除ODATA的服务了。

3.根据模板创建Fiori应用

这一步要填写app信息,慎重填写(不要学我乱填)

​ 选择刚刚激活的CDS

全选

选择主页面,点击完成

4.效果

4.1运行

4.2效果

主页

点击进入详情页

SAP CDS 开发和Fiori App生成学习笔记相关推荐

  1. 《Java Web开发入门很简单》学习笔记

    <Java Web开发入门很简单>学习笔记 1123 第1章 了解Java Web开发领域 Java Web主要涉及技术包括:HTML.JavaScript.CSS.JSP.Servlet ...

  2. iOS App Clips学习笔记

    一.什么是App Clip? App Clip是一个App的轻量版,用来提供一些用户所需功能,我们可以把它看成苹果的小程序.它不需要下载就直接能打开.这样即可达到不下载完整版APP便可体验APP的部分 ...

  3. 《Node.js开发实战详解》学习笔记

    <Node.js开发实战详解>学习笔记 --持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...

  4. python web开发入门_python大佬整理的python web开发从入门到精通学习笔记

    原标题:python大佬整理的python web开发从入门到精通学习笔记 Python(发音:英[?pa?θ?n],美[?pa?θɑ:n]),是一种面向对象.直译式电脑编程语言,也是一种功能强大的通 ...

  5. 【实习之T100开发】Genero FGL (TIPTOP4GL) 学习笔记(1)

    Genero FGL 学习 Genero FGL 简介 Genero FGL 开发(编译.连接.执行) 第一个程序 Hello World 变量与运算符 变量定义(DEFINE) 预定义变量 变量集合 ...

  6. Matlab App Designer 学习笔记

    提示:本文的学习视频来自B站小刘老师的教程 链接:https://www.bilibili.com/video/BV16f4y147x9?from=search&seid=2070258926 ...

  7. 《智能对话机器人开发实战20讲》--学习笔记--AIML基础功能拓展-与互联网的集成

    一.学习笔记 环境要求: aiml bs4 语料库: tuling.aiml search_web.aiml <that>WHICH SEARCH ENGINE WOULD YOU LIK ...

  8. MATLAB学习(一)——APP的学习笔记

    1.写在前面 这是一篇MATLAB学习笔记,不断更新. 2.MATLAB基本操作 2.1 函数 Disp函数:打印算子 示例: Disp(pathname) Class函数: 功能:判断数值的类型: ...

  9. 硬件学习、高速dsp开发板制作、STM32学习笔记

    1.硬件工程师成长之路(1)--元件基础_[云轩]的博客-CSDN博客_硬件工程师的成长之路 总目录:https://blog.csdn.net/weixin_44407238/category_10 ...

最新文章

  1. 程序员转型AI,这里有最全的机器学习介绍+应用实例
  2. Maven实战读书笔记(六):Maven灵活构建
  3. 前后端分离项目后端向前端返回压缩包的方法实现java版
  4. 一座在云端的工厂是什么样的?
  5. 小白学习政策定价内容
  6. 判断某点在多边形内——方法二
  7. Java 案例大全(详细)二
  8. 香橙派python编程_香橙派Orange Pi 4开发板在Ubuntu系统下使用python 控制GPIO
  9. 如何设计一个小而美的秒杀系统(抢红包)?
  10. 【刷题篇】鹅厂文化衫问题
  11. 特殊的Excel填充序号技巧,总有一种你会遇到【特别实用,赶紧收藏】
  12. jdk下载,安装与卸载,删除注册表
  13. [Linux Shell] su和sudo命令
  14. Unity灯光(light)
  15. 利用Zotero进行文献检索与管理
  16. C++ vector函数
  17. 【BLDC驱动】分析同步续流与体二极管续流
  18. C#模仿腾讯QQ源码下载(附效果图)_张童瑶的博客
  19. 【历史上的今天】1 月 3 日:苹果公司正式注册成立;《电脑报》正式创刊;英特尔创始人诞生
  20. 网络小说《赘婿》中涉及的地名及其地图

热门文章

  1. 如何利用业余时间学习Python,有没有比较完整的规划。。
  2. 硬件工程师的系统开发之路
  3. 务实java基础之集合总结
  4. MVC AJAXPro
  5. CSS filter 有哪些神奇用途
  6. 【技术类】【ArcGIS对国产卫星的支持2:高分一号卫星】篇5、实时表观反射率产品生产
  7. 激光SLAM:Livox激光雷达硬件时间同步
  8. 计算机技术发展迅速的原因,飞速发展的计算机技术,你知道它的历史源流吗?...
  9. 【图像去模糊】Rethinking Coarse-to-Fine Approach in Single Image Deblurring
  10. Xilinx ISE系列教程(8):读取FPGA芯片唯一ID号