SAP-ABAP: 深入浅出 SAP 经典可执行程序:从零开始掌握

SAP-ABAP:深入浅出 SAP 经典可执行程序:从零开始掌握

在 SAP ABAP 开发的世界里,几乎每一位开发者的第一行代码都写在一个可执行程序里。它简单、直观、功能强大,是理解 SAP 开发模式的绝佳起点。本文将带你全面了解经典可执行程序的方方面面。


一、什么是可执行程序?

可执行程序(Executable Program)是 SAP ABAP 中最基础、最常用的程序类型之一。它的核心特征可以用一句话概括:可以不依赖任何事务代码,直接在 ABAP 编辑器(SE38)中点击运行按钮(F8)来执行

在 ABAP 程序类型分类中,可执行程序的类型值为 1。与模块池(类型 M)、函数组(类型 F)、类池(类型 K)等其他程序类型不同,可执行程序拥有一个独立运行的入口,不需要通过事务代码或屏幕调用即可启动。

可执行程序与报表程序的关系

很多人会混淆"可执行程序"和"报表程序"这两个概念。严格来说:

  • 可执行程序是程序类型层面的技术分类
  • 报表程序是功能层面的描述,指用于输出数据列表的程序

实际上,所有的报表程序都是可执行程序,但可执行程序的应用范围远不止报表------它还可以用于数据导入、批量处理、后台作业等场景。因此,"可执行程序"这个名称更能准确反映其技术本质。


二、可执行程序的核心特点

2.1 独立运行,无需事务码

这是可执行程序最鲜明的特征。在 SE38 中输入程序名,按 F8 即可运行。当然,如果你希望将它挂到 SAP 菜单上或分配给某个权限角色,也可以随时为它创建事务码(通过 SE93),但这并非必须。

2.2 预定义事件块驱动

可执行程序的执行流程由一系列预定义的事件块控制。系统会按照固定的顺序自动调用这些事件块,开发者只需要在对应的事件块中编写业务逻辑即可。这种设计让代码结构清晰、易于维护。

2.3 自带选择屏幕

可执行程序天然支持选择屏幕(Selection Screen)。开发者可以使用 PARAMETERSSELECT-OPTIONS 等语句定义用户输入界面,无需编写复杂的 Dynpro 屏幕代码。当用户运行程序时,系统会自动显示这个选择屏幕,供用户输入查询条件。

2.4 支持逻辑数据库

逻辑数据库(Logical Database)是 SAP 提供的一种标准化数据提取工具。可执行程序可以直接关联一个逻辑数据库,从而大幅简化数据读取逻辑------你不需要关心具体从哪些表中读取数据、如何处理表之间的关联关系,逻辑数据库会帮你完成。

2.5 可后台调度

可执行程序支持通过 SM36 事务码配置为后台作业(Background Job),可以定时、定期或在特定事件触发时自动运行。这一特性使其成为批量处理任务的理想载体。


三、创建一个可执行程序(手把手教程)

让我们从一个最经典的"Hello World"开始,逐步创建一个完整的可执行程序。

第 1 步:启动事务码 SE38

在 SAP GUI 的命令栏中输入 SE38,进入 ABAP 编辑器(也称为 ABAP 工作台)。

第 2 步:输入程序名称并创建

在"程序"字段中输入一个程序名。强烈建议以 Z 或 Y 开头------这是 SAP 预留的客户命名空间,可以确保你的程序不会与 SAP 标准程序或其他客户程序发生命名冲突。

例如:Z_HELLO_WORLD

输入后,点击"创建"按钮。

第 3 步:选择程序类型

系统会弹出"ABAP:程序属性"窗口。在这里:

  • 类型 :选择 "可执行程序"(Executable Program)
  • 标题 :输入一个简短的描述,如 我的第一个ABAP程序

其他字段(如"应用程序组件"、"逻辑数据库"等)可以暂时留空。

点击"保存",系统会提示你选择开发类(Package)。如果是练习用途,可以选择本地对象($TMP)。

第 4 步:编写代码

在编辑器中输入以下两行代码:

abap 复制代码
REPORT Z_HELLO_WORLD.
WRITE 'Hello, SAP World!'.
  • REPORT 语句是每个可执行程序的必备语句,用于声明程序名称。
  • WRITE 语句用于在屏幕上输出内容。

第 5 步:激活并运行

  • 点击激活 按钮(或按 Ctrl + F3),系统会检查语法是否正确。如果没有错误,程序会被激活(生成运行时对象)。
  • 激活成功后,点击直接处理 按钮(或按 F8),即可运行程序。

