Mark的技术博客

SAP顾问 | 咨询专家 | IT与AI技术探索者

吴让宇(Mark)

吴让宇(Mark)

SAP顾问 | 咨询专家 | IT与AI技术探索者

吴让宇(Mark)的个人技术博客,专注于SAP系统实施、行业方案咨询、IT技术与AI技术的研究与分享。

SAP Fiori ABAP CDS OData Dify Docker AI LLM

最新文章

ABAP 运行环境

🚀 ABAP简介

ABAP报告是熟悉一般ABAP原则和工具的良好起点。ABAP报告用于许多领域,本章将介绍如何编写简单的ABAP报告。

🖥️ AS ABAP概念

AS ABAP(Application Server ABAP)是具有以下特性的应用程序服务器:

  • 🗄️ 独立数据库
  • ⚙️ ABAP运行时环境
  • 🛠️ ABAP开发工具(如ABAP编辑器)
  • 🎯 提供独立于硬件、操作系统和数据库的开发平台

ABAP语句特点

  • 🔤 每个ABAP语句以ABAP关键字开头
  • 📍 以句点(.)结尾
  • ⚡ 关键字必须至少由一个空格分隔
  • 📝 无论ABAP语句使用一行或多行

🛠️ 使用ABAP编辑器

步骤1:启动ABAP编辑器

通过事务码 SE38 导航到ABAP编辑器。

步骤2:创建报表

程序命名规则

  • 📝 输入字段PROGRAM:指定报告名称,如 ZHELLO1
  • ⚠️ 前缀 Z 很重要,确保报告驻留在客户命名空间中
  • 💡 客户命名空间包括所有具有前缀 YZ 的对象
  • 🎯 目的:将客户对象与SAP标准对象区分开,防止名称冲突

提示:可以用小写字母键入名称,但编辑器会自动更改为大写。ABAP对象的名称是不区分大小写的。

步骤3:程序属性设置

ABAP: PROGRAM ATTRIBUTES 弹出窗口:

  • 📋 报告类型:选择”可执行程序”
  • 🏷️ 标题:输入”我的第一个ABAP报告”
  • 💾 保存程序

步骤4:创建对象目录条目

CREATE OBJECT DIRECTORY ENTRY 窗口:

  • 🎯 选择 LOCAL OBJECT 按钮
  • ✅ 弹出框将关闭,程序创建完成

📝 第一个ABAP程序

1
2
REPORT ZHELLO1.
WRITE 'Hello World'.

代码解析

  1. REPORT ZHELLO1. - 声明程序名称
  2. WRITE 'Hello World'. - 输出文本到屏幕

▶️ 启动报表

激活和运行

  1. 保存程序

    • 🎯 使用快捷键 Ctrl + S
    • 💾 或点击保存图标(命令字段旁边的右侧)
  2. 激活程序

    • 🎯 点击激活按钮(开始图标旁边的左侧)
    • ⚡ 激活编译程序代码
  3. 运行程序

    • 🚀 使用图标 DIRECT PROCESSING
    • ⌨️ 或按 F8 功能键
    • 📊 显示输出结果

输出示例

1
2
My First ABAP Report
Hello World

⚠️ 重要注意事项

激活的重要性

只要不激活新报告或激活对现有报告的更改:

  • ❌ 不会与其他用户相关
  • 🔒 在中央开发环境中非常重要
  • 🤝 防止影响其他开发人员在其项目中使用的对象

前向导航

  • 🎯 查看字段程序并双击值 ZHELLO1
  • 📖 ABAP编辑器将显示报告的代码
  • 🔄 这称为前向导航
  • 💡 双击对象的名称在适当的工具中打开该对象

ABAP 继承

🎯 继承的基本概念

面向对象编程中最重要的概念之一是==继承==。继承允许我们根据另一个类定义一个类,这使得创建和维护应用程序变得更容易,也提供了重用代码功能和快速实现时间的机会。

当创建类时,程序员可以指定新类应该继承现有类的成员,而不是写入完全新的数据成员和方法。此现有类称为==基类==或==超类==,新类称为==派生类==或==子类==。



graph TD
    A[超类 Superclass] -->|继承| B[子类 Subclass]
    A --> C["公共成员<br>(可访问)"]
    A --> D["保护成员<br>(可访问)"]
    A --> E["私有成员<br>(不可直接访问)"]
    B --> F["继承的成员<br>+ 新增成员"]
    B --> G["可重定义方法"]

继承的特点

  • 一个类的对象可以获取另一个类的属性
  • 派生类继承超类的数据和方法,但可以==覆盖方法==并==添加新方法==
  • 继承的主要优点是==可重用性==

📋 继承语法

除了类定义语句之外,还使用 INHERITING FROM 指定继承关系:

1
CLASS <subclass> DEFINITION INHERITING FROM <superclass>.

💡 示例:基本继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
REPORT zinheritan_1.
CLASS parent DEFINITION.
PUBLIC SECTION.
DATA: w_public(25) VALUE 'This is public data'.
METHODS: parentm.
ENDCLASS.

CLASS child DEFINITION INHERITING FROM parent.
PUBLIC SECTION.
METHODS: childm.
ENDCLASS.

CLASS parent IMPLEMENTATION.
METHOD parentm.
WRITE /: w_public.
ENDMETHOD.
ENDCLASS.

CLASS child IMPLEMENTATION.
METHOD childm.
SKIP.
WRITE /: 'Method in child class', w_public.
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
DATA:
parent TYPE REF TO parent,
child TYPE REF TO child.

CREATE OBJECT:
parent,
child.
CALL METHOD:
parent->parentm,
child->childm.

输出结果

1
2
This is public data
Method in child class This is public data
💥代码解析
  • INHERITING FROM parent — 子类 child 继承自父类 parent
  • 子类自动拥有父类的公共数据 w_public
  • 子类可以定义自己的方法 childm

🔍 访问控制和继承

派生类可以访问其基类的所有==非私有成员==。因此,不应该被子类的成员函数访问的超类成员应该在超类中被声明为私有的。

访问类型总结

访问位置 公开(PUBLIC) 保护(PROTECTED) 私有(PRIVATE)
同类
派生类
外部

三种继承类型



graph LR
    A[继承类型] --> B["公共继承<br>PUBLIC"]
    A --> C["保护继承<br>PROTECTED"]
    A --> D["私有继承<br>PRIVATE"]
    B --> B1["public → public<br>protected → protected"]
    C --> C1["public → protected<br>protected → protected"]
    D --> D1["public → private<br>protected → private"]

1. 公共继承(常用)

  • 超类的公共成员 → 子类的公共成员
  • 超类的受保护成员 → 子类的受保护成员
  • 超类的私有成员不能直接从子类访问

2. 受保护的继承

  • 超类的公共和受保护成员 → 子类的受保护成员

3. 私有继承

  • 超类的公共和受保护成员 → 子类的私有成员
💡实际开发建议
在ABAP面向对象开发中,几乎总是使用公共继承。保护继承和私有继承很少使用。

🏗️ 子类中的重定义方法

超类的方法可以在子类中==重新实现==。重新定义方法的规则:

规则 说明
同一节声明 重定义语句必须与原始方法的定义在同一节中
无需重写接口 只需要输入方法的名称,不需要再次输入其接口
超类引用 可以使用 SUPER-> 访问直接超类的组件
使用范围 伪引用 SUPER 只能在重定义的方法中使用
💡超类引用
在重定义的方法中,可以使用 SUPER-> 来访问超类的原始实现:
1
2
3
4
5
METHOD addition1.
" 先调用父类的原始实现
SUPER->addition1( ... ).
" 再添加额外逻辑
ENDMETHOD.

示例:方法重定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
REPORT zinheri_redefine.
CLASS super_class DEFINITION.
PUBLIC SECTION.
METHODS: addition1 IMPORTING g_a TYPE i
g_b TYPE i
EXPORTING g_c TYPE i.
ENDCLASS.

CLASS super_class IMPLEMENTATION.
METHOD addition1.
g_c = g_a + g_b.
ENDMETHOD.
ENDCLASS.

CLASS sub_class DEFINITION INHERITING FROM super_class.
PUBLIC SECTION.
METHODS: addition1 REDEFINITION.
ENDCLASS.

CLASS sub_class IMPLEMENTATION.
METHOD addition1.
g_c = g_a + g_b + 10. " 增加了额外的逻辑
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
PARAMETERS: p_a TYPE i,
p_b TYPE i.
DATA: h_addition1 TYPE i.
DATA: ref1 TYPE REF TO sub_class.

CREATE OBJECT ref1.
CALL METHOD ref1->addition1
EXPORTING
g_a = p_a
g_b = p_b
IMPORTING
g_c = h_addition1.

WRITE:/ h_addition1.

执行结果

输入值 9 和 10,输出结果为:

1
Redefinition Demo  29
💥代码解析
  • REDEFINITION — 关键字表示子类重定义了父类的方法
  • 子类 addition1 在父类的基础上增加了 +10 的逻辑
  • 结果 29 = 9 + 10 + 10

⚠️ 注意事项

  • 谨慎使用继承,避免过深的继承层次
  • 优先使用==组合==而非继承
  • 确保子类满足 “==is-a==” 关系
  • 重写方法时考虑向上兼容性
  • ABAP 只支持==单继承==(一个类只能有一个父类)

ABAP 结构

🏗️ 结构的基本概念

定义

结构是由存储器中一个接一个存储的任何数据类型的组件组成的数据对象。

结构的特点



graph TB
    A[结构] --> B[组件1]
    A --> C[组件2]
    A --> D[组件3]
    
    B --> B1[数据类型1]
    C --> C1[数据类型2]
    D --> D1[数据类型3]

结构 vs 表

特性 结构
记录数 运行时只有一个记录 可以有很多记录
存储方式 内存中连续存储 数据库中存储
用途 屏幕字段定义、数据操作 数据持久化存储

🎯 结构的用途

1. 屏幕字段绘制

结构对于绘制屏幕字段非常有用,可以将相关的字段组合在一起:



graph LR
    A[客户结构] --> B[基本信息]
    A --> C[联系信息]
    A --> D[地址信息]
    
    B --> B1[姓名]
    B --> B2[出生日期]
    B --> B3[性别]
    
    C --> C1[电话]
    C --> C2[邮箱]
    C --> C3[手机]
    
    D --> D1[街道]
    D --> D2[城市]
    D --> D3[邮编]

2. 数据操作

结构对于操作具有由离散数量的字段定义的一致格式的数据非常有用:

  • 数据传输
  • 函数模块参数
  • 临时数据存储

🛠️ 创建结构

步骤1:启动事务

使用事务 SE11 进入ABAP字典。

步骤2:选择数据类型

在屏幕上点击”数据类型”选项,输入名称”ZSTR_CUSTOMER1”,然后点击创建按钮。

步骤3:选择结构类型

在下一个屏幕中选择”结构”选项,按Enter键,进入”Maintain / Change Structure”向导。

步骤4:输入基本信息

在结构维护屏幕中输入简短说明:

属性 说明 示例
结构名称 结构的唯一标识 ZSTR_CUSTOMER1
短文本 结构的描述 “客户结构”

步骤5:定义组件

输入组件(字段名称)和组件类型(数据元素):

组件命名规则

  • 组件名称按照SAP建议从Z开始
  • 使用有意义的名称
  • 遵循命名规范

组件类型选择

使用已经在数据库表中创建的数据元素:

组件名称 数据元素 说明
ZCUSTOMER ZCUSTNUM 客户编号
ZNAME SCUSTOM-NAME 客户姓名
ZDOB SCUSTOM-DOB 出生日期

步骤6:保存和激活

完成组件定义后,需要执行以下操作:

  1. 保存:保存结构定义
  2. 检查:检查语法和逻辑
  3. 激活:激活结构使其可用

激活过程

  1. 在激活屏幕中,结构”ZSTR_CUSTOMER1”会突出显示
  2. 点击绿色勾号按钮
  3. 状态栏显示”活动”消息

💡 结构的使用场景

1. 数据类型声明

1
2
3
4
5
6
7
* 使用结构定义变量
DATA: customer_structure TYPE zstr_customer1.

* 赋值
customer_structure-zcustomer = '1001'.
customer_structure-zname = '张三'.
customer_structure-zdob = '19900101'.

2. 函数模块接口

1
2
3
4
5
6
7
* 使用结构作为参数
FUNCTION Z_CUSTOMER_UPDATE.
IMPORTING
is_customer TYPE zstr_customer1
EXPORTING
ev_result TYPE char1.
ENDFUNCTION.

3. 屏幕字段定义

1
2
3
* 在屏幕中使用结构
CONTROLS: tc_customer TYPE TABLEVIEW USING SCREEN 0100.
TABLES: zstr_customer1.

🔍 结构的属性

结构组件

属性 描述 示例
组件名称 字段的名称 ZCUSTOMER
数据类型 组件的数据类型 CHAR, NUMC
长度 字段的长度 10, 20
短文本 组件的描述 “客户编号”

激活状态

  • 激活状态:结构已激活并可用
  • 激活日志:显示激活过程中的任何错误或警告

⚠️ 注意事项

1. 命名规范

  • 组件名称建议从Z开始
  • 使用有意义的名称
  • 避免使用保留字

2. 数据元素关联

  • 每个组件必须关联一个数据元素
  • 确保数据元素已激活
  • 组件继承数据元素的属性

3. 激活顺序

  • 先激活数据元素
  • 再激活结构
  • 确保所有引用都已激活

ABAP 视图

📊 视图的基本概念

定义

视图的行为就像数据库表,但不会占用存储空间。视图类似于虚拟表 - 一个没有任何物理存在的表。

视图的创建方式

通过组合包含关于应用对象的信息的一个或多个表的数据来创建视图。使用视图,可以:

  1. 表示表中数据的子集
  2. 将多个表连接到单个虚拟表中

数据分布

应用程序对象相关的数据通过使用数据库视图分布在多个表中。它们使用内部连接条件来连接不同表的数据。

🔍 视图的类型

1. 维护视图

  • 用途:用于显示和修改存储在应用程序对象中的数据
  • 特点:每个维护视图都具有与其关联的维护状态
  • 应用:业务数据的维护操作

2. 投影视图



graph TB
    A[投影视图] --> B[筛选字段]
    A --> C[隐藏不需要的字段]
    A --> D[显示相关字段]
    
    B --> B1[选择需要的列]
    C --> C1[屏蔽敏感字段]
    D --> D1[简化数据展示]

投影视图的特点

  • 表限制:必须在单个透明表上定义
  • 内容:只包含一个表
  • 选择条件:不能为投影视图定义选择条件

🛠️ 创建视图

步骤1:启动事务

在ABAP字典的初始屏幕上选择”查看”单选按钮,输入要创建的视图名称(如ZVIEW_TEST),然后单击创建按钮。

步骤2:选择视图类型

选择”投影视图”单选按钮,同时选择视图类型,点击复制按钮。进入”Dictionary: Change View”屏幕。

步骤3:输入基本信息

基本属性设置

属性 描述 示例
视图名称 视图的唯一标识 ZVIEW_TEST
短文本 视图的描述 “测试投影视图”
基准表 视图基于的表 ZCUSTOMERS1

步骤4:选择表字段

点击”表格字段”按钮,在投影视图中包含CUSTOMERS表格的字段。

字段选择

  • 显示表ZCUSTOMERS1屏幕中的字段
  • 选择要包含在投影视图中的字段
  • 如:客户、客户编号、姓名等

步骤5:确认字段选择

点击复制按钮后,投影视图的所有选定字段将显示在”Dictionary: Change View”屏幕上。

步骤6:定义访问方法

选择维护状态选项卡以定义访问方法:

访问选项 说明 用途
只读 只允许查看数据 数据展示
显示/维护允许的限制 有限制的维护 特定操作

从”数据浏览器/表视图维护”的下拉菜单中选择适当的选项。

步骤7:保存和激活

  1. 保存视图定义
  2. 激活视图

步骤8:测试视图

  1. 在”字典:更改视图”屏幕中,选择实用程序(M) > 显示ZVIEW_TEST选择屏幕的内容
  2. 点击执行图标
  3. 查看投影视图的输出

💡 视图的示例输出

输出示例

表CUSTOMERS 1由5个字段组成,投影视图中显示3个字段(客户、客户编号和名称),有4个条目:

客户编号 客户 名称
100001 C001 张三
100002 C002 李四
100003 C003 王五
100004 C004 赵六

🔧 视图的使用场景

1. 数据查询

1
2
* 使用视图查询数据
SELECT * FROM zview_test INTO TABLE lt_data.

2. 数据展示

1
2
3
4
* 在报表中使用视图
SELECT * FROM zview_test
WHERE customer = 'C001'
INTO CORRESPONDING FIELDS OF TABLE lt_result.

3. 报表开发

1
2
3
4
5
6
7
* 视图作为报表数据源
REPORT z_view_report.
TABLES: zview_test.

DATA: lt_data TYPE TABLE OF zview_test.

SELECT * FROM zview_test INTO TABLE lt_data.

📝 视图的优点

1. 数据安全性

  • 屏蔽敏感字段
  • 只显示必要的数据
  • 控制访问权限

2. 简化开发

  • 简化复杂的表连接
  • 预定义查询逻辑
  • 减少重复代码

3. 性能优化

  • 减少数据传输量
  • 只获取需要的字段
  • 优化查询性能

⚠️ 注意事项

1. 视图限制

  • 投影视图只能基于一个表
  • 不能在视图中定义选择条件
  • 视图不占用物理存储空间

2. 维护状态

  • 正确设置维护状态
  • 考虑数据安全性需求
  • 定义适当的访问权限

3. 性能考虑

  • 避免过度复杂的视图
  • 注意视图的查询性能
  • 合理使用索引

ABAP 读取内表

🔍 内表读取概述

读取功能

使用READ TABLE语句可以读取内表的行,支持多种查询方式。

读取方式



graph TD
    A[内表读取] --> B[索引读取]
    A --> C[键值读取]
    A --> D[条件读取]
    
    B --> B1[READ TABLE ... INDEX]
    C --> C1[READ TABLE ... WITH KEY]
    D --> D1[LOOP AT ... WHERE]

📝 READ TABLE语法

基本语法

1
READ TABLE <internal_table> FROM <work_area_itab>.

参数说明

参数 说明 示例
目标内部表 mytable
工作区,与内表行类型兼容 Record1

带键值的读取

1
READ TABLE <internal_table> WITH KEY = <internal_tab_field>.

说明:

  • 内部表的整行用作搜索键
  • 将表的整行内容与<internal_tab_field>的内容进行比较
  • 如果字段不兼容,系统会根据内表行类型进行转换

🔧 高级读取语法

带COMPARING子句

1
2
READ TABLE <internal_table> <key> INTO <work_area_itab>
[COMPARING <F1> <F2>...<Fn>].

COMPARING子句作用

  1. 字段比较:将指定表字段与工作区的相应字段进行比较

  2. 比较结果

    • SY-SUBRC = 0:找到匹配的条目
    • SY-SUBRC = 2:找到条目但字段不同
    • SY-SUBRC = 4:未找到条目
  3. 数据复制:无论查找结果如何,系统都会将条目复制到目标工作区中

ALL FIELDS选项

1
READ TABLE mytable FROM Record1 INTO Record1 COMPARING ALL FIELDS.

比较所有组件,不仅仅是键字段。

💡 实例分析

完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
REPORT  zread_demo.

* 创建内表结构
DATA:
BEGIN OF Record1,
ColP TYPE i,
ColQ TYPE i,
END OF Record1.
* 创建哈希表
DATA mytable LIKE HASHED TABLE OF Record1
WITH UNIQUE KEY ColP.

* 填充数据
DO 6 TIMES.
Record1-ColP = sy-index.
Record1-ColQ = sy-index + 5.
INSERT Record1 INTO TABLE mytable.
ENDDO.

* 准备查询条件
Record1-ColP = 4.
Record1-ColQ = 12.

* 执行读取(带COMPARING)
READ TABLE mytable FROM Record1 INTO Record1
COMPARING ColQ.

* 输出结果
WRITE: 'SY-SUBRC =', sy-subrc.
SKIP.
WRITE: / Record1-ColP, Record1-ColQ.

输出分析

1
SY-SUBRC =    2   4         9

执行逻辑说明

  1. mytable初始化:填充了六行数据

    • ColP字段:1, 2, 3, 4, 5, 6
    • ColQ字段:6, 7, 8, 9, 10, 11
  2. 查询条件

    • Record1-ColP = 4
    • Record1-ColQ = 12
  3. 执行读取

    • 系统根据ColP=4找到匹配行
    • 比较ColQ字段:期望值12,实际值9
    • 由于字段不同,SY-SUBRC=2
  4. 结果

    • 找到匹配项但字段不匹配
    • 数据被复制到工作区(ColQ=9)

🎯 读取方法详解

1. 索引读取

1
2
3
4
5
6
7
8
* 使用索引读取第3行
READ TABLE mytable INTO Record1 INDEX 3.

IF sy-subrc = 0.
WRITE: / '读取成功:', Record1-ColP, Record1-ColQ.
ELSE.
WRITE: / '读取失败'.
ENDIF.

2. 键值读取

1
2
3
4
5
6
7
* 使用键值读取
READ TABLE mytable INTO Record1
WITH TABLE KEY ColP = 4.

IF sy-subrc = 0.
WRITE: / '找到记录:', Record1-ColQ.
ENDIF.

3. 条件读取

1
2
3
4
* 使用LOOP AT进行条件读取
LOOP AT mytable INTO Record1 WHERE ColP > 3 AND ColQ < 10.
WRITE: / '符合条件的记录:', Record1-ColP, Record1-ColQ.
ENDLOOP.

⚠️ 重要注意事项

1. 返回码含义

返回码 含义 处理建议
SY-SUBRC = 0 成功找到匹配项 继续处理
SY-SUBRC = 2 找到条目但字段不匹配 检查数据差异
SY-SUBRC = 4 未找到条目 处理不存在的情况

2. 性能考虑

  • 哈希表:使用键值查找时性能最佳(O(1))
  • 排序表:使用键值查找时性能良好(O(log n))
  • 标准表:只能使用线性查找(O(n))

3. 错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* 完整的错误处理
READ TABLE mytable INTO Record1
WITH TABLE KEY ColP = 4
COMPARING ColQ.

CASE sy-subrc.
WHEN 0.
WRITE: / '完全匹配:', Record1.
WHEN 2.
WRITE: / '键匹配但字段不同:', Record1.
WHEN 4.
WRITE: / '记录不存在'.
WHEN OTHERS.
WRITE: / '未知错误'.
ENDCASE.

💡 最佳实践

1. 使用适当的内表类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* 根据查询模式选择内表类型
DATA: lt_standard TYPE STANDARD TABLE OF ty_data,
lt_sorted TYPE SORTED TABLE OF ty_data
WITH UNIQUE KEY key_field,
lt_hashed TYPE HASHED TABLE OF ty_data
WITH UNIQUE KEY key_field.

* 选择查询模式
IF find_mode = 'key'.
lt_data = lt_hashed. " 键值查找首选哈希表
ELSEIF find_mode = 'range'.
lt_data = lt_sorted. " 范围查询首选排序表
ELSE.
lt_data = lt_standard. " 通用查询
ENDIF.

2. 批量读取优化

1
2
3
4
5
6
* 先检查键是否存在
IF line_exists( mytable WITH TABLE KEY ColP = 4 ).
READ TABLE mytable INTO Record1
WITH TABLE KEY ColP = 4.
" 处理找到的记录
ENDIF.

3. 使用BINARY SEARCH(排序表)

1
2
3
4
* 排序表使用二分查找提高性能
READ TABLE lt_sorted INTO Record1
WITH TABLE KEY ColP = 4
BINARY SEARCH.

ABAP 锁对象

🔒 锁对象概述

定义

锁对象是由ABAP字典提供的功能,用于通过多个程序同步对相同数据的访问。在特定程序的帮助下访问数据记录。

主要目的

锁对象在SAP中使用,以避免在数据库中插入或更改数据时出现不一致。

锁定要求

要锁定其数据记录的表必须在锁对象中与其关键字段一起定义。

⚙️ 锁定机构

锁定的两个主要功能

  1. 程序间通信

    • 程序可以与其他程序关于它正在读取或改变的数据记录进行通信
  2. 数据一致性

    • 程序可以防止自己读取刚刚被另一个程序改变的数据

锁定请求流程



graph TD
    A[程序生成锁定请求] --> B[发送到Enqueue服务器]
    B --> C[在锁表中创建锁]
    C --> D[Enqueue服务器设置锁定]
    D --> E[程序准备访问数据]

🛠️ 创建锁对象

步骤1:启动事务

使用事务 SE11 进入ABAP字典。

步骤2:选择锁对象类型

点击”锁对象”单选按钮,输入以E开头的锁定对象名称(如EZLOCK12),然后单击创建按钮。

命名规则

  • 锁定对象名称必须以 E 开头
  • 遵循命名规范
  • 使用有意义的名称

步骤3:输入基本信息

在简短说明字段中输入锁对象的描述。

步骤4:定义表和锁定模式

表选项卡

在名称字段中输入表名称,并选择锁定模式:

锁定模式 描述 用途
写锁定 排他锁定,阻止其他访问 数据修改
读锁定 共享锁定,允许多个读 数据查询

步骤5:设置锁定参数

点击锁定参数选项卡,定义锁参数:

参数 描述 用途
锁参数 锁对象中包含的表的键字段 用作函数模块中的输入参数
输入参数 用于设置和删除锁定 控制锁定范围

步骤6:保存和激活

保存并激活锁对象。系统自动生成2个功能模块。

步骤7:检查功能模块

使用”转到→锁定模块”查看生成的功能模块。

生成的功能模块

  1. ENQUEUE_<锁对象名>

    • 设置锁
    • 接受锁参数作为输入
  2. DEQUEUE_<锁对象名>

    • 释放锁
    • 接受锁参数作为输入

💡 锁对象的使用场景

1. 数据修改保护

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
* 设置锁
CALL FUNCTION 'ENQUEUE_EZLOCK12'
EXPORTING
mode_zlock12 = 'E'
zcustomer = '1001'
EXCEPTIONS
lock_failed = 1
OTHERS = 2.

IF sy-subrc = 0.
* 执行数据修改
UPDATE ztable SET field = 'value' WHERE customer = '1001'.

* 释放锁
CALL FUNCTION 'DEQUEUE_EZLOCK12'
EXPORTING
mode_zlock12 = 'E'
zcustomer = '1001'.
ENDIF.

2. 数据一致性保证

1
2
3
4
5
6
7
8
9
10
11
12
13
* 在事务中使用锁
CALL FUNCTION 'ENQUEUE_EZORDER'
EXPORTING
mode_ezorder = 'E'
ebeln = lv_ebeln.

* 执行相关操作
* ...
* 释放锁
CALL FUNCTION 'DEQUEUE_EZORDER'
EXPORTING
mode_ezorder = 'E'
ebeln = lv_ebeln.

3. 批处理作业

1
2
3
4
5
6
7
8
9
10
11
12
* 在批处理中避免冲突
CALL FUNCTION 'ENQUEUE_EZMAT'
EXPORTING
mode_ezmat = 'E'
matnr = lv_matnr.

* 处理物料
* ...
CALL FUNCTION 'DEQUEUE_EZMAT'
EXPORTING
mode_ezmat = 'E'
matnr = lv_matnr.

🔧 锁参数详解

锁参数的作用

锁对象中包含的表的键字段称为锁参数,它们用作函数模块中的输入参数。

锁参数示例

表名 锁参数 说明
ZCUSTOMERS CUSTOMER 客户编号作为锁参数
ZORDERS EBELN 采购订单号作为锁参数
ZMATERIAL MATNR 物料编号作为锁参数

参数类型

参数类型 描述 示例
GENERIC 通用锁,锁定范围较大 锁定整个表
EXCLUSIVE 排他锁,锁定特定记录 锁定单个客户
SHARED 共享锁,允许多个读 多个程序同时读取

⚠️ 注意事项

1. 锁定原则

  • 最短锁定时间:锁定时间尽量短
  • 及时释放:完成后立即释放锁
  • 避免死锁:按固定顺序获取锁

2. 性能考虑

  • 过多的锁会影响性能
  • 避免在循环中获取锁
  • 合理设置锁定超时

3. 错误处理

  • 处理锁定失败的情况
  • 提供适当的错误信息
  • 实现重试机制

ABAP 面向对象

🎯 面向对象编程概述

定义

对象导向简化了软件设计,使其更易于理解、维护和重用。面向对象编程(OOP)表示在编写软件时的不同思维方式。

OOP的优势



graph TD
    A[面向对象编程] --> B[简化设计]
    A --> C[易于维护]
    A --> D[代码重用]
    A --> E[易于沟通]
    A --> F[高质量软件]

OOP的美丽

  • 简单性:OOP的表达能力使得更容易按时交付高质量的软件组件
  • 通用语言:解决方案根据现实世界的对象设计,程序员和业务分析师使用通用域语言交换想法
  • 需求发现:沟通的改进有助于揭示隐藏的要求,识别风险
  • 质量提升:提高正在开发的软件的质量

🔍 过程编程 vs 面向对象编程

对比分析

特征 程序导向法 面向对象方法
重点 重点是任务 重点是做那些任务的事情
模块化 程序分为称为函数的小程序 程序组织成类和对象,功能嵌入到类的方法中
数据安全 大多数函数共享全局数据 数据可以被隐藏,不能被外部源访问
可扩展性 修改和扩展现有功能更耗时 新的数据和功能可以轻松添加

📋 ABAP中的面向对象

ABAP的发展历程

  • 最初:ABAP被开发为过程语言(类似于COBOL)
  • 现在:ABAP已适应面向对象范式的原理,引入了ABAP对象
  • 兼容性:ABAP中面向对象的概念与其他现代面向对象语言(如Java或C++)基本相同

ABAP面向对象的核心概念

  1. 类(Class)
  2. 对象(Object)
  3. 继承(Inheritance)
  4. 多态(Polymorphism)

🏗️ 面向对象的主要特点

1. 有效的编程结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
" 良好的类设计示例
CLASS zcl_example DEFINITION.
PUBLIC SECTION.
METHODS:
" 公共方法
calculate_discount
IMPORTING iv_amount TYPE p
EXPORTING ev_discount TYPE p,
get_total
IMPORTING iv_items TYPE i
RETURNING(rv_total) TYPE p.
PRIVATE SECTION.
" 私有数据和方法
DATA: mv_discount_rate TYPE p VALUE 0.10.
METHODS: validate_amount
IMPORTING iv_amount TYPE p.
ENDCLASS.

2. 现实世界的实体建模



classDiagram
    class Customer {
        +String name
        +String id
        +Date registrationDate
        +registerOrder()
        +getDiscount()
    }
    
    class Order {
        +String orderId
        +Date orderDate
        +Double totalAmount
        +addItem()
        +calculateTotal()
    }
    
    class OrderItem {
        +String productId
        +Integer quantity
        +Double price
        +getSubtotal()
    }
    
    Customer "1" -- "0..*" Order : places
    Order "1" -- "1..*" OrderItem : contains

3. 数据安全和访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CLASS zcl_secure_data DEFINITION.
PUBLIC SECTION.
METHODS:
get_data
RETURNING(value(rv_data)) TYPE string,
set_data
IMPORTING iv_data TYPE string.
PRIVATE SECTION.
DATA: mv_secure_data TYPE string.
ENDCLASS.

" 外部代码只能通过公共方法访问数据
DATA(lo_secure) = NEW zcl_secure_data( ).
lo_secure->set_data( ' confidential information ' ).
" 直接访问 mv_secure_data 会导致编译错误

4. 最小化代码冗余

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
" 使用继承减少重复代码
CLASS zcl_base_vehicle DEFINITION.
PUBLIC SECTION.
METHODS:
start_engine
ABSTRACT, " 抽象方法
get_speed
RETURNING(value(rv_speed)) TYPE i.
ENDCLASS.

" 子类继承并实现
CLASS zcl_car DEFINITION INHERITING FROM zcl_base_vehicle.
PUBLIC SECTION.
METHODS:
start_engine REDEFINITION,
get_speed REDEFINITION.
ENDCLASS.

CLASS zcl_car IMPLEMENTATION.
METHOD start_engine.
WRITE: / 'Car engine started'.
ENDMETHOD.

METHOD get_speed.
rv_speed = 120. " 汽车速度
ENDMETHOD.
ENDCLASS.

5. 数据抽象和封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
" 封装:隐藏实现细节,只暴露接口
CLASS zcl_bank_account DEFINITION.
PUBLIC SECTION.
METHODS:
deposit
IMPORTING iv_amount TYPE p,
withdraw
IMPORTING iv_amount TYPE p,
get_balance
RETURNING(value(rv_balance)) TYPE p.
PRIVATE SECTION.
DATA: mv_balance TYPE p VALUE 0.
METHODS: validate_amount
IMPORTING iv_amount TYPE p.
ENDCLASS.

" 使用者不需要知道余额如何存储
DATA(lo_account) = NEW zcl_bank_account( ).
lo_account->deposit( 1000 ).
lo_account->withdraw( 200 ).
WRITE: / 'Balance:', lo_account->get_balance( ).

💡 面向对象设计原则

1. 单一职责原则(SRP)

1
2
3
4
5
6
7
8
9
" 每个类只负责一个职责
CLASS zcl_order_service DEFINITION.
PUBLIC SECTION.
METHODS:
save_order
IMPORTING iv_order TYPE zcl_order=>ty_order,
send_confirmation
IMPORTING iv_order_id TYPE vbeln.
ENDCLASS.

2. 开放封闭原则(OCP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
" 对扩展开放,对修改封闭
CLASS zcl_discount_calculator DEFINITION.
PUBLIC SECTION.
METHODS:
calculate_discount
IMPORTING iv_amount TYPE p
RETURNING(value(rv_discount)) TYPE p.
ENDCLASS.

" 新的折扣类型通过扩展而不是修改来添加
CLASS zcl_vip_discount_calculator DEFINITION
INHERITING FROM zcl_discount_calculator.
PUBLIC SECTION.
METHODS: calculate_discount REDEFINITION.
ENDCLASS.

3. 里氏替换原则(LSP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
" 子类可以替换父类
CLASS zcl_payment_processor DEFINITION.
PUBLIC SECTION.
METHODS:
process_payment
IMPORTING iv_amount TYPE p
RAISING cx_payment_error.
ENDCLASS.

CLASS zcl_credit_card_processor DEFINITION
INHERITING FROM zcl_payment_processor.
PUBLIC SECTION.
METHODS: process_payment REDEFINITION.
ENDCLASS.

" 可以安全地使用任意处理器
DATA(lo_processor) = NEW zcl_payment_processor( ).
" 或者
DATA(lo_processor2) = NEW zcl_credit_card_processor( ).

4. 接口隔离原则(ISP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
" 定义专门的接口
INTERFACE zcl_discountable.
METHODS: get_discount_percentage
RETURNING(value(rv_percentage)) TYPE p.
ENDINTERFACE.

INTERFACE zcl_taxable.
METHODS: calculate_tax
IMPORTING iv_amount TYPE p
RETURNING(value(rv_tax)) TYPE p.
ENDINTERFACE.

" 类实现需要的接口
CLASS zcl_product DEFINITION.
PUBLIC SECTION.
INTERFACES: zcl_discountable, zcl_taxable.
ENDCLASS.

🎯 面向对象的实际应用

1. 业务对象建模

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
" 客户类示例
CLASS zcl_customer DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING iv_id TYPE kunnr,
add_order
IMPORTING iv_order TYPE zcl_order=>ty_order,
get_orders
RETURNING(value(rt_orders)) TYPE zcl_order=>tt_orders,
calculate_lifetime_value
RETURNING(value(rv_value)) TYPE p.
PRIVATE SECTION.
DATA: mv_id TYPE kunnr,
mt_orders TYPE zcl_order=>tt_orders.
ENDCLASS.

2. 工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
" 工厂类创建对象
CLASS zcl_factory DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
create_document
IMPORTING iv_type TYPE char1
RETURNING(value(ro_document)) TYPE REF TO zcl_document.
ENDCLASS.

CLASS zcl_factory IMPLEMENTATION.
METHOD create_document.
CASE iv_type.
WHEN 'PDF'.
ro_document = NEW zcl_pdf_document( ).
WHEN 'DOC'.
ro_document = NEW zcl_doc_document( ).
WHEN OTHERS.
RAISE EXCEPTION TYPE cx_document_error.
ENDCASE.
ENDMETHOD.
ENDCLASS.

3. 观察者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
" 主题接口
INTERFACE zcl_subject.
METHODS:
register_observer
IMPORTING io_observer TYPE REF TO zcl_observer,
notify_observers.
ENDINTERFACE.

" 观察者接口
INTERFACE zcl_observer.
METHODS:
update
IMPORTING iv_message TYPE string.
ENDINTERFACE.

" 具体实现
CLASS zcl_news DEFINITION.
PUBLIC SECTION.
INTERFACES: zcl_subject.
ENDCLASS.

CLASS zcl_email_notifier DEFINITION.
PUBLIC SECTION.
INTERFACES: zcl_observer.
ENDCLASS.

⚠️ 注意事项

1. 避免过度设计

1
2
3
4
5
6
7
8
9
10
11
12
13
" 不必要的复杂化
CLASS zcl_example_too_complex DEFINITION.
" 太多设计模式,简单任务用简单方法
ENDCLASS.

" 更好的方案
CLASS zcl_simple_example DEFINITION.
PUBLIC SECTION.
METHODS:
do_simple_task
IMPORTING iv_input TYPE any
RETURNING(value(rv_result)) TYPE any.
ENDCLASS.

2. 保持类的大小合理

1
2
3
4
5
6
7
8
9
10
" 遵循单一职责原则
CLASS zcl_user_management DEFINITION.
PUBLIC SECTION.
" 用户管理相关方法
METHODS:
create_user,
update_user,
delete_user,
get_user_by_id.
ENDCLASS.

3. 使用合适的访问修饰符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
" 合理使用PUBLIC/PRIVATE/PROTECTED
CLASS zcl_good_design DEFINITION.
PUBLIC SECTION.
" 对外暴露的公共接口
METHODS:
get_public_data
RETURNING(value(rv_data)) TYPE string.
PRIVATE SECTION.
" 内部实现细节
DATA: mv_private_data TYPE string.
METHODS:
calculate_internal_value
RETURNING(value(rv_value)) TYPE i.
ENDCLASS.

ABAP 运算符

ℹ️概述
ABAP提供了一组丰富的运算符来操纵变量。所有ABAP运算符分为四类:算术运算符、比较运算符、按位运算符和字符串运算符。

📊 运算符分类



graph TD
    A[ABAP运算符] --> B[算术运算符]
    A --> C[比较运算符]
    A --> D[按位运算符]
    A --> E[字符串运算符]


🔢 算术运算符

算术运算符在数学表达式中使用的方式与在代数中使用的方式相同。

运算符列表

假设整数变量A保持20,变量B保持40:

编号 算术运算符 描述 示例 结果
1 +(加法) 在运算符的两侧添加值 A + B 60
2 -(减法) 从左边操作数中减去右边操作数 A - B -20
3 ***(乘法)** 将运算符两侧的值相乘 A * B 800
4 /(除法) 用右边操作数除左边操作数 B / A 2
5 MOD(模量) 用右边操作数除左边操作数,并返回余数 B MOD A 0

示例代码

1
2
3
4
5
6
7
8
REPORT YS_SEP_08.
DATA:
A TYPE I VALUE 150,
B TYPE I VALUE 50,
Result TYPE I.

Result = A / B.
WRITE / Result.

输出

1
3

🔍 比较运算符

比较运算符用于比较两个操作数的值。

运算符列表

编号 比较运算符 描述 示例
1 =(相等) 检查两个操作数的值是否相等 A = B
2 <>(不等) 检查两个操作数的值是否不相等 A <> B
3 >(大于) 检查左操作数是否大于右操作数 A > B
4 <(小于) 检查左操作数是否小于右操作数 A < B
5 >=(大于等于) 检查左操作数是否大于等于右操作数 A >= B
6 <=(小于等于) 检查左操作数是否小于等于右操作数 A <= B
7 BETWEEN 检查值是否在指定范围内 A BETWEEN B AND C
8 IS INITIAL 检查变量是否为初始值 A IS INITIAL
9 IS NOT INITIAL 检查变量是否不是初始值 A IS NOT INITIAL

替代形式

运算符 替代形式
= EQ
<> NE
> GT
< LT
>= GE
<= LE

数据类型转换规则

如果变量的数据类型或长度不匹配,执行自动转换:

转换规则 说明
I优先 如果一个字段是类型I,另一个字段转换为类型I
P优先 如果一个字段是类型P,另一个字段转换为类型P
D优先 如果一个字段是类型D,另一个字段转换为类型D
N/C转换 N类型与C或X比较时,都转换为类型P
X转C X类型与C比较时,转换为类型C

示例代码

实例1

1
2
3
4
5
6
7
8
REPORT YS_SEP_08.
DATA:
A TYPE I VALUE 115,
B TYPE I VALUE 119.

IF A LT B. -- 使用替代形式
WRITE: / 'A is less than B'.
ENDIF.

输出

1
A is less than B

实例2

1
2
3
4
5
REPORT YS_SEP_08.
DATA: A TYPE I.
IF A IS INITIAL.
WRITE: / 'A is assigned'.
ENDIF.

输出

1
A is assigned.

💻 按位运算符

ABAP提供了一系列可以用于构建布尔代数表达式的逐位逻辑运算符。

运算符列表

编号 按位运算符 说明
1 BIT-NOT 一元运算符,将所有位翻转为相反的值
2 BIT-AND 二进制运算符,使用布尔AND运算符逐位比较
3 BIT-XOR 二进制运算符,使用布尔XOR(异或)运算符
4 BIT-OR 二进制运算符,使用布尔OR运算符

真值表

字段A 字段B AND OR XOR
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

示例

1
2
DATA: hex_val TYPE X VALUE 'AA'.
BIT-NOT hex_val. -- 结果: 55 (01010101)

🔤 字符串运算符

字符串运算符用于处理字符串和字符的比较操作。

运算符列表

编号 字符串运算符 描述
1 CO(仅包含) 检查A是否仅由B中的字符组成
2 CN(不包含) 检查A是否包含不在B中的字符
3 CA(包含任何) 检查A是否至少包含一个字符B
4 NA(不含任何) 检查A是否不包含任何字符B
5 CS(包含字符串) 检查A是否包含字符串B
6 NS(不包含字符串) 检查A是否不包含字符串B
7 CP(包含模式) 检查A是否包含B中的模式
8 NP(不包含模式) 检查A是否不包含B中的模式

示例代码

1
2
3
4
5
6
7
8
REPORT YS_SEP_08.
DATA:
P(10) TYPE C VALUE 'APPLE',
Q(10) TYPE C VALUE 'CHAIR'.

IF P CA Q.
WRITE: / 'P contains at least one character of Q'.
ENDIF.

输出

1
P contains at least one character of Q.

🎯 运算符优先级



graph TD
    A[运算符优先级] --> B[高优先级]
    A --> C[低优先级]
    
    B --> B1[算术运算符:*, /, MOD]
    B --> B2[算术运算符:+, -]
    B --> B3[比较运算符:=, <>, >, <, >=, <=]
    B --> B4[逻辑运算符:AND, OR, NOT]
    
    C --> C1[字符串运算符]
    C --> C2[按位运算符]

使用括号控制优先级

1
2
3
4
5
" 默认优先级:1 + 2 * 3 = 7
Result = 1 + 2 * 3.

" 使用括号改变优先级:(1 + 2) * 3 = 9
Result = (1 + 2) * 3.

💡 实际应用示例

1. 数值计算

1
2
3
4
5
6
7
8
" 计算平均值
DATA:
num1 TYPE I VALUE 100,
num2 TYPE I VALUE 200,
num3 TYPE I VALUE 300,
average TYPE F.

average = ( num1 + num2 + num3 ) / 3.

2. 条件判断

1
2
3
4
5
" 复杂条件
IF ( age >= 18 AND salary > 5000 )
OR ( status = 'VIP' ).
WRITE: / '符合条件'.
ENDIF.

3. 字符串处理

1
2
3
4
" 检查邮箱格式
IF email CP '*@*.*'.
WRITE: / '有效邮箱格式'.
ENDIF.

💡 最佳实践

1. 运算符使用原则

  • 使用有意义的变量名
  • 添加括号明确运算顺序
  • 避免复杂的嵌套表达式
  • 注释复杂的运算逻辑

2. 比较运算符使用

  • 优先使用有意义的替代形式(如GT而不是>)
  • 注意数据类型的自动转换
  • 对于NULL值检查使用IS INITIAL

3. 字符串运算符使用

  • 根据需求选择合适的运算符
  • 注意区分字符和字符串运算
  • 使用模式匹配时注意通配符

4. 性能考虑

  • 避免在循环中进行复杂运算
  • 合理使用运算符优先级
  • 注意大数据量下的运算效率

5. 代码可读性

  • 复杂表达式拆分为多行
  • 使用有意义的临时变量
  • 添加必要的注释说明

SCM600 销售和分销流程 - MOC

ℹ️Course Information
  • Course Code: SCM600
  • Course Name: 销售和分销流程 (Sales and Distribution Processes)
  • Module: SD (Sales and Distribution)
  • Duration: 5 days
  • Target: Project Team Leaders, Project Team Members

Topic Map (主题地图)

Unit 1: Enterprise Structure (企业结构)

  • [[01-Enterprise-Structure/Org-Units-Overview]] → Organizational Units Overview
  • [[01-Enterprise-Structure/Sales-Area-Structure]] → Sales Area Structure
  • [[01-Enterprise-Structure/Shipping-Structure]] → Shipping Structure
  • [[01-Enterprise-Structure/IDES-Company-Structure]] → IDES Company Structure
  • [[01-Enterprise-Structure/Practice-01-Org-Structure]] → Exercise 1

Unit 2: Process Overview (流程概览)

  • [[02-Process-Overview/SD-Process-Chain]] → SD Process Chain
  • [[02-Process-Overview/Sales-Processing]] → Sales Processing
  • [[02-Process-Overview/Shipping-Processing]] → Shipping Processing
  • [[02-Process-Overview/Billing-Processing]] → Billing Processing
  • [[02-Process-Overview/Practice-02-SD-Process]] → Exercise 2

Unit 3: Master Data (主数据)

  • [[03-Master-Data/Customer-Master]] → Customer Master Data
  • [[03-Master-Data/Material-Master]] → Material Master Data
  • [[03-Master-Data/Customer-Material-Info]] → Customer-Material Info Record
  • [[03-Master-Data/Condition-Records]] → Condition Records for Pricing
  • [[03-Master-Data/Other-Master-Data]] → Other Master Data
  • [[03-Master-Data/Practice-03-05-Master-Data]] → Exercises 3-5

Unit 4: Data Determination & Central Processing (数据确定和集中处理)

  • [[04-Data-Determination/Sales-Document-Types]] → Sales Document Types
  • [[04-Data-Determination/Plant-Shipping-Route]] → Plant, Shipping Point, Route Determination
  • [[04-Data-Determination/Shipping-Planning]] → Shipping Planning
  • [[04-Data-Determination/Central-Processing]] → Central Processing in SD
  • [[04-Data-Determination/Practice-06-07-Data-Determination]] → Exercises 6-7

Unit 5: Availability Check (可用性检查)

  • [[05-Availability-Check/ATP-Basics]] → ATP Basics
  • [[05-Availability-Check/Business-Scenarios]] → Sample Business Scenarios
  • [[05-Availability-Check/Transportation]] → Transportation Processing
  • [[05-Availability-Check/Practice-08-09-Availability]] → Exercises 8-9

Unit 6: Make-to-Order (按订单生产)

  • [[06-Make-to-Order/Presales-Processing]] → Presales Processing
  • [[06-Make-to-Order/Item-Categories]] → Item Category Functions
  • [[06-Make-to-Order/Assembly-Processing]] → Assembly Processing
  • [[06-Make-to-Order/Practice-10-11-MTO]] → Exercises 10-11

Unit 7: Complaint Processing (投诉处理)

  • [[07-Complaints/Credit-Memo]] → Credit Memo Requests
  • [[07-Complaints/Returns]] → Returns Processing
  • [[07-Complaints/Invoice-Correction]] → Invoice Correction Requests
  • [[07-Complaints/Practice-12-Complaints]] → Exercise 12

Unit 8: Process Analysis (流程分析)

  • [[08-Analysis/Lists-Reports]] → Lists and Reports
  • [[08-Analysis/Sales-Information-System]] → Sales Information System (SIS)
  • [[08-Analysis/Business-Warehouse]] → Business Information Warehouse (BW)
  • [[08-Analysis/Practice-13-15-Analysis]] → Exercises 13-15

Unit 9: SAP CRM Integration (SAP CRM 集成)

  • [[09-CRM-Integration/CRM-Functions]] → SAP CRM in SD Environment

Unit 10: SAP Roles (SAP 角色)

  • [[10-SAP-Roles/Internal-Sales-Rep]] → Internal Sales Representative Role

Unit 11: IMG Overview (IMG 概览)

  • [[11-IMG-Overview/IMG-Functions]] → IMG Functions & Solution Manager

Unit 12: Appendix (附录)

  • [[12-Appendix/Login-Screen]] → Login and Screen Design
  • [[12-Appendix/Functions-Personalization]] → Select Functions and Personalization
  • [[12-Appendix/Help-Options]] → Help Options
  • [[12-Appendix/Practice-16-18-Appendix]] → Exercises 16-18

Practice Notes (练习笔记)

All practice exercises are organized by unit with their respective concept notes.

Study Tools (学习工具)

  • [[00-Dashboard/00-Quick-Reference]] → Quick Reference Guide
  • [[00-Dashboard/00-Exam-Traps]] → Common Exam Traps
  • [[00-Dashboard/00-Tag-Index]] → Tag Index

Tag Index (标签索引)

  • #sap #sd #concept → All concept notes
  • #sap #sd #practice → All practice notes
  • See [[00-Dashboard/00-Tag-Index]] for complete tag hierarchy

Weak Areas (待强化领域)

ℹ️Track your weak areas here
Add links to concepts you need to review:
  • [[…]] → Topic name

Non-Core Topic Policy (非核心主题说明)

⚠️Note on Scope
This StudyVault focuses on core SD concepts covered in SCM600. Advanced topics (customizing, deep technical details) are marked as non-core and can be added later based on needs.

Exam Traps (考试陷阱)

⚠️Common Pitfalls
This page lists common mistakes and traps in SD exams. Each trap links to the relevant concept note.

Organizational Structure Traps

Trap: Sales Area Assignments
Question: Can a sales organization be assigned to multiple company codes?

Wrong Answer: Yes
Correct Answer: No - A sales organization can only be assigned to ONE company code. However, multiple sales organizations can be assigned to one company code.

→ [[01-Enterprise-Structure/Org-Units-Overview]]

Trap: Shipping Point Assignment
Question: How are shipping points assigned?

Wrong Answer: Shipping points are assigned directly to sales organizations.
Correct Answer: Shipping points are assigned to plants, not directly to sales organizations.

→ [[01-Enterprise-Structure/Shipping-Structure]]

Trap: Multiple Distribution Channels
Question: Can one distribution channel be assigned to multiple sales organizations?

Correct Answer: Yes - A distribution channel can be assigned to multiple sales organizations.

→ [[01-Enterprise-Structure/Sales-Area-Structure]]


Master Data Traps

Trap: Customer Master Number Assignment
Question: How are customer numbers assigned?

Key Points:

  • Account Group controls whether number assignment is internal or external
  • Internal: System automatically assigns the next available number
  • External: User must enter a unique number
  • This is set at the account group level, not globally

→ [[03-Master-Data/Customer-Master]]

Trap: One-Time Customers
Question: What is special about one-time customers?

Key Points:

  • One-time customers have a single master record
  • Actual customer data (name, address) is entered at document level
  • Used when you don’t want to maintain full master records for occasional customers

→ [[03-Master-Data/Customer-Master]]

Trap: Material Master Views
Question: Who maintains which material master views?

Key Points:

  • Basic Data View: All departments (central maintenance)
  • Sales View: Sales department (pricing, sales unit)
  • Shipping View: Shipping/Plant departments (shipping data, loading grp)
  • Not all views are required for all materials

→ [[03-Master-Data/Material-Master]]


Document Processing Traps

Trap: Sales Area Assignment
Question: Can you change the sales area of a sales document after creation?

Correct Answer: No - Once a sales document is created, its sales area assignment cannot be changed. This is because pricing, master data access, and many other controls are based on sales area.

→ [[04-Data-Determination/Sales-Document-Types]]

Trap: Document Flow
Question: Which documents can follow a sales order?

Key Points:

  • Standard flow: Sales Order → Delivery → Billing
  • Not all documents are mandatory - depends on document type and configuration
  • You can have multiple deliveries from one order (partial deliveries)
  • You can have multiple billing documents from one delivery

→ [[02-Process-Overview/SD-Process-Chain]]

Trap: Delivery Type Determination
Question: How is the delivery type determined?

Key Points:

  • Delivery type is determined based on sales document type + item category
  • Not directly selectable by the user in most cases
  • Configuration in delivery type determination table

→ [[04-Data-Determination/Sales-Document-Types]]


Shipping and Delivery Traps

Trap: Shipping Point Determination
Question: When is shipping point determined?

Key Points:

  • Shipping point is determined at sales order time (not at delivery creation)
  • Based on: Plant + Shipping Conditions (from customer master) + Loading Group (from material master)
  • If multiple shipping points are found, system may require manual selection

→ [[04-Data-Determination/Plant-Shipping-Route]]

Trap: Route Determination
Question: What factors determine the route?

Key Points:

  • Departure Zone (from shipping point master)
  • Transportation Zone (from customer master)
  • Shipping Conditions (from customer master)
  • Transportation Group (from material master)
  • Weight Group (from weight of items)
  • Route is determined at sales order time

→ [[04-Data-Determination/Plant-Shipping-Route]]

Trap: Picking and Shipping
Question: What is the sequence of shipping activities?

Correct Sequence:

  1. Create Delivery (VL01N)
  2. Post Goods Issue (VL02N)
  3. Pick (VL02N) - can be before GI
  4. Pack (VL02N) - optional
  5. Ship (VL02N) - create shipment document

→ [[04-Data-Determination/Shipping-Planning]]


Availability Check Traps

Trap: ATP Logic
Question: What is included in ATP calculation?

Key Points:

  • Warehouse Stock: Physical stock in plant
  • Planned Issues: Outgoing movements (orders, deliveries)
  • Planned Receipts: Incoming movements (purchase orders, production orders)
  • ATP = Warehouse Stock + Planned Receipts - Planned Issues
  • Different checking rules control what’s included

→ [[05-Availability-Check/ATP-Basics]]

Trap: Checking Group vs Checking Rule
Question: What’s the difference?

Key Points:

  • Checking Group: Material-specific (defined in material master)
  • Checking Rule: Transaction-specific (defined in sales order type, etc.)
  • Together they control the availability check scope
  • Example: Different rules for sales order vs delivery

→ [[05-Availability-Check/ATP-Basics]]


Complaint Processing Traps

Trap: Credit Memo vs Returns
Question: What’s the difference between credit memo and returns?

Key Points:

  • Credit Memo Request: No goods movement, only financial credit
  • Returns: Goods are returned from customer, requires delivery and goods receipt
  • Credit memo is faster for financial-only adjustments
  • Returns must track physical goods

→ [[07-Complaints/Credit-Memo]]

Trap: Invoice Correction Request
Question: When should you use invoice correction?

Key Points:

  • Used for correcting billing amount errors
  • Contains both debit and credit items
  • Creates an invoice with corrected amounts
  • Not for returning goods (use Returns instead)

→ [[07-Complaints/Invoice-Correction]]


Pricing and Condition Traps

Trap: Condition Exclusion
Question: How do condition exclusions work?

Key Points:

  • Multiple condition records can exist for same condition type
  • Exclusion indicator prevents certain conditions from being combined
  • Best Condition principle: Most favorable condition is selected
  • Configuration controls which conditions can be combined

→ [[03-Master-Data/Condition-Records]]

Trap: Access Sequence
Question: What is an access sequence?

Key Points:

  • Access Sequence defines the search order for condition records
  • System searches in sequence until it finds a valid record
  • Example: Customer/Material → Customer → Material → All
  • First match wins!

→ [[03-Master-Data/Condition-Records]]


General Exam Tips

💡Memory Aids
  • Sales Area = Sales Org + Dist Channel + Division (remember: S+D+D = Sad)
  • Shipping Point = Plant + Shipping Cond + Loading Grp (remember: P+S+L = PSL)
  • Document Flow: Always remember: Order → Delivery → Billing
  • ATP: Stock + In - Out
💡Question Keywords
  • “Always” or “Never” → These answers are often wrong
  • “Multiple” → Check if it’s N:1 or 1:N relationship
  • “Automatic” → Usually involves configuration/master data
  • “Manual” → Requires user intervention during processing
⚠️Read Carefully
  • Pay attention to: “Sales Organization” vs “Sales Area”
  • “Shipping Point” vs “Plant”
  • “Customer Master” vs “Customer Material Info Record”
  • “Condition Type” vs “Condition Record”

  • [[00-Dashboard/00-Quick-Reference]] → Quick reference for all concepts
  • [[00-Dashboard/00-MOC]] → Complete topic map
0%