当前位置: 首页 > article >正文

ABAP语言的动态编程(4) - 综合案例:管理费用明细表

本篇来实现一个综合案例:管理费用明细表。报表在实际项目中,也有一定的参考意义,一方面展示类似的报表,比如管理费用、研发费用等费用的明细,使用业务比较习惯的展示格式;另一方面正好综合运用前面学习的动态编程知识点。

本系列博客的链接:

ABAP语言的动态编程 (1)-CSDN博客

ABAP语言的动态编程(2) - field symbol 的典型用法_filed symbol-CSDN博客

ABAP语言的动态编程(3) - data reference 对象_abap for in a reference table-CSDN博客

本篇的主要要点:

  • 期间费用等类似报表的取数方法
  • 通过 RTTS 实现动态内表
  • 如何删除动态内表的空值
  • 通过 SALV 输出动态内表

本例实现的功能:

选择屏幕:

输出界面:

程序总体逻辑

  • frm_get_data: 获取数据
  • frm_add_dyn_fields:根据成本中心设置动态内表格式
  • frm_process_data: 将数据加工成输出格式所需的格式
  • frm_alv_show: 在 ALV 中显示数据

数据获取

数据比较简单,直接从 FAGLFLEXT 汇总表获取,也可以直接从 ACDOCA 表获取。

form frm_get_data .ranges: lr_racct for faglflext-racct.lr_racct[] = value #( ( sign = 'I' option = 'CP' low = '0080*' ) ).* 从FAGLFLEXT获取数据select rbukrs             "公司代码, racct as saknr    "科目号, rcntr as kostl    "成本中心, hsl01             "1月, hsl02             "2月, hsl03, hsl04, hsl05, hsl06, hsl07, hsl08, hsl09, hsl10, hsl11, hsl12from v_faglflext_viewwhere rbukrs in @s_bukrsand ryear eq @p_ryearand rldnr eq '0L'and rrcty eq '0'and rvers eq '001'and racct in @lr_racctinto table @data(lt_faglflext).* 按照gs_list格式对数据进行合计loop at lt_faglflext into data(ls_faglflext).move-corresponding ls_faglflext to gs_list.collect gs_list into gt_list.clear: ls_faglflext, gs_list.endloop." 获取会计科目描述select distinct saknr from @lt_faglflext as t into table @data(lt_saknr) .select s~saknr,s~txt20from skat as sinner join @lt_saknr as t on s~saknr eq t~saknrwhere s~ktopl eq '1000'and s~spras eq @sy-languinto table @data(lt_skat).sort lt_skat by saknr." 获取成本中心描述select distinct kostl from @lt_faglflext as t into table @data(lt_cntr). " cost centerselect c~kostl, c~ktextfrom cskt as cinner join @lt_cntr as  d  on c~kostl eq d~kostlwhere c~kokrs eq '1000' and c~spras eq @sy-langu and c~datbi ge @sy-datuminto table @gt_cskt.sort gt_cskt by kostl." 将科目描述和成本中心描述填充到gt_listloop at gt_list into gs_list.if line_exists( lt_skat[ saknr = gs_list-saknr ] ).gs_list-txt20 = lt_skat[ saknr = gs_list-saknr ]-txt20.endif.if line_exists( gt_cskt[ kostl = gs_list-kostl ] ).gs_list-ltext = gt_cskt[ kostl = gs_list-kostl ]-ktext.endif.modify gt_list from gs_list.clear gs_list.endloop.
endform.

设置动态内表