你会看到屏幕上输出:

复制代码
Hello, SAP World!

恭喜你,你的第一个 SAP 可执行程序已经成功运行!


四、可执行程序的事件块详解

可执行程序的执行流程是由一系列事件块驱动的。理解这些事件块的执行顺序,是编写高质量程序的基础。

4.1 完整的事件块及执行顺序

abap 复制代码
REPORT Z_EVENT_DEMO.

" 1. LOAD-OF-PROGRAM - 程序加载时执行(最先)
LOAD-OF-PROGRAM.
  WRITE: / '1. LOAD-OF-PROGRAM'.

" 2. INITIALIZATION - 选择屏幕显示之前执行
INITIALIZATION.
  WRITE: / '2. INITIALIZATION'.

" 定义选择屏幕参数
PARAMETERS: p_date TYPE sy-datum DEFAULT sy-datum.

" 3. AT SELECTION-SCREEN - 用户点击执行按钮后,选择屏幕输入验证时执行
AT SELECTION-SCREEN.
  IF p_date < sy-datum.
    MESSAGE '日期不能早于今天' TYPE 'E'.
  ENDIF.

" 4. START-OF-SELECTION - 数据选择开始前执行(最常用的事件)
START-OF-SELECTION.
  WRITE: / '4. START-OF-SELECTION'.
  WRITE: / '用户输入的日期是:', p_date.

" 5. END-OF-SELECTION - 数据选择结束后、列表输出前执行
END-OF-SELECTION.
  WRITE: / '5. END-OF-SELECTION'.

4.2 各事件块的用途说明

事件块 触发时机 典型用途
LOAD-OF-PROGRAM 程序被加载到内存时 初始化全局数据、加载缓存等(较少使用)
INITIALIZATION 选择屏幕显示之前 设置选择屏幕字段的默认值、动态修改选择屏幕属性
AT SELECTION-SCREEN 用户输入选择条件后、点击执行时 校验用户输入、动态改变选择屏幕行为
START-OF-SELECTION 数据选择开始前 核心业务逻辑:数据库查询、数据计算等(最常用)
END-OF-SELECTION 数据选择结束后、列表输出前 汇总统计、输出额外信息

💡 实践建议 :90% 以上的业务逻辑都可以写在 START-OF-SELECTION 中。其他事件块只在有特殊需求时才使用。

4.3 选择屏幕相关的事件块

除了上述核心事件,可执行程序还支持更多与选择屏幕交互的事件:

  • AT SELECTION-SCREEN ON p_field:针对特定选择屏幕字段的校验
  • AT SELECTION-SCREEN OUTPUT:选择屏幕显示时触发,可动态修改屏幕元素属性
  • AT SELECTION-SCREEN ON HELP-REQUEST FOR p_field:用户按 F1 帮助时触发
  • AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_field:用户按 F4 搜索帮助时触发

五、选择屏幕开发

选择屏幕是可执行程序与用户交互的主要界面。通过简单的 ABAP 语句,就能创建出功能强大的查询界面。

5.1 基本元素:PARAMETERS 与 SELECT-OPTIONS

PARAMETERS:定义单个值的输入字段

abap 复制代码
PARAMETERS: p_ebeln TYPE ekko-ebeln OBLIGATORY,  " 必输
            p_bukrs TYPE bkpf-bukrs DEFAULT '1000',  " 默认值
            p_date  TYPE sy-datum.  " 日期

SELECT-OPTIONS:定义范围输入字段(相当于四个值的组合:低值、高值、选项、符号)

abap 复制代码
SELECT-OPTIONS: s_ebeln FOR ekko-ebeln,  " 采购订单范围
                s_budat FOR bkpf-budat.  " 过账日期范围

5.2 选择屏幕的布局控制

代码块 :使用 SELECTION-SCREEN BEGIN OF BLOCKEND OF BLOCK 将字段分组

abap 复制代码
SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-001.
PARAMETERS: p_ebeln TYPE ekko-ebeln.
SELECT-OPTIONS: s_ebelp FOR ekpo-ebelp.
SELECTION-SCREEN END OF BLOCK block1.

注释行 :使用 SELECTION-SCREEN COMMENT 添加说明文字

abap 复制代码
SELECTION-SCREEN COMMENT /1(30) text-002.  " 在第1列输出30个字符长的说明

5.3 动态修改选择屏幕

