where条件中怎么设定字句优先级_总结|对日ABAP编程中的一些注意点

在做项目过程中有很多细节的东西,其实很简单但是有时候就是在不经意间出错。

这里从多个方面整理出一些注意事项方便经常翻一翻,可能还有很多不足,以后慢慢再更新。

关于扩张和Code inspector检查

这个是对日项目中必须做的且一定要在测试程序之前做,否则测试已经开始了,发现代码还有很多错误和警告那就尴尬了。

1,所有程序写完测试之前先对程序进行扩张和Code inspector检查

  a,错误:红色的错误信息,一般项目都会要求不能有错误信息。除非是因为要满足设计要求无法对应的可以说明不对应。

  b,警告:能够对应的尽量要对应掉。

  c,信息:一般不做特别要求

扩张

8f5516e305099f75c92c97e7ea8f9388.png

6d77b8c66e2019ccf778e781345338e2.png

Code inspector

756d4f02d0fa1aa0f6a5c5fd3fb690ac.png

关于内表操作的

1,根据modify更新内部表时,要用TRANSPORTING来确定更新的项目

2,在LOOP中做MODIFY更新内表的当前行时,用的语句是MODIFY itab FROM wa [INDEX idx],这句在循环中是按索引更新,而不是MODIFY TABLE itab FROM wa.这是把非数字型的字段作为KEY来更新,如果有重复KEY则更新第一条。

3,尽量不要在LOOP处理内表时添加和删除数据行,如果一定要做这类操作,注意以下几点

  a,直接用APPEND添加的行会插到当前处理行的下一行,会造成LOOP的死循环

  b,用INSERT插入,并且制定当前行的话会插入到当前行的前面,在下一次循环处理的时候会使sy-tabix自动加一

  c,删除当前行的话,会在下一次循环处理的时候使sy-tabix自动减一

二分法查询

关于READ TABLE … BINARY SEARCH二分法查询

对于大量数据时能够提高执行效率,但是使用一定要注意不能忘记先按查询字段排序,否则会出现错误的查询结果

关于OPEN SQL

1,不用括号的情况下 “非(NOT)”的优先级大于“与(AND)”,“与(AND)”的优先级大于“或(OR)”

2,尽量不要在WHERE中的OR运算符连接的表达式中出现IN,一旦当IN右边的range表为空的时候,这个条件始终为“真”,所以由OR连接的所有条件构成的逻辑表达式为“真”,无法过滤任何数据。除非你确定你要这么做。

例:    SELECT * INTO CORRESPONDING FIELDS OF TABLE td_spfli FROM spfli

      where countryto = 'US'

        and carrid = 'AA'

        and ( period = 0

        or countryfr in s_fr ) .

这里如果s_fr为空的话,countryfr in s_fr条件为真,括号里的period = 0也就没有过滤作用了,因为整个括号里的条件都为真

    SELECT * INTO CORRESPONDING FIELDS OF TABLE td_spfli FROM spfli

      where countryto = 'US'      where ( countryto = 'US'

        and carrid = 'AA'                and carrid = 'AA'

        and period = 0                   and period = 0 )

        or countryfr in s_fr.             or countryfr in s_fr.

以上两个WHERE条件是等价的,这里如果s_fr为空的话,countryfr in s_fr条件为真,前面三个由and连接的条件也没有过滤作用了,整个表达式都为真

尽量不要在WHERE中的AND运算符连接的表达式中出现NOT IN

3,在NOT IN的时候,一旦当NOT IN右边的range表为空的时候,这个条件始终为“假”,

所以由AND连接的所有条件构成的逻辑表达式为“假”,会过滤所有数据。除非你确定你要这么做。

关于LOOP的关键字AT的注意点

1,在LOOP有使用WHERE和FROM,TO的时候不要使用AT关键字(这在扩张检查中会提示红色错误,但编译运行不会出错)

2,在AT NEW和AT END中,LOOP赋值的构造中所有的AT的字段右边的变量都将暂时变为*

3,AT NEW和AT END并不是指AT指定的那个变量出现变化了,而是指这个构造中这个变量左边所有的变量任何一个出现变化

关于FOR ALL ENTRIES IN 的注意点

1,使用FOR ALL ENTRIES IN 的时候,注意抽出的数据中会自动删除所有重复的数据。如果是在抽出数据中有金额等集计项目时,一定要将能区分唯一记录的KEY项目一同抽出

3,注意在抽出前,一定要检查一下FOR ALL ENTRIES 使用的内表是否为空,因为当此内表为空时WHERE的条件会全部被忽略,变成全件抽出

4,不要在for all entries in的内表中出现重复的条件。

重复的条件会进行重复的抽取,而重复的数据又会被删除,所以请事先对条件内表用所需条件进行排序和删除,避免效率上的浪费

关于变量与类型

SAP中对类型的控制非常严格,对类型的定义,转换,存取一定要谨慎,不要很随意的定义一个类型,或者变换一个数据库中本来的类型。

1,在程序中,对于数值项目(I型,CURRENCY,DEC等)的IF判断,不要使用单引号'' 或字符类型。

2,不要让字符类型参与到数值运算中

关于金额和数量类型的计算和输出

1,开发中,绝对禁止用类似 *100  或者 /100的形式进行金额的内外部变换。

如果想要得到这种金额外部形式的转换系数,请用函数CURRENCY_CONVERTING_FACTOR得到。

2,无论是ALV输出还是WRITE输出,金额和数量一定要有货币和单位的参照,除非你确定不要那么做(例如需要输出小数位的日元)。

3,程序中一旦涉及到金额,数量的合计时,要有溢出处理

关于变量

1,read一个内表到构造之前,一定要先对构造做清空处理,因为如果read失败,这个构造会保持原来的值,会容易引起后面处理的失误

2,在需要使用变量初期值的时候,一定要先清空变量,而不是在使用变量后清空。当程序的复杂度增加的时候,你不一定能确定使用的时候是否已经被清空过

3,在程序完成后不要忘了检查一下定义的所有的全局变量,并在初始化的时候清空。

4,日期和时间(d和t)类型的变量初始化状态是全0而不是空串,一个被赋值为空串的日期或时间类型判断is initial的话会结果为假。所以如果想要初始化任何一种变量,都不要去给变量赋值,包括给字符型的赋值空串,而是要CLEAR这个变量,这是一种比较好的编程习惯。

5,在循环处理的时候,一定要仔细检查在循环中使用的变量是否需要清空 6,select-options定义的变量是一个带表头的range表,在使用时要注意带表头内表的特殊性。(S_MATNR和S_MATNR[]的区别)

关于系统变量的使用注意点

1,使用SY开头的系统变量的时候一定要在需要使用这个变量的那个时点把这个系统变量赋值到自定义变量中暂存,然后再使用。因为系统变量的控制权不在你程序里,你不一定能确定它何时发生变化。例如在LOOP中使用的SY-TABIX等等

2,大多数sy-subrc都在有处理执行后立即判断,所以这种处理后立即判断的情况不一定需要。但如果处理后不能立即判断,需要运行其他语句,请根据1中方法用临时变量接一下。

关于FORM的参数

1,不要使用FORM定义型参中的TABLES关键字,使用TABLES定义的型参会自动转成带表头的形式,在我们不习惯处理这种带表头内表的情况下容易造成失误。

2,FORM中的changing传入的型参习惯上要在FORM的开始就清空,确保要输出的变量是form中处理输出的,而不是外部残留的,

3,如果是需要传入的参数应该要写在using中,这样功能上比较清晰

4,默认的USING和CHANGING都是引用传递,一定要注意USING的形参最好不要直接使用,赋值到局部变量再使用。对USING形参的操作直接会改变实参的值,如果是要值传递,请在USING后加上VALUE关键字

5,在对CHANGING的形参进行操作时,如果是带有VALUE关键字的值传递,则不会直接改变实参的值,而是在PROFORM结束后才会返回一个形参的拷贝

6,不要把一个全局变量作为参数传入form,同时又在这个form中操作这个全局变量

7,避免不同变量类型之间的直接转换,如果一定要转,在不确定的情况下最好先去查一下帮助文档里的各类型互相转换规则

b9ae0ecf956ef9e7b0ce14b78b5f7d2e.png

关于字段符号(field-symbols)

1,字段符号在被分配以后,一定要立刻判断SY-SUBRC是否成功,再进行后续处理,因为一旦没有分配成功,存取操作将造成程序崩溃。

关于内外部形式

1,一般需要提供给用户看的变量(alv,报表画面,文件输出等等),大都需要转换成这个变量的外部形式

2,任何一种数据库中直接取得变量,都一定是这个变量的内部形式。

3,程序对文件中数据的读取和写入,是内部还是外部一定要和设计者确认清楚在处理。

ps:查询DB的时候如何看到外部形式和内部形式

a,推荐使用在SE16N,双击行弹出界面可以看到内外部格式

1bfb8f7e66580edff60c1fbbc7cdbfc2.png

b,SE11或SE16中查看需要设置一下

f8104863143c3088fe9afec1393a5527.png

6c7243668eac2b0322c5aac796ac91ce.png

关于ALV

在取自定义构造的fieldcatalog时,使用REUSE_ALV_FIELDCATALOG_MERGE的各种注意点

1,系统变量不要直接给函数的参数,要先赋值给一个自定义变量

2,构造的名称赋值的时候一定要全部大写

3,构造中的字段一定要使用LIKE定义,如果要使用TYPE的话则一定要是基本类型

4,构造的定义一定要用OCCURS关键字(这是废止无效的关键字,但是如果非要用这个函数就没办法)

如果不满足以上条件,会使fieldcatalog取不到

5,所有的变量最好都要用他本来的类型来显示,输出格式要通过fieldcatalog的设置来控制,例如数字型的变量用字符型来显示,这样就无法使用系统提供的合计等统计功能

6,ALV中没有直接的使数字负号提前显示的方法,需要自己开发一个转换函数,并在FIELDCAT里的EDIT_MASK属性中设置。

7,有时候构造中定义了某个字段,比如通货code,这个是用来作为金额的参考不需要在ALV画面显示。建议不要把他用no_out隐藏掉,这样还是能通过ALV中的隐藏字段设置让他显示,应该是设为技术字段(TECH属性),或者不要加入到fieldcatalog中

关于批处理

1,在批处理中,系统画面的出错信息不一定是E型的,有时候错误信息是S型的或是别的,在写判断前最好确定一下。

2,在BDC表中编辑的画面字段变量,填的都是这个变量的外部形式,用之前最好调查一下这个字段的DOMAIN中有没有内外部转换。

关于DYNPRO

1,画面字段变量如果是数字,日期或时间类型的话,定义长度一定要是外部形式的长度,否则输出长度大于画面显示长度,会使这个画面在PBO结束的时候崩溃。

如何通过定义的domain确定该变量长度,可参考下面

01dcb3cc9193547e2d10996de33ba460.png

2,在不同屏幕之间跳转不要使用Call SCREEN ,这样在两个屏幕之间反复跳转超过50次就会堆栈溢出,要使用LEAVE TO SCREEN

3,使用MODIFY SCREEN来改变屏幕控件的属性时,只能用在DYNPRO画面的PBO里或是选择屏幕的AT SELECTION-SCREEN OUTPUT里,在报表处理中,AT SELECTION-SCREEN OUTPUT事件就相当于选择屏幕的PBO事件

4,对于有表格的画面,在编辑数据的时候不要忘了表格的翻页或是定位行处理。

关于UNICODE环境下字符的存储与显示

1,UNICODE的存储位数和显示所需的位数是两回事,双字节与单字节字符存储是都是占一位,显示的话,双字节占两位。如果要按字节数取字符串的话,不能直接按位数取,要使用CL_ABAP_LIST_UTILITIES=>READ_FROM_DISPLAY_LAYOUT,或者TEXT_SPLIT,推荐优先使用类里的方法

ee3d9928d14c9c62efa6ad31c37de3c2.png

关于SAP MEMORY 和ABAP MEMORY

SAP MEMORY 有可能在程序运行的时候被同一个客户端的另一个程序改动,所以在使用时候要谨慎

1,SAP内存使用SET/GET parameters方法;

SET PARAMETER ID 'MAT' field p_matnr.

GET PARAMETER ID 'MAT' field p_matnr.

用户登陆后,最多一个系统可以开6个窗口,这在SAP中称为External Mode。

SAP Memory,它是属于External Mode间可以共享的数据

2,ABAP内存使用 EXPORT 和 IMPORT  方法;

export p_matnr = p_matnr to memory id 'ZTESTMAT'.

import p_matnr = p_matnr from memory id 'ZTESTMAT'

而同一个窗口中,运行某程序后,可以通过CALL TRANSACTION/SUBMIT或其他代码跳转到其他程序,这个称为Internal Mode。Internal Mode的调用栈最多为9层。

那么ABAP Memory,它是属于Internal Mode间可以共享的数据,而在External Mode间无法共享。

关于锁表

1,解锁一定要在commit之后做。一定要事务提交或者回滚之后才可以解锁。

2,对于上了锁的表,在对其操作完后一定不要忘解锁。

关于效率

1,效率是一把双刃剑,建议在对效率要求不高的时候,优先考虑代码的可读性,可维护性和扩展性,不必要写的过于精简和优化

2,不要简单的认为在循环,内表数据处理,这种需要反复操作的代码只会执行一个较小的次数,想象一下有几百万条数据的时候是什么状况,就会在效率问题上有更多考虑

3,虽然ABAP拥有垃圾处理的机制, 但是这个是在程序运行完成后实现的。所以我们尽量在一段逻辑或者一个FORM结束时就把无用的变量,内表,对象都释放掉。

4,在进行内部表的sort时,一定要指定排序key

5,注意使用CORRESPONDING FIELDS OF 和  MOVE-CORRESPONDING 时候会进行字段比较, 带来CPU的很大负担

6,尽量在LOOP中减少数据库的连接

7,在select语句中,如果遇到需要用up to 1 rows 时,最好加上exit.效率会快一点的。

8,SELECT A B C INTO TABLE ITAB这样操作会将所有符合条件的数据一次性地读进内表,

这比在SELECT A B C INTO WA... APPEND... ENDSELECT的循环中添加数据到内表更快,因为不用频繁的读取DB

9,使用SQL语句里面的JOIN时候, 应该避免JOIN的表不要超过3个, 否则严重影响效率. 如果真的要JOIN表3个以上的话, 正确的方法是使用SELECT ... INTO TABLE ... FOR ALL ENTRIES IN 以及 READ TABLE WITH KEY BINARY SEARCH,以获得最大的效率

10,避免过多而频繁的数据类型转换

11,避免使用SQL语句动态查询条件,动态表名和动态字段名

12,对于同一功能的函数和方法, 调用METHOD比调用FUNCTION要快,所以有类似功能的,优先使用类的方法

13,使用APPEND LINES(或者INSERT LINES) OF ITAB1 TO ITAB2 比 LOOP AT ITAB1 INTO WA. APPEND(INSERT) WA TO ITAB2. ENDLOOP. 要高效

代码规范

规范的代码不仅自己能看懂,也要保证接手你工作的人也能看懂。并且要保证别人或是几个月后的自己也能看得懂。

1,规范的命名变量和FORM,尽量不要用那种LW_A,LW_B,LTD_C之类,完全不知道是什么。推荐使用:lw_werks,ltd_eban_data之类的。

2,适当的注释,特别是在有逻辑分歧,form和函数调用的时候

3,尽量在定义FORM的时候使用带有参数的,第一可以使人更清楚这个FORM在处理什么数据,输出什么结果。第二可以在调试的时候直接看到这个FORM的处理结果,而不要去找全局变量或是进到FORM里面

4,不要用过多的flg来判断状态

5,尽量减少缩进的层次,loop,if之类,一个有三四层loop再加三四层if…elseif… 像金字塔一样的代码,比如下面这样,是不是要MMP?

loop at xxx into xxx.  loop at xxx into xxx where xxx.    if xxx      if xxx        xxx      else.        xxx      endif.    elseif xxx      if xxx        xxx      else.        xxx      endif.    elseif xxx.      xxx    elseif xxx.      xxx    elseif xxx.      xxx    else.      xxx    endif.  endloop.endloop.

6,关于if和case的用法,当条件分歧在三个以上的话最好用case。

7,WHERE中同时有AND和OR运算符的时候一定要以你确定的优先级用括号分开,不要使用默认的优先级

8,不要使用任何关键字或语法的默认属性和隐式声明,即使你清楚的知道这个默认的定义,也都要明确的写出来。例如:定义类型是C默认为一个字节的,排序时默认为升序,LOOP中MODIFY的默认使用当前索引等等

9,要习惯对代码进行合理封装,全部写在一个FORM下这样的代码看起来头大。

一般一个FORM封装标准:

a,一块清晰独立的业务逻辑。

b,一段完成某个功能的独立的处理逻辑

10,在使用函数,类的方法,和message等的时候一定要用编辑器里的“模式插入”,不要手写也不要复制试样上的,会避免一些遗漏与错误。

9f6fdd11824227d6b70c01c1a0e7005d.png

日语遇上搬砖

 每天一起进步一点点

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值