输出的格式中,有些字段是确定的,通过 data 语句直接定义。而每一个成本中心都需要增加一个动态列,在程序中动态设定,关键就是构建动态内表的组件 (gt_component, 类型为 cl_abap_structdescr=>component_table

预先定义的部分:

* 用于数据输出
data: begin of gs_output,rbukrs  type faglflext-rbukrs, "公司代码racct   type faglflext-racct,  "科目号txt20   type skat-txt20,       "科目名称hsl_sum type faglflext-hsl12,  "合计end of gs_output.
data gt_output like standard table of gs_output.

程序动态设置的部分:

*--------------------------------------------------------
* 基于有数据发生的成本中心,将成本中心加到输出字段中
*--------------------------------------------------------
form frm_add_dyn_fields .
data: ls_dref type ref to data,lt_dref type ref to data.data: lo_strcut_descr type ref to cl_abap_structdescr,lo_table_descr  type ref to cl_abap_tabledescr.data: lv_index     type string,lv_fieldname type string.data lv_reffield type faglflext-hsl01.free: gt_component.* 基于gs_outputlo_strcut_descr ?= cl_abap_structdescr=>describe_by_data( gs_output ).gt_component = lo_strcut_descr->get_components( ).* 根据成本中心列表增加动态字段loop at gt_cskt into gs_cskt.lv_index = sy-tabix.lv_fieldname = gc_dyn_prefix && lv_index .condense lv_fieldname no-gaps.clear gs_component.gs_component-name = lv_fieldname.gs_component-type = cast #( cl_abap_elemdescr=>describe_by_data( lv_reffield ) ).append gs_component to gt_component.endloop."根据字段目录创建动态结构类型lo_strcut_descr ?= cl_abap_structdescr=>create( p_components = gt_component ).lo_table_descr ?= cl_abap_tabledescr=>create( p_line_type = lo_strcut_descr ).create data lt_dref type handle lo_table_descr.create data ls_dref type handle lo_strcut_descr.assign ls_dref->* to <dyn_wa>.assign lt_dref->* to <dyn_table>.
endform.

程序运行的时候,gt_component 的结构和内容如下 (每一行的关键是 name 和 type):

根据输出格式加工数据

因为程序只是获取单月的数据,而从 FAGLFLEXT 表取数底表格式(每个月 1 列)决定了有可能当月并没有数据,所以代码中增加了删除空行的代码。静态内表删除内表比较简单,而动态内表因为列名是在程序中生成的,所以处理起来相对麻烦一些。

form frm_process_data .data lv_src_fldname type fieldname.data lv_target_fldname type fieldname.data gv_tabix like sy-tabix.lv_src_fldname = 'HSL' && p_rpmax. " 基于选择屏幕的月份condense lv_src_fldname.*-------------------------------------------------------------
* 行转列,同时进行聚合计算
*-------------------------------------------------------------loop at gt_list into gs_list.move-corresponding gs_list to <dyn_wa>." 从1到12月份,获取选择屏幕所在月份的数据assign component lv_src_fldname of structure gs_list to field-symbol(<lfs_source>)." 找到对应成本中心的indexread table gt_cskt transporting no fields with key kostl = gs_list-kostl binary search.if sy-subrc = 0.gv_tabix = sy-tabix.lv_target_fldname = gc_dyn_prefix && gv_tabix.condense lv_target_fldname.  " 对应的动态列名" 找到成本中心对应的字段assign component lv_target_fldname of structure <dyn_wa> to field-symbol(<lfs_target>).<lfs_target> = <lfs_source>." 合计字段assign component 'HSL_SUM' of structure <dyn_wa> to field-symbol(<lfs_sum>).<lfs_sum> = <lfs_source>.endif.collect <dyn_wa> into <dyn_table>.clear:  gs_list, <dyn_wa>.endloop.*-----------------------------------------------------
* 删除空行
*-----------------------------------------------------data lt_component like gt_component.lt_component[] = gt_component[]." 删除不相关行delete lt_component where name = 'RBUKRS'.delete lt_component where name = 'SAKNR'.delete lt_component where name = 'TXT20'.loop at <dyn_table> assigning <dyn_wa>.data(lv_is_empty) = abap_true." lt_component保存了所有gt_output的字段,删除了RBUKRS, SAKNR和TXT20loop at lt_component assigning field-symbol(<ls_comp>).assign component <ls_comp>-name of structure <dyn_wa> to field-symbol(<ls_field>).if <ls_field> is not initial.lv_is_empty = abap_false.exit.endif.endloop.if lv_is_empty = abap_true.delete <dyn_table>.endif.endloop.endform.

ALV 输出

使用 SALV (CL_SALV_TABLE)在 ALV 中显示数据。

form frm_alv_set_style tables t_data type standard table.data ls_program type salv_s_layout_key."结构包含布局变式所属程序名data lv_tabix like sy-tabix.data lv_fieldname type fieldname.ls_program-report = sy-repid.* 实例化SALVcl_salv_table=>factory(importing r_salv_table = gr_alv_tablechanging t_table = t_data[] ).* 设置动态字段的field catalogdata(lr_alv_columns) = gr_alv_table->get_columns( ).loop at gt_cskt into gs_cskt.lv_tabix = sy-tabix.lv_fieldname = gc_dyn_prefix && lv_tabix.condense lv_fieldname no-gaps.perform frm_set_field using lr_alv_columns lv_fieldname gs_cskt-ktext '' ''.clear gs_cskt.endloop.* 设置合计字段的显示perform frm_set_field using lr_alv_columns 'HSL_SUM' '金额合计' '' ''.* 优化列宽lr_alv_columns->set_optimize( 'X' ).* 设置 toolbargr_alv_table->get_functions( )->set_all(  ).* 设置ALV布局data(lr_layout) = gr_alv_table->get_layout( ).lr_layout->set_key( ls_program ).                                "设置布局保存为变式时基于此Keylr_layout->set_save_restriction( cl_salv_layout=>restrict_none )."允许保存布局为变式* 设置条纹显示gr_alv_table->get_display_settings(  )->set_striped_pattern( abap_true ).
endform.

frm_alv_set_style 调用了 frm_set_field:

form frm_set_field  using uo_cols type ref to cl_salv_columns_tablevalue(uv_fieldname)     " 字段名value(uv_text)          " 字段文本value(uv_length)        " 输出宽度value(uv_istechnical).  " 是否隐藏data: lo_col    type ref to cl_salv_column_table,lo_agg    type ref to cl_salv_aggregations,lv_text_s type scrtext_s,lv_text_m type scrtext_m,lv_text_l type scrtext_l.lo_col ?= uo_cols->get_column( uv_fieldname ).* 是否隐藏if not uv_istechnical is initial.lo_col->set_technical( abap_true ). "隐藏endif.* 设置显示字段文本if not uv_text is initial.lv_text_s = uv_text.lv_text_m = uv_text.lv_text_l = uv_text.lo_col->set_short_text( lv_text_s ).lo_col->set_medium_text( lv_text_m ).lo_col->set_long_text( lv_text_l ).endif.* 设置输出宽度if not uv_length is initial.lo_col->set_output_length( uv_length ).endif.lo_col->set_zero(  '' ).
endform.

调用 display() 方式实现输出:

form frm_alv_show  tables   t_data type standard table.perform frm_alv_set_style tables t_data[].gr_alv_table->display( ).
endform.

为了方便阅读,正文给出主要的代码,完整的代码请参考链接。

源码

ABAP动态编程-管理费用明细表

相关文章:

ABAP语言的动态编程(4) - 综合案例:管理费用明细表

本篇来实现一个综合案例&#xff1a;管理费用明细表。报表在实际项目中&#xff0c;也有一定的参考意义&#xff0c;一方面展示类似的报表&#xff0c;比如管理费用、研发费用等费用的明细&#xff0c;使用业务比较习惯的展示格式&#xff1b;另一方面正好综合运用前面学习的动…...

通过Geopandas进行地理空间数据可视化

目录 引言 安装与导入 数据加载与探索 数据预处理 基本地图可视化 添加其他数据到地图上 空间分析与查询 地图叠加与分组 空间缓冲区 交互式地图可视化 实际应用案例 城市规划 环境监测 结论 引言 在数据科学领域,地理空间数据可视化扮演着至关重要的角色。它不…...

【大语言模型_5】xinference部署embedding模型和rerank模型

一、安装xinference pip install xinference 二、启动xinference ./xinference-local --host0.0.0.0 --port5544 三、注册本地模型 1、注册embedding模型 curl -X POST "http://localhost:5544/v1/models" \ -H "Content-Type: application/json" \…...

CSS3学习教程,从入门到精通,CSS3 选择器权重问题语法知识点及案例代码(5)

CSS3 选择器权重问题语法知识点及案例代码 一、选择器权重概述 在 CSS 中&#xff0c;当多个选择器同时匹配同一个元素时&#xff0c;浏览器会根据选择器的权重来决定哪个样式生效。权重高的选择器的样式会覆盖权重低的选择器的样式。 二、选择器权重计算规则 1. 内联样式&…...

在Vue3中使用Echarts的示例

1.常用-引用ts文件方式 1.1 导出ts文件-一个简单的柱状图 export const baseBarChart (xdata: string[], data: number[][], legendData: string[]) > {if (data.length 0) {return noData;}// 定义颜色数组const color [#00CCCC,#FF9900,#1677DC,#FF6666,#B366FF,#666…...

Three.js 阴影 (Shadow) 知识点整理

阴影主要由 castShadow 和 receiveShadow 控制&#xff0c;并通过不同类型的光源 (DirectionalLight、SpotLight、PointLight) 生成。我们将系统地整理与阴影相关的知识点。 1️⃣ 基础概念 castShadow &#x1f3ad;&#xff1a;物体是否投射阴影。receiveShadow &#x1f3d…...

GHCTF web方向题解

upload?SSTI! import os import refrom flask import Flask, request, jsonify,render_template_string,send_from_directory, abort,redirect from werkzeug.utils import secure_filename import os from werkzeug.utils import secure_filenameapp Flask(__name__)# 配置…...

Logic-RL:小参数qwen模型复现DeepSeek R1 zero

最近很多参照DeepSeek模型训练推理模型的工作,本文将深入 “Logic-RL: Unleashing LLM Reasoning with Rule-Based Reinforcement Learning” 的论文,该论文提出了一种Rule-Based Reinforcement Learning, Logic-RL框架,旨在提升 LLM 的逻辑推理能力,在qwen2.5-7b-instruct…...

CVE-2017-5645(使用 docker 搭建)

介绍: 是一个与 Apache Log4j2 相关的安全漏洞,属于远程代码执行,它可能允许攻击者通过构造恶意的日志信息 在目标系统上执行任意代码 Log4j2 介绍 Log4j2 是 Apache 的一个日志记录工具,属于 Java 应用的日志框架,它是 Log4j 的升级版,性能更好,功能更多.它被广泛的适用于 J…...

conda install 和 pip install 的区别

conda install 和 pip install 是两个常用的包安装命令&#xff0c;但它们在很多方面存在差异。 1. 所属管理系统不同 1.1 conda install conda install 是Anaconda和Miniconda发行版自带的包管理工具 conda 的安装命令。conda 是一个跨平台的开源包管理系统和环境管理系统&…...

蓝桥杯备考:特殊01背包问题——》集合subset

我们划分成两个集合&#xff0c;实际上我们只需要看一部分就行了&#xff0c;也就是从集合的所有元素里挑出恰好满足集合总和的一半儿&#xff0c;当然&#xff0c;如果我们的集合总和是奇数的话&#xff0c;我们是无论如何也挑不出刚好一半儿的&#xff0c;因为我们没有小数&a…...

设计模式之外观模式:原理、实现与应用

引言 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过提供一个统一的接口来简化复杂系统的使用。外观模式隐藏了系统的复杂性&#xff0c;使得客户端可以通过一个简单的接口与系统交互。本文将深入探讨外观模式的原理、实现方式以及实…...

C#设计模式Demo——MVC

设计模式Demo——MVC 1.View1.1页面示例1.2View代码1.3修改界面以及代码 2.Model3.Controller4.数据结构5.枚举类型6.工具类6.1缓存信息6.2扩展类. 文件结构图 1.View 1.1页面示例 1.2View代码 using System; using System.Data; using System.Windows.Forms; using MVC模式…...

【sql靶场】第18-22关-htpp头部注入保姆级教程

目录 【sql靶场】第18-22关-htpp头部注入保姆级教程 1.回顾知识 1.http头部 2.报错注入 2.第十八关 1.尝试 2.爆出数据库名 3.爆出表名 4.爆出字段 5.爆出账号密码 3.第十九关 4.第二十关 5.第二十一关 6.第二十二关 【sql靶场】第18-22关-htpp头部注入保姆级教程…...

LabVIEW棉花穴播器排种自动监测系统

一、项目背景与行业痛点 1. 农业需求驱动 我国棉花主产区&#xff0c;种植面积常年超250万公顷&#xff0c;传统人工播种存在两大核心问题&#xff1a; 效率瓶颈&#xff1a;人均日播种面积不足0.5公顷&#xff0c;难以匹配规模化种植需求&#xff1b; 精度缺陷&#xff1a;人…...

【程序人生】成功人生架构图(分层模型)

文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层&#xff1a;调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…...

golang开发支持onlyoffice的token功能

一直都没去弄token这块&#xff0c;想着反正docker run的时候将jwt置为false即可。 看了好多文章&#xff0c;感觉可以试试&#xff0c;但是所有文件几乎都没说思路。 根据我的理解和成功的调试&#xff0c;思路是&#xff1a; 我们先定义2个概念&#xff0c;一个是文档下载…...

Qt for WebAssembly程序中文乱码问题处理过程

一、环境 操作系统DeepinV23 Qt版本6.8.2 编程语言C 二、问题现象 Qt for WebAssembly应用在浏览器页面上英文字母显示正常&#xff0c;中文显示为乱码。 经测试分析原因为默认字体不能正常显示汉字。 三、处理过程 1.准备中文字体文件 从Windows下复制宋体简体字体文件…...

速通大厂测开

最近26届暑期实习招聘和25届春招已经开始&#xff0c;测开学习圈也有同学拿到offer了 今天分享一位25届秋招圈友快速拿到大厂测开offer的经历&#xff0c;希望对大家有所帮助 我是某211本科生&#xff0c;在去年暑假准备考研的间隙意外收获了某大厂测开实习offer&#xff0c;…...

基于Netty实现高性能HTTP反向代理

以下将分步骤实现一个基于Netty的高性能HTTP反向代理&#xff0c;支持动态路由、负载均衡和基础鉴权功能。 1. 项目依赖配置&#xff08;Maven&#xff09; 2. 定义路由规则 3. 实现HTTP反向代理服务端 4. 实现反向代理处理器 5. 实现基础鉴权 6. 性能优化策略 连接池管理…...

Spring Boot集成MyBatis与MySQL

Spring Boot集成MyBatis与MySQL开发全攻略 一、前言&#xff1a;现代Java持久层开发的选择 在微服务架构盛行的今天&#xff0c;Spring Boot以其"约定优于配置"的理念成为Java开发的事实标准。结合MyBatis这一灵活高效的ORM框架和MySQL这一成熟稳定的关系型数据库&…...

【NLP 37、实践 ⑨ NER 命名实体识别任务 LSTM + CRF 实现】

难过的事情我要反复咀嚼&#xff0c;嚼到它再也不能困扰我半分 —— 25.3.13 数据文件&#xff1a; 通过网盘分享的文件&#xff1a;Ner命名实体识别任务 链接: https://pan.baidu.com/s/1fUiin2um4PCS5i91V9dJFA?pwdyc6u 提取码: yc6u --来自百度网盘超级会员v3的分享 一、配…...

再学:函数可见性、特殊函数、修饰符

目录 1.可见性 2.合约特殊函数 constructor && getter 3. receive && fallback 4.view && pure 5.payable 6.自定义函数修饰符 modifier 1.可见性 public&#xff1a;内外部 private&#xff1a;内部 external&#xff1a;外部访问 internal&…...

基于Spring Boot的项目申报系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

Web元件库 ElementUI元件库+后台模板页面(支持Axure9、10、11)

Axure是一款非常强大的原型设计工具&#xff0c;它允许设计师和开发者快速创建高保真原型&#xff0c;以展示应用或网站的设计和功能。通过引入各种元件库&#xff0c;如ElementUI元件库&#xff0c;可以极大地丰富Axure的原型设计能力&#xff0c;使其更加贴近实际开发中的UI组…...

若依excel工具类导出excel模板数据带下拉映射

导出模板代码&#xff0c;原理是combo属性 传递一个数组 里面是label下拉数组。 Overridepublic void downloadTemplate(HttpServletResponse response) {ExcelUtil<ThMachineryManageExcel> util new ExcelUtil<>(ThMachineryManageExcel.class);List<SysDist…...

孜然SEO静态页面生成系统V1.0

孜然SEO静态页面生成系统&#xff0c;1秒生成上万个不同的静态单页系统&#xff0c;支持URL裂变采集&#xff0c;采集的内容不会重复&#xff0c;因为程序系统自带AI重写算法&#xff0c;AI扩写算法&#xff0c;可视化的蜘蛛池系统让您更清楚的获取到信息&#xff01; 可插入二…...

Python爬虫-爬取汽车之家燃油车月销量榜数据

前言 本文是该专栏的第48篇,后面会持续分享python爬虫干货知识,记得关注。 在本文中,笔者已整理18篇汽车平台相关的爬虫项目案例。对此感兴趣的同学,可以直接翻阅查看。 而本文,笔者将以汽车之家平台为例子。基于Python爬虫,实现批量爬取全部“燃油车”的月销量数据。废…...

Blender-MCP服务源码3-插件开发

Blender-MCP服务源码3-插件开发 Blender-MCP服务源码解读-如何进行Blender插件开发 1-核心知识点 1&#xff09;使用Blender开发框架学习如何进行Blender调试2&#xff09;学习目标1-移除所有的Blender业务-了解如何MCP到底做了什么&#xff1f;3&#xff09;学习目标2-模拟MC…...

C语言和C++到底有什么关系?

C 读作“C 加加”&#xff0c;是“C Plus Plus”的简称。 顾名思义&#xff0c;C 就是在 C 语言的基础上增加了新特性&#xff0c;玩出了新花样&#xff0c;所以才说“Plus”&#xff0c;就像 Win11 和 Win10、iPhone 15 和 iPhone 15 Pro 的关系。 C 语言是 1972 年由美国贝…...