尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SAP RAP报表示例:从CDS数据建模到Fiori界面开发全解析

SAP RAP报表示例:从CDS数据建模到Fiori界面开发全解析 1. 为什么我会用 SAP RAP 来做报表示例1.1 这个示例到底解决什么问题大概前一阵子内部有个需求销售团队想看一张按销售组织、订单状态和时间范围快速筛选的订单汇总报表同时要能在手机上打开不能只停留在 SAP GUI 里。虽然用传统 ABAP 写个 ALV 报表很快但用户坚持要 Fiori 的交互体验还要能点击订单号跳转到详情。我当时刚好在熟悉 SAP RAP就决定用 RAP 做一版“销售订单报表”的 PoC。整个项目不大却覆盖了 RAP 从数据建模到 UI 暴露的完整链路很适合作为“RAP - 报表示例”。这一版示例要解决三个问题第一把 VBAK/VBAP 这些头行表的散落数据聚合成一个报表所需的结构第二通过 OData 服务把数据交给前端保证 Fiori 列表能直接消费第三保留后续扩展能力比如加导出、加行级操作而不是像普通报表一样重新写一套。最终交付的形态就是一个 Fiori Elements List Report前端界面基本由注解生成不需要写一行 JavaScript。1.2 RAP 和传统报表开发方式的差别如果你有 ABAP 背景一定经历过传统的报表开发SE38 里写一个程序定义屏幕选择条件然后调用 REUSE_ALV_GRID_DISPLAY 输出表格。这个方法成熟稳定但不方便做响应式布局也很难被外部系统复用。RAP 的思路是把“数据定义”和“数据操作”分开用 CDS 视图描述数据长什么样用行为定义描述数据可以执行哪些操作最后通过服务定义和服务绑定统一暴露成 OData API前端 Fiori Elements 自动识别元数据生成界面。对报表开发而言这种差异尤其明显。传统报表的字段列表写死在程序里用户要加一列你得改代码RAP 报表的字段列表来自 CDS 视图调整注解和视图结构前端会自动跟着变。更关键的是RAP 天生支持 OData 协议这意味着同一个服务可以被 Fiori、第三方系统、甚至日后迁移到 SAP BTP 上的应用共用。代价就是概念变多了学习曲线比写报表陡刚开始看行为定义、服务绑定、DCL 这些东西会有点懵。1.3 适合谁来参考如果你满足下面任何一个条件这篇内容都值得看负责报表交付的 SAP 顾问正在从传统 ABAP 往 S/4HANA 或 BTP 转的开发以及企业内部想要快速搭 Fiori 报表原型的技术人员。我会默认你懂基本的 ABAP 语法和事务代码比如 SE11、SE80但不强制要求有 RAP 经验因为下面的步骤会尽量拆开讲。如果你完全没接触过 Eclipse ADT可能需要先花点时间熟悉一下界面。这个示例本身不难但可以帮你把 RAP 报表的整条链路跑通。2. RAP 报表的核心模型与设计思路2.1 数据模型CDS 视图如何支撑报表RAP 的应用逻辑建立在 CDS 数据模型之上。报表场景里第一件事就是把要展示的字段和筛选条件封装到 CDS 视图里。CDS 本质上是在数据库层定义的一种“语义化视图”可以做 join、union、聚合写起来比 open SQL 更简单还能通过注解把业务含义、UI 行为直接挂在字段上。如果你以前只在 SE11 里看表RAP 一下会感觉到“描述数据”这件事比以前优雅很多。在我这个销售订单报表示例里我建了一个根视图实体ZC_SO_REPORT数据源来自订单抬头表 VBAK 和客户主数据 KNA1。为什么没有直接选 VBAP 行项目因为报表头部只需要订单总额而行项目需要汇总如果主视图直接 join VBAP 再聚合很容易把 key 声明搞复杂。所以我用一个视图展示抬头级字段把订单金额放到另一个子视图里做预聚合再通过 association 关联进来。这个分层思路在 RAP 报表里非常常见先看清粒度再决定字段放在哪个视图。CDS 视图可以这样写简化示例字段做了解释性命名EndUserText.label: 销售订单报表示例 AccessControl.authorizationCheck: #CHECK AbapCatalog.compiler.compareFilter: true define root view entity ZC_SO_REPORT as select from vbak as h left outer join kna1 as c on c.kunnr h.kunnr { key h.vbeln as SalesOrder, h.vkorg as SalesOrg, h.vtweg as DistributionChannel, h.spart as Division, h.bukrs as CompanyCode, c.name1 as CustomerName, h.erdat as CreatedOn, h.netwr as TotalAmount, h.waerk as Currency, h.vbtyp as OrderCategory, h.lifsk as DeliveryBlock } where h.vbtyp C这里的关键有三点根视图必须有 key字段命名尽量用业务语义而不是直接叫 VBAK_VBELN如果后面要暴露给 Fiori筛选字段需要追加注解。实际项目里客户名称可能因为 KNA1 主记录变更产生历史不一致所以生产报表大多会用快照表或者 CDS View 自动维护客户名。不过 PoC 阶段不用太纠结能看出整体结构就行。2.2 行为定义不只是只读还要能操作RAP 的一大特点是区分“数据模型”和“行为定义”。报表通常只需要读数据听起来似乎不需要行为定义但 Fiori Elements 需要知道这个实体是只读、可创建、可更新还是可删除才能决定界面如何渲染。比如如果你想让列表报表支持行内编辑状态字段必须在行为定义里声明对应操作如果你想加一个顶栏按钮做导出也得定义 action。只读报表的行为定义非常简洁define behavior for ZC_SO_REPORT alias Report { }这个空行为定义告诉框架实体是只读的不提供 create / update / delete。Fiori 预览出来的列表就没有“创建”“编辑”这些按钮干净很多。如果你想增加一个导出按钮可以加define behavior for ZC_SO_REPORT alias Report { action exportExcel result [1..1]; }然后在行为实现类里写方法exportExcel用 ABAP 代码查询数据并生成 XLSX。不过示例阶段我没做导出因为 Fiori Elements 本身自带导出功能只要浏览器支持就行。简单报表不需要自定义 action我建议你先别急着加等核心链路跑通了再说。2.3 服务暴露与 UI 消费从 OData 到 Fiori有了 CDS 视图和行为定义还不等于有一个可用的报表中间需要过一道“服务”概念。RAP 把服务抽象成两层Service Definition 负责声明暴露哪些实体Service Binding 负责指定协议类型OData V2 或 V4和暴露出的 API 端点。报表开发一般就用 OData V2兼容性好云环境里推荐 V4但 Fiori Elements 两种都支持。服务定义非常简单就一句话define service ZC_SO_REPORT_SRV { expose ZC_SO_REPORT; }激活以后再创建一个服务绑定绑定到这个服务定义选择 ODATA V2。ADT 的服务绑定界面会自动列出实体并且可以直接 Preview 查看 OData 返回的 JSON。到这里你的数据源已经变成了一个可以访问的 API。前端可以用 SAPUI5 自己写页面但更省事的做法是用 Fiori Elements 的 List Report 模板填写服务 URL配置好导航界面就自动生成了筛选条件、表格列、响应式布局全部由后端注解驱动。这是 RAP 报表比传统方式“香”的主要原因后端把数据结构定义好前端 UI 几乎是白送的。3. 动手实现一个 RAP 报表示例3.1 开发环境准备在开始建对象之前需要确认开发环境。如果用的是本地传统编译环境比如 NetWeaver 7.5需要安装对应版本的 S/4HANA 开发组件如果用的是 SAP BTP ABAP Environment则直接在浏览器里打开 ABAP 服务。我个人推荐在 Eclipse 中装好 ABAP Development Tools (ADT) 插件因为 CDS 的语法提示、错误定位比 SE11 舒服得多。开发包建议单独建一个比如ZRAP_REPORT_DEMO里面专门放示例相关对象方便整体传输和后续清理。环境准备好以后有一个容易被忽略的点包的角色和软件组件。如果你在云环境里玩把包创建成“development”包勾选要支持的 API 状态防止后面对象不可激活。第一次做的话不要把包建错在$TMP临时包里虽然能激活但一旦传输就会被丢掉后面的服务绑定也可能不给你建。另外确保你的系统用户有激活 ABAP 开发许可证的权限否则激活 CDS 视图时会收到莫名其妙的权限报错。3.2 定义 CDS 视图模型字段、key 与筛选条件在 ADT 中新建 Data Definition名称填ZC_SO_REPORT模板选 “Define View Entity”。新版 ADT 强烈建议用 view entity 而不是旧 syntax因为旧语法在后续生成行为定义时会有兼容问题。视图代码写完后点激活这时候 ADT 会在后台跑语法解析和 DDL 生成。如果报错先看问题列表最常见的是缺 key、字段名冲突、关联条件写错。激活完成后还需要给筛选字段加注解让它变成 Fiori 上的筛选条件Consumption.filter: { position: 10, mandatory: false } SalesOrg, Consumption.filter: { position: 20, mandatory: false } OrderCategory, Consumption.filter: { position: 30 } CreatedOnFiori Elements 生成 List Report 时会自动读取这些Consumption.filter注解把字段放到筛选区。如果你想默认按创建日期倒序展示可以在视图上定义EndUserText或使用UI注解控制排序但最简单的做法是在 Fiori 预览里设置表格默认排序。我再加一个细节金额字段如果想在表格底部显示汇总需要在行项目注解里写UI.lineItem: [{ position: 30, label: 订单金额, total: true }]不然前端就只显示一列数字没有统计功能。3.3 添加行为定义与实现从空行为到自定义操作行为定义可以通过右键新建选择刚才的根视图作为根实体。默认生成的内容是空的代表只读。为了让用户能在列表上对某些订单做“冻结”操作我加了一个 actionFreezeOrder。先在行为定义里声明define behavior for ZC_SO_REPORT alias Report { action FreezeOrder parameter ZSO_FREEZE_PARAM result [1..1]; }然后激活行为定义再新建行为实现类写方法METHOD FreezeOrder. MODIFY vbak SET lifsk 01 WHERE vbeln parameter-OrderId. IF sy-subrc 0. result value #( ( %cid parameter-%cid %key parameter-%key %param parameter ) ). ENDIF. ENDMETHOD.这只是示意实际项目还要考虑授权和锁管理。不过我的建议是如果报表只读就够用别着急加这些花活。我第一次强行做自定义 action 时因为没处理好%key前端根本刷新不了状态花了好久排查。只读报表跑通后再迭代行为操作情绪会好很多。3.4 暴露服务并生成 Fiori 预览服务定义ZC_SO_REPORT_SRV写好后激活。接下来在 ADT 中新建 Service Binding选“ODATA V2”协议绑定到该服务定义。激活后你会看到实体ZC_SO_REPORT已经以 entity set 的形式列出来。点击实体的 URL 可以预览返回的 JSON确认数据没问题。这里有个小技巧先在 Service Binding 页面的“Service Details”里看几个请求的 response比如$metadata是否完整、实体集是否可读能帮助快速排查后端问题。生成 Fiori 界面有两种方式。第一种是在 SAP Fiori Tools 里用 UI Generator 生成一个 Fiori Elements List Report 项目对应你绑定的 OData 服务第二种如果你在的 S/4HANA 版本带 Fiori Preview 功能可以直接在 Service Binding 页面的实体上右键选择 “Fiori Preview”系统会自动打开一个 List Report 页面筛选区和表格都出来了。我用的就是第二种非常快完全没写 UI 代码页面已经能用了。当然这只是一个预览版真正的 Fiori 应用配置还需要在 Fiori Tools 里做应用描述文件但作为 PoC 足够了。3.5 报表增强筛选、汇总、跳转配置要点实际给客户演示时我还加了几个增强点。首先是筛选RAP 的筛选条件效果最好的是绑定到 CDS 视图字段上的Consumption.filter。我这里用了销售组织、订单类别和创建日期三个条件。需要注意日期条件如果想默认给一个范围可以通过ObjectModel.dateRange注解实现这样 Fiori 界面会出现一个 date range 输入框而不是两个日期框。其次是汇总。Fiori Elements List Report 对数字字段的汇总是在 UI 注解层控制的。例如在整行字段注解里写total: true就会在底部显示总和。如果你想显示价格和数量的汇总要确保这些字段在 CDS 里是可靠的数字类型比如为abap.dats或abap.cuky否则注解不生效。最后是跳转。常见做法是把主视图的订单号设为主链接点击后跳转到订单明细详情页。这需要建立两个实体之间的 association同时在 annotationUI.lineItem里设置type: #FOR_LINK并配置 Fiori Elements 的应用导航属性。在示例中我没有做这个复杂跳转但如果你用 Fiori 参考应用模板模板会自动带上不必手写。如果你想从零开始加建议先跑通一个简单 association再处理参数传递。4. 实操中的常见问题与排查技巧4.1 激活报错语法检查与依赖顺序刚接触 RAP最常见的问题就是激活顺序和语法错误。例如视图还没激活就激活行为定义系统会提示找不到引用对象。解决办法严格按依赖顺序激活CDS 视图、行为定义、行为实现、服务定义、服务绑定每一步都对照 ADT 的问题列表。激活报错时双击错误条目会跳到具体代码行大多数都是字段名拼写、关联名称错误、缺少 key 之类的。另一个容易踩的坑旧版 CDS view 语法里用ObjectModel.query.implementedBy标记这是老语法新版 view entity 比较简单直接定义字段即可。如果你不小心把别人旧的 CDS 视图 copy 过来可能因为版本兼容问题出一堆没头没脑的报错。所以示例代码尽量选 view entity别用现在已经过时的 SELECT list 加 annotation 混合套路。4.2 数据权限PFCG 与 DCL 的坑这个坑我在示例里也遇到了。刚开始为了快速跑通我在 CDS 视图上写了AccessControl.authorizationCheck: #NOT_REQUIRED这样谁访问都能看到数据演示很顺利。但临到上线前业务主管要求严格按销售组织隔离数据销售一部仅能看到自己组织的数据二部只能看到二部的。这时就要引入 DCLData Control Language。RAP 默认会检查访问权限如果你不建 DCL所有数据都会被拦截结果就是服务能访问但结果集为空。在权限设计里可以新建一个 DCL 对象通过 PFCG 角色推送授权字段给用户。比如 CDS 视图里EndUserData.denied用来标记禁止访问整个实体但更常见的做法是在 DCL 里写select where SalesOrg aspect pfcg_auth(SALES_ORG)。很多初学者数据出不来不是代码问题而是权限模型压根没建导致 RAP 把所有数据都挡住。4.3 性能优化避免慢查询和加载卡顿报表型 RAP 应用面对的典型场景是“数据量可能很大”。如果你把整张 VBAK 表直接作为根视图不加任何过滤Fiori 第一次加载时可能请求几万条记录页面会卡死。优化手段有几个在 CDS 视图用Consumption.filter标记筛选条件Fiori 会把筛选需求下推给后端后端通过 where 条件执行 DB 查询而不是先把全量数据拉到前端再过滤如果业务上只允许查看已审批订单就直接在 CDS 视图 where 里限制合理使用 association 避免 N1 的性能风险对高频查询字段建数据库索引并保证 CDS 视图能正确使用唯一索引。尽量避免在 CDS 里做过于复杂的字符串拼接、类型转换后再过滤这些计算字段会拖慢查询。如果你真的需要海量数据分析比如千万级订单那就应该评估 SAP Analytics Cloud、BW/4HANA而不是硬用 RAP。RAP 适合操作型报表例如日运营看板、待办列表不适合大而全的数据仓库式报表。4.4 扩展建议从只读报表升级到完整应用示例完成后至少有三个扩展方向值得留意。第一增加“导出 Excel” action让报表能直接输出当前筛选结果第二增加“审批流”或“状态更新”行为让报表不仅读还能承载业务操作第三把服务 OData V2 改成 V4方便未来上 SAP BTP 做外部集成。之后我又试了一下在行为定义里加了 action让用户可以在列表上勾选订单一键发送提醒给销售员。这在传统 ALV 里也能做但 RAP 的优势是前端自动生成复选框和按钮后端行为实现里可以直接拿到选中的实体 key不用自己写复杂的表格交互。有了这层经验我对 RAP 从“只能看”到“能操作”的转变也更清楚了。另外如果你的报表之后要接入 SAP Analytics Cloud建议走 CDS Analytical Query 而不是 RAP 的行为定义SAC 更适配分析模型。当然这已经属于另一个话题了。5. 报表示例做完后我沉淀下的几条经验5.1 RAP 报表最适合的三类场景通过完整跑完这个示例我认为 RAP 报表并不适合所有报表它最适合三类场景第一类是面向业务人员的操作型报表比如订单待处理、采购审批待办、设备维修工单数据量在百万以内需要实时读取数据库并且希望能在 Fiori 上直接操作第二类是基础设置维护界面例如定价条件、客户主数据显示这类虽然不叫报表但结构上也是列表 明细第三类是需要把 SAP 数据以 OData 服务方式开放给外部集成的场景RAP 可以把报表做成一个 API供 BTP 或第三方系统消费。如果你是做“经营分析大屏”或“高管驾驶舱”数据模型复杂、涉及大量汇总计算、需要多维分析那 RAP 不是最优解SAP Analytics Cloud、BW/4HANA 这些分析平台会更合适。RAP 报表的优势在“离业务更近”——直接读 SAP 标准表能拿到原始数据也能和事务操作打通这是分析平台做不到的。因此报表示例虽然简单但定位清晰。5.2 从示例到项目化落地团队协作与命名规范最后一个环节是项目化落地。示例里我喜欢用语义化的字段名比如SalesOrder、SalesOrg这对团队协作非常重要。如果你把 CDS 字段直接叫VBELN、VKORGFiori 界面上的标签会非常难懂而且后续生成 OData 服务时外部系统看到的 API 字段也不够友好。建议从一开始就定义一套命名规范CDS 视图以ZC_开头字段用业务意义命名行为实现类统一加_ACTION后缀服务定义统一加_SRV。这样每个对象的作用一眼能看出来。另外开发的时候一定要用传输请求管理不要把所有东西都塞到同一个请求里。RAP 对象依赖链条很长从 CDS 到行为到服务如果拆成多个请求到测试系统激活时可能会因为顺序不对挂掉。我习惯把示例相关的对象分成两个请求一个装数据模型和权限一个装服务绑定和 Fiori 配套。这样传输失败时问题定位起来也快很多。个人经验是这个报表示例花在环境调试上的时间比真正写 CDS 和行为的时间还长所以环境配置和依赖顺序真的不能图省事。如果你也想练手建议从我这个销售订单报表示例开始先建 CDS再建行为定义最后服务绑定和 Fiori 预览。整个过程用不了半天但能把 RAP 的核心链路摸得明明白白。等你看懂了这张报表是怎么从数据库一步步变成手机上的 Fiori 列表再回头处理更复杂的业务逻辑心里就有底了。
返回列表