通过 AT SELECTION-SCREEN OUTPUT 事件,可以动态修改选择屏幕字段的属性:

abap 复制代码
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    IF screen-name = 'P_EBELN'.
      screen-input = 0.  " 将字段设为不可输入
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.

六、逻辑数据库的使用

逻辑数据库(Logical Database)是一种将数据读取逻辑封装好的工具。使用逻辑数据库,开发者可以:

  • 避免编写复杂的数据库连接逻辑(如多表关联、数据筛选)
  • 自动获得选择屏幕(逻辑数据库自带的筛选条件)
  • 利用系统内置的缓存和性能优化

6.1 如何指定逻辑数据库

在创建程序时,在程序属性窗口的"逻辑数据库"字段中选择一个逻辑数据库。例如:

  • F1S:财务凭证数据库
  • PNP:HR 人员主数据数据库
  • SDF:销售与分销数据库

6.2 逻辑数据库的事件块

使用逻辑数据库时,还需要额外了解几个事件块:

  • GET 表名:每次读取到一条数据时触发
  • GET 表名 LATE:该表所有数据处理完后触发
  • PUT 表名:将数据传递给报表程序

示例(使用财务凭证逻辑数据库 F1S):

abap 复制代码
REPORT Z_F1S_DEMO.

GET bkpf.  " 每读取一个财务凭证抬头时触发
  WRITE: / bkpf-bukrs, bkpf-belnr, bkpf-gjahr.

GET bseg.  " 每读取一个凭证行项目时触发
  WRITE: / bseg-buzei, bseg-hkont, bseg-dmbtr.

七、后台调度:让程序自动运行

可执行程序的一大优势是可以配置为后台作业,实现无人值守的批量处理。

7.1 创建后台作业(SM36)

  1. 输入事务码 SM36
  2. 在"作业名称"字段输入一个有意义的名称
  3. 点击"步骤"按钮,在步骤列表中指定要运行的程序名
  4. 点击"开始条件"按钮,定义作业的执行时间(立即、定时、周期性)
  5. 保存后,作业即被调度

7.2 监控后台作业(SM37)

  • 使用事务码 SM37 查看所有后台作业的状态
  • 常见状态:计划中(Scheduled)、已发布(Released)、就绪(Ready)、活跃(Active)、已完成(Finished)、已取消(Cancelled)
  • 可以通过作业日志查看程序的输出结果

7.3 后台作业的最佳实践

  • 在程序中使用 WRITE 语句输出执行日志,这些内容会写入作业日志,方便排查问题
  • 避免在后台作业中使用依赖用户交互的语句(如 POPUP 弹窗)
  • 设置合适的开始时间,避免在系统高峰期运行

八、典型应用场景

8.1 数据报表

这是可执行程序最常见的用途。结合 ALV(ABAP List Viewer),可以快速开发出专业的数据报表。

abap 复制代码
REPORT Z_PURCHASE_REPORT.

TABLES: ekko, ekpo.
DATA: gt_ekko TYPE TABLE OF ekko.

SELECT-OPTIONS: s_ebeln FOR ekko-ebeln.

START-OF-SELECTION.
  SELECT * FROM ekko INTO TABLE gt_ekko
    WHERE ebeln IN s_ebeln.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_structure_name = 'EKKO'
    TABLES
      t_outtab        = gt_ekko.

8.2 数据批量导入

从本地文件(如 Excel、TXT)读取数据,然后更新到 SAP 数据库中。

abap 复制代码
REPORT Z_DATA_UPLOAD.

PARAMETERS: p_file TYPE rlgrap-filename.

DATA: BEGIN OF it_data OCCURS 0,
        field1 TYPE char10,
        field2 TYPE char20,
      END OF it_data.

START-OF-SELECTION.
  CALL FUNCTION 'UPLOAD'
    EXPORTING
      filename = p_file
    TABLES
      data_tab = it_data.

  LOOP AT it_data.
    " 执行数据库更新操作
  ENDLOOP.

8.3 数据一致性检查

定期运行程序,扫描业务数据中的异常情况,并输出报告。

8.4 批量状态变更

对满足条件的业务对象(如订单、凭证)进行批量状态修改或处理。


九、开发规范与最佳实践

9.1 命名规范

  • 程序名以 ZY 开头
  • 名称应具有业务含义:Z_PURCHASE_ORDER_REPORT 优于 ZTEST123
  • 使用下划线分隔单词

9.2 代码组织

  • 将类型定义和全局数据放在程序开头(TOP 部分)
  • 将复杂业务逻辑封装成 FORM 子程序局部类(Local Class)
  • 使用 INCLUDE 语句将代码拆分到多个包含程序中,提升可维护性
abap 复制代码
REPORT Z_MY_PROGRAM.

INCLUDE Z_MY_PROGRAM_TOP.    " 数据定义
INCLUDE Z_MY_PROGRAM_F01.    " FORM 子程序
INCLUDE Z_MY_PROGRAM_E01.    " 事件块

9.3 性能优化

  • 避免 SELECT *:只查询需要的字段
  • 使用内表批量处理 :尽量用 SELECT ... INTO TABLE 一次性读取数据,避免逐行 APPEND
  • 善用索引 :在 WHERE 条件中使用数据库表的索引字段
  • 使用 FOR ALL ENTRIES:当需要根据另一个内表查询数据时使用
abap 复制代码
" 不推荐:循环中逐条查询
LOOP AT it_main.
  SELECT SINGLE * FROM ekpo WHERE ebeln = it_main-ebeln.
ENDLOOP.

" 推荐:批量查询
SELECT * FROM ekpo INTO TABLE it_ekpo
  FOR ALL ENTRIES IN it_main
  WHERE ebeln = it_main-ebeln.

9.4 异常处理

  • 使用 MESSAGE 语句向用户反馈错误信息
  • 在后台作业中,将错误信息写入日志文件或自定义日志表

十、常用事务码速查

事务码 用途
SE38 ABAP 编辑器(创建、修改、运行可执行程序)
SA38 执行可执行程序(比 SE38 更轻量)
SE80 对象导航器(管理程序及其组件)
SE93 为程序创建事务代码
SM36 定义后台作业
SM37 监控后台作业
SLIN ABAP 扩展程序检查(代码质量检查)

十一、总结

可执行程序是 SAP ABAP 开发的基石。掌握它,你就掌握了 SAP 开发的第一把钥匙。本文的核心要点:

维度 核心内容
定义 无需事务码、可在 SE38 中直接运行的程序(类型值 1)
核心特征 事件块驱动、自带选择屏幕、支持逻辑数据库、可后台调度
创建步骤 SE38 → 新建 → 选择"可执行程序" → 编写 REPORT + 业务逻辑 → 激活 → 运行
事件块顺序 LOAD-OF-PROGRAM → INITIALIZATION → AT SELECTION-SCREEN → START-OF-SELECTION → END-OF-SELECTION
选择屏幕 PARAMETERS(单值)、SELECT-OPTIONS(范围)
逻辑数据库 通过程序属性关联,使用 GET 事件接收数据
后台调度 SM36 定义作业 + SM37 监控
最佳实践 Z/Y 命名、避免 SELECT *、批量处理、代码分层

可执行程序看似简单,但它的设计思想------事件驱动、声明式选择屏幕、与逻辑数据库的集成------贯穿了 SAP 开发的方方面面。当你熟悉了可执行程序,再学习模块池、函数组、类池等其他程序类型时,会发现许多概念是一脉相承的。

现在,打开 SE38,写下你的第一行 REPORT 语句,开始你的 SAP 开发之旅吧!


本文基于 SAP 经典 ABAP 开发环境编写,适用于 ECC 6.0 及早期版本。现代 S/4HANA 开发范式(CDS、RAP、Application Jobs 等)不在本文讨论范围内,如有需要可参考相关专题文章。

相关推荐
2401_897190552 小时前
mysql数据库性能基准测试工具推荐_使用sysbench进行压力测试
jvm·数据库·python
zzh0812 小时前
keepalived高可用与负载均衡笔记
运维·笔记·负载均衡
Shorasul2 小时前
mysql如何处理由于网络抖动导致的复制断开_mysql重试机制配置
jvm·数据库·python
星辰_mya2 小时前
进程状态转换
linux·运维·服务器
zhangchaoxies2 小时前
Python Flask路由怎么限制方法_methods列表配置仅允许GET或POST限制接口非法请求
jvm·数据库·python
HoneyMoose2 小时前
Jenkins 中 NodeJS 安装如何添加全局安装组件
运维·jenkins
凯强同学2 小时前
不上班,想裸辞,可以不可以?
服务器·前端·javascript
孙同学_2 小时前
【项目篇】高并发服务器 - Reactor模型详解
运维·服务器
WangJunXiang62 小时前
keepalived高可用与负载均衡
运维·负载均衡