Solution 在 SM30保存时检查数据

作者:郑德鼎 约 6 分钟阅读 更新日期:2025-03-02 1 年前更新 标签:ABAP, Data Engineering, SD, WM, 仓库管理, 开发, 数据工程, 销售分销
Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

** 1/7 问题描述 **

在SM30保存时检查数据,你可能会直接修改生成的屏幕,比如Field后面写个Module xx ON REQUEST,或者在 MODULE

LISTE_AFTER_LOOP.前写一个自己的MODULE,执行你的检查代码。 但:

1.当SM30维护器重新生成的时候,屏幕的逻辑流都会重建,导致我们修改的逻辑流都没了;

2.我们在 列表屏 点退出,系统会提示“是否保存数据 ” ,如果点“是 ” ,数据可能还保存上,绕过了我们的检查代码。

** 2/7 解决方案 **

更合理的做法是,利用SM30提供的 **事件出口** ( _ 如果你用过事件出口,也不要着急退出,下面可能有你没用过的知识 _ ) 。 如下:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

然后在弹出的屏幕中,选择事件01,并创建一个检查的FORM,如:FRM_CHECK。

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

之后,点击“编辑器 ”列的代码编辑按钮,系统会提示你创建一个INCLUDE程序来包括这个FORM。

** 3/7 新的问题 **

之后,写个测试代码如下:

FORM frm_check. MESSAGE '错误' TYPE 'E'.ENDFORM.

激活所有对象,编辑一下数据,点保存,测试一下效果。 结果意外发生了……如下图:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

虽然系统报了错误,但从SM30的列表屏幕中退出来了,我们更希望是 **能在列表屏提示错误** 。

** 4/7 问题分析 **

1.系统退回到了SM30的初始界面,一定是执行了 **LEAVE** 命令,保存前输入/H,然后保存,再按命令打断点,如下:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

然后,继续执行。果然系统执行到了LEAVE代码处,如下:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

2.可为什么我们保存成功的时候,系统并没有停留在SM30的初始界面,而是在列表屏呢?这说明,系统执行了LEAVE后,又执行了类似 **CALL

SCREEN** 之类的命令,跳转到了列表屏。

于是再加一个命令断点:CALL SCREEN,重新执行测试,发现系统果然又执行了CALL SCREEN的命令,如下:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

3.那我们怎么才能让系统既报错误,又能重新执行这个CALL SCREEN的命令呢?

之前我们报的E消息,程序执行到这里就停止了。程序停止保存动作是我们想要的结果,但这个E类型消息满足不了我们的要求,所以我们应该考虑 **RAISE异常**

于是我们看看 **程序堆栈** 中 是 不是有函数调用,函数中是不是有 **EXCEPTION** 参数,如下:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

** 5/7 最终方案 **

通过上面的程序堆栈可以看出,我们自己写的检查FORM的代码,是在这个FUNCTION中调用的,而且这个FUNCTION提供了异常saving_correction_failed的异常。所以我们改一下检查的代码:

FORM frm_check. MESSAGE '错误' TYPE 'S' DISPLAY LIKE 'E'. RAISE saving_correction_failed.ENDFORM.

再重新执行测试一下,果然没有问题了,错误消息完美的在列表屏中显示出来了:

Solution 在 SM30保存时检查数据 - 封面图
Solution 在 SM30保存时检查数据 - 封面图

** 6/7 更多知识 **

SM30维护器函数有两个比较重要的公共内表,分别是 **EXTRACT** 和 **TOTAL** 。

EXTRACT指的是 **当前TableControl** 里的数据。比如你点新条目时,输入了两行新数据,那么EXTRACT就只有两行。 所以

进行事件增强前,一定要想好是要用哪个内表。

TOTAL指的是所有数据,包括删除还未保存的行项目。

循环EXTRACT的时候,<XACT> <VIM_EXTRACT_STRUC>会发生变化;

循环TOTAL的时候,<ACTION> <VIM_TOTAL_STRUC>会变化。

其中<XACT>和<ACTION>代表的是循环到的行的 **操作状态** (比如D代表删除 ),而另外两个则是工作区 。

使用方法:

DATA: ls_sl01 TYPE ysl01. "YSL01是表名 LOOP AT total. MOVE-CORRESPONDING <vim_total_struc> TO ls_sl01. ENDLOOP.

**7/7 总结**

我的文章基本不会只罗列解决方案,而是会把解决问题的思路讲清楚。毕竟会一个知识点那只是会了 **术** ,而会了方法掌握了策略才是得了更高一级的 **法**

我的SE38插件工具箱——视频介绍:

** https://www.bilibili.com/video/BV1hP4y1N7Qz/ **

联系286503700获取

> **ABAP文章汇总:**

>

> **https://mp.weixin.qq.com/s/djmMeM0qfDxPPwxbjuJABA**

>

> **Excel文章汇总:**

>

> **https://mp.weixin.qq.com/s/NwJ0SzIrn9hVmaCMo-UYyA**

>

> **网盘永久链接:**

>

> **https://mp.weixin.qq.com/s/f_WwKZdwM-vPEstTjjz_eQ**

**关注公众号,点下方菜单打开上面的链接,更方便哦。**

**笔者微信:** **** **286503700(QQ同号)** ****

**如果喜欢,谢谢转发。**

郑德鼎

关于作者:郑德鼎

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「Solution在SM30保存时检查数据.md」整理生成,仅用于内部技术分享与学习交流。