我用ABAP做过的那些无聊的事情
国庆大假马上就要来临了,我们聊点轻松的话题,关于假期。
Jerry的成都同事李贝宁(Li Ben), 《SAP成都研究院李三郎:SCP Application Router简介》的作者,有一次11月份的时候和Jerry一起去德国出差,不解地问到:德国好歹也有八千多万人口,怎么街上冷冷清清的几乎看不到人呢?
对于这个问题Jerry也没有答案。而且这种现象在德国的法定节假日里更加突出。
Jerry的文章《Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现》曾经提到,去年我在德国待了三个月,最难熬的就是德国几乎每个月都有那么几天的法定节假日,因为既然放假,SAP总部的员工食堂就不开了,而且商店也全部关门,得提前一天备好干粮。
SAP德国总部员工食堂的伙食是非常非常好的,就在Jerry写这段文字时,仿佛又闻到了中午饭点时走近食堂,从里面散发出食物的香味。
总部员工食堂菜的味道有甜有酸,有些汤的味道稍稍带着苦味,没有辣味,正好Jerry讨厌吃辣,所以口味非常适合我,我一连吃了90天也不觉得腻。
荤素搭配很合理,而且肉和菜吃不够随便加,管饱,对于Jerry这种饭量大的程序猿来说简直是天堂。
这些食物太美味了,每顿饭结束后我都是这个状态:
然而到了德国法定节假日和星期日,这一切都消失了。德国商店的营业时间一直按照20世纪50年代的规定执行的:商店在工作日最晚开到下午六点半,周六最晚下午2点关闭,周日全天不营业。
于是,2017年五一小长假,4月29日~5月1日三天,Jerry只好靠这些干粮充饥,三天一共只花了9欧元。
Jerry是一个程序猿,对吃的不挑剔,Zopf很经饿。什么是Zopf?
我住在德国乡下,平时也难得见到人,更别提节假日了。街上全是这种风格:
要不是耳边传来偶尔驶过的汽车和德国小朋友在自己花园里嬉戏的声音,Jerry还以为自己来到了科幻电影《我是传奇》里的世界。
五一小长假的最后一天,我的同事Liang Simon(梁亚舒)邀请我到他的家中,吃了一顿地道的德国烤肉。在此之前啃了两天Zopf的我,觉得这是我这辈子吃过的最美味的烤肉!烤肉一扫光后,Simon的老婆又端出一个自己动手做的巧克力蛋糕。
Jerry吃完之后,心里遗憾地想:当初这个蛋糕制作的时候,半径再大几厘米就更完美了。
在这种情况下,作为一个程序猿,娱乐的方式就只剩撸代码了。所以本文提到的这些东西都是Jerry在德国节假日里无聊的产物,对于ABAP顾问的实际工作可能帮助不大。不过因为是过节,大家当看看小说消遣好了。
1. Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
把本科学过的八种排序算法用ABAP逐一实现了一次。
SAP社区上有一位网友Sinai可能觉得我是吃饱了撑着没事干(这倒是事实),毕竟在ABAP里要排序直接使用关键字SORT即可。
不过幸好还有另外的网友跳出来为我辩护,中心思想就四个字:开心就好。
2. 不用四则运算符比较两个整数的大小
看文字描述就能感觉到这又是一个让程序猿感觉很囧的需求。
使用位操作,JavaScript可以很优雅地实现:
Java也没问题:
轮到ABAP就麻烦了。因为ABAP的BIT-XOR这种位操作不支持整型类型。
既然语言层面不支持,就只好自己动手模拟了。
我用一个尺寸为32的ABAP内表存储一个32位整数的每一个bit的值,然后基于这个内表模拟了整数的与或非以及异或操作,还有按位左移,右移。
让ABAP整数也能像上图JavaScript和Java那样支持按位逻辑操作的模拟实现代码在我的博客里:
Bitwise operation ( OR, AND, XOR ) on ABAP Integer
用这种模拟方式实现的ABAP代码比JavaScript和Java足足长了一倍。虽然丑陋,但好歹实现了题目的需求。
3. 给出尽可能多的计算两个整数和的方案
下面的答案可以归纳为:
-
普通程序员的答案
-
2B程序员的答案
-
文艺程序员的答案
-
闲得蛋疼的程序员的答案
-
。。。
最后一种解法实际就是本科计算机原理里介绍的加法器:通过按位逻辑与运算(&)判断当前位操作是否有进位产生,用按位逻辑或运算(|)保存当前位进位的值。
最后一种解决方案的ABAP版本:
下面就是一些小工具了。
1. 如果您是一位ABAP顾问,您知道每个月,哪个SAP事务码被自己使用最多次数么?
只需写一个简单的ABAP报表,执行就能知道答案。报表的源代码可以通过点击文末"阅读原文"获得。下图是Jerry在SAP内部的开发系统执行该报表后的结果,排在第一位的SE24,一个月使用了713次不奇怪,令我吃惊的是SAT居然使用了692次。不用说,这个月一定在和各种与性能相关的incident进行苦战。
2. 增强的ABAP代码版本管理功能。
打个比方, 如果我想查找一行注释"* Wave 12 Schema version is 7"最早是在哪一个ABAP代码改动版本引入的,最后发现是第45个版本引入的。
在实际工作中,SAP的开发人员经常需要做类似的事情,比如分析一个bug,最后定位到是引入了某一行代码引起的,然后就需要找到是哪一个请求号对应的版本引入的这行有问题的代码。
但是,这个方法一共有77个版本,难道我要从第一个版本开始,将其和当前版本比较,一直比较到最后一个版本?
这个是纯粹的体力活,时间复杂度o(n)。我们也可以用二分查找的思路,把77个版本中间的版本即版本39和当前版本比较,如果版本39没有出现我们要查找的代码,就对版本40和77这个区间段再次使用二分查找。
这种查找办法只是把时间复杂度降成了对数级别,这种体力活仍然让我心烦意乱。有没有o(1)的解决方案?
当然有。就是把这个方法每个版本的源代码全部下载到本地保存成一个txt文件,里面的版本内容从低到高排序,然后直接按照要查找的关键字进行搜索,瞬间即可得出答案。
有了这个本地文件,我可以用文本编辑器同时打开它两次,然后可以通过鼠标滑动的方式,快捷地比较任意两个版本的差异,而不需要SAPGUI"选择待比较的版本->点击比较按钮->查看比较结果->点回退按钮->选择下一组要比较的版本"这种笨拙的操作,工作效率得到质的提升。
在我心中,重复的鼠标点击对于程序猿来说就是万恶之源。
这个工具的源代码可以通过点击"阅读原文"获得。
3. 增强的SAT功能。
SAP成都研究院CRM开发团队曾经接到一个CRM On HANA的测试项目,就是在两个系统上同时运行一系列相同的ABAP代码,这两个系统底层的数据库分别是非HANA数据库和HANA数据库,通过这种方式评测SAP CRM运行在HANA数据库上的性能。一旦发现某些代码在HANA数据库上运行的性能还不如非HANA数据库,就找出原因,对相应代码做优化。
当时,德国同事给我们的要求就是,在两个系统分别用SAT运行应用,然后手动分析SAT结果,把在数据库为HANA的系统上运行速度慢于非HANA系统的点都找出来,写成文档。
我当时一接到这个项目,心里暗暗叫苦:这不又是纯体力活么。如果待测试的一段代码调用了非常多的API,那岂不是要把这些API在两个系统上执行的时间一个一个找出来手动比较么?就算用双屏,脑袋也要像波浪鼓一样左右晃动,这又不是在练习自由泳的转头换气。
后来Jerry就写了一个工具自动进行比较。下图是工具界面,HN1和Q2U是这两个系统的代号,其中HN1系统后台数据库是HANA,而Q2U后台是非HANA。
Green Threashold指定成50,意思是如果同一个方法,HN1的执行速度比Q2U快50%,则这个方法的比较结果显示成绿灯;Yello Threshold则代表HN1比Q2U快,但只快了20%到50%。如果HN1比Q2U还慢,这就比较糟糕了,是我们需要采取措施的场景。
工具的输出是一个ALV,可以直接导出成excel。
有了这个工具,原本需要填几个小时的excel,现在十秒就能完成。节省下来的时间可以花费到亮红灯的那些结果,即真正需要进行HANA数据库调优的那些代码中去。
后来Jerry把这个工具秀给了德国的项目主管,他很喜欢这个工具,让我在一个内部会议上给SAP全球其他地区的同事讲讲工具怎么用。这也是Jerry在这篇文章里介绍的众多用ABAP搞出来的无聊的东西里唯一被SAP官方认可的工具,囧。
这个工具的完整代码通过点击"阅读原文"获得。
4. 直接用excel执行SAPGUI里的事务码或者函数。
作为一个SAP ABAP开发人员,SAPGUI上的系统清单总是很长很长,这还是我清理过多次,删除了若干很少使用系统之后的清单。有些系统我每天登陆上去只是为了看几个简单的事务码,比如SM04,ST22,SE10这些。为此,每天我都要在SAPGUI里选中某个系统,双击之后进行登录,然后在键盘上输入事务码。
很快我的懒癌又犯了,因为我在这些系统上并不会进行开发工作,那么有没有办法不用SAPGUI登录系统,也能执行事务码并查看结果呢?有,用excel。在excel里做几个按钮,每个按钮的事件处理函数用VB硬编码成对应系统的地址,系统编号,用户名和密码,以及期望执行的函数或者事务码的名称。
这样以前繁琐的操作,现在双击打开excel啪啪啪点几个按钮,然后切去做其他事情,等一会再切回excel查看结果即可。节省下来的时间可以做其他更有意义的事情。
这种VB代码像下面这样写:
5. 直接在SAPGUI里给同系统其他在线用户打招呼。
执行这个工具,会看到当前系统在线用户列表和每个用户正在使用的事务码。
双击某个用户名称,他/她的SAPGUI里就会出现一个弹出框,上面显示一条预先指定好的文本,比如:
这个恶作剧其实就是通过函数TH_POPUP给指定的用户发送一条文本消息,以弹出框的形式显示出来:
6. 项目经理可以使用的查岗工具。
比如项目经理想查看名叫WANGJER的顾问从2017年3月1日到3月25日这些天到底在系统里做了哪些开发,只需要执行这个工具就能得到清单。
其实写这个工具的初衷是为了方便我快速得回忆起任何一个时间段,比如一个月或者一年以前到底做了哪些开发工作。程序猿上了年纪后记忆力就衰减了,必须要通过工具的辅助。
最后一个是恶作剧。
一天我正在上班的时候,微信上一位partner向我求助,说是这根红色标注的分割线可以往左拖拽。
一旦把它拖到最左边的极限位置后,将无法再调整其位置了。如下图这样,因为左边对象列表的宽度实在太窄,此时SE80其实已经没有办法使用了。
当时Jerry看了这位朋友微信上发过来的截图,半信半疑,还有这种操作?
照着试了一下,结果我也杯具了。
好在我知道有这张表的存在:
一行代码即可让SE80的设置回复到初始设置:
DELETE FROM rseumod WHERE uname = 'WANGJER'.
感谢大家耐心听完我的唠叨,提前祝大家2018年国庆节快乐。
更多阅读
要获取更多Jerry的原创文章,请关注公众号"汪子熙":