ABAP中FIELD-SYMBOLS的详细用法

 (一)定义
1 . FIELD-SYMBOLS: <fs> [<type>]为内部字段定义field-symbols .
    当不输入<type>时﹐<fs>继承赋给它的变量的所有属性
    当输入<type>时﹐赋给它的变量必须与<fs>同类型
例如﹕ (说明﹕用户日期格式为dd.mm.yyyy)

 


FIELD-SYMBOLS: <f1> .
DATA: dat(8) VALUE '19950916' .
ASSIGN dat TO <f1> .
WRITE:/ <f1> .

<f1>继承dat属性﹐为C型﹐输出为: 19950916

 


FIELD-SYMBOLS: <f1> TYPE d.
DATA: dat(8) VALUE '19950916' .
ASSIGN dat TO <f1> .
WRITE:/ <f1> .

<f1>类型为D型﹐而dat为C型﹐类型不匹配﹐出现语法错误

FIELD-SYMBOLS: <f1> TYPE d.
DATA: dat(8) VALUE '19950916' .
ASSIGN dat TO <f1> TYPE 'D' .
WRITE:/ <f1> .

 


<f1>类型为D型﹐而dat为C型﹐类型不匹配﹐但TYPE ‘D’是将dat类型转换成D型再分配给<f1>
     输出为﹕16091995

2.定义结构化的field-symbols
    FIELD-SYMBOLS: <fs> STRUCTURE <s> DEFAULT<f> .
首先将<f>指派给<fs> ,然后<fs>继承结构<s>的属性
注意点: a. <s>中不包涵类型为I或F字段时﹐<f>的定义长度>= <s>所有字段长度之和﹐否则语
法错误
          b. <s>中包涵类型为I或F字段时﹐<f>最好为结构类型﹐且结构应该同与<s> ﹐否则容
易出错

 


例如﹕
DATA: wa(100) VALUE '001LH 123419950627' .
DATA: BEGIN OF line1 ,
          col1(6) TYPE c,
          col2(4) TYPE c,
          col3(8) TYPE c,
       END OF line1.
FIELD-SYMBOLS: <f1> STRUCTURE sbook DEFAULT wa . “sbook为SAP现存结构
FIELD-SYMBOLS: <f2> STRUCTURE line1 DEFAULT wa .
WRITE:/ <f1>-mandt, <f1>-carrid, <f1>-connid,<f1>-fldate .
WRITE:/ <f2>-col1, <f2>-col2, <f2>-col3 .
输出结果﹕ 001 LH 1234 27.06.1995
001LH 1234 19950627

如果下列代码就会出错﹕ (原因wa没有line1长)
DATA: wa(17) VALUE '001LH 123419950627' .
DATA: BEGIN OF line1 ,
          col1(6) TYPE c,
          col2(4) TYPE c,
          col3(8) TYPE c,
       END OF line1.
FIELD-SYMBOLS: <f2> STRUCTURE line1 DEFAULT wa .

结构中含有I, F类型的结构例如﹕
DATA: BEGIN OF line1 ,
          col1 TYPE i,
          col2(4) TYPE c,
       END OF line1.
DATA: BEGIN OF line2,
          col1 TYPE i,
          col2(4) TYPE c ,
       END OF line2 .
line2-col1 = 8 . line2-col2 = 'test' .
FIELD-SYMBOLS: <f2> STRUCTURE line1 DEFAULT line2 .
WRITE:/ <f2>-col1, <f2>-col2 .
输出结果﹕ 8 test

如果如下则错误(因为line2长度< line1 )
DATA: BEGIN OF line1 ,
          col1 TYPE i,
          col2(5) TYPE c,
       END OF line1.
DATA: BEGIN OF line2,
          col1 TYPE i,
          col2(4) TYPE c ,
       END OF line2 .
line2-col1 = 8 . line2-col2 = 'test' .
FIELD-SYMBOLS: <f2> STRUCTURE line1 DEFAULT line2 .
WRITE:/ <f2>-col1, <f2>-col2 .


(二) ASSIGN的用法﹕
1.静态分配
a.无偏移量
ASSIGN <f> TO <fs>

例如﹕
FIELD-SYMBOLS: <f1> .
FIELD-SYMBOLS: <f2> TYPE i .
DATA: txt(20) TYPE c VALUE 'Hello, How are you?'.
DATA: num TYPE i VALUE 5 .
ASSIGN txt TO <f1> .
ASSIGN num TO <f2> .
DESCRIBE FIELD <f1> LENGTH <f2>.
WRITE:/ <f1> , 'has length', <f2> .

输出结果﹕Hello, How are you? has length 20
如下代码将出错(原因<f2>没有指向任何内存地址)
FIELD-SYMBOLS: <f1> .
FIELD-SYMBOLS: <f2> TYPE i .
DATA: txt(20) TYPE c VALUE 'Hello, How are you?'.
DATA: num TYPE i VALUE 5 .
ASSIGN txt TO <f1> .
*ASSIGN num TO <f2> .
DESCRIBE FIELD <f1> LENGTH <f2>.
WRITE:/ <f1> , 'has length', <f2> .






b.有偏移量
ASSIGN <f>[+<o>][(<l>)] TO <fs>

说明﹕(1). <o>和<l>都可以是变量
       (2).系统不会判断所选择的部分是否在<f>内部,偏移量<o>和长度<l>都可以比
            <f>的长度大,写地址时﹐可以超出<f>的的限制﹐但不能超过定义的内存区
       (3).如果没有指定长度<l> ,系统默认为<f>的长度
       (4).如果<o>小于<f>的长度﹐可以通过为<l>指定一个‘*’来阻止<fs>参
照<f>限制之外的区域
例如﹕
FIELD-SYMBOLS: <f1> .
DATA: BEGIN OF line1,
          col1(10) VALUE'0123456789',
          col2(10) VALUE'abedefghij',
       END OF line1.
WRITE:/ line1-col1+5.
ASSIGN line1-col1+5 TO <f1> .
WRITE:/ <f1> .
ASSIGN line1-col1+5(*) TO <f1> .
WRITE:/ <f1> .

输出结果﹕56789
56789abede
56789

在内存地址分配时﹐和容易造成内存中的数据更改问题﹐例如﹕
FIELD-SYMBOLS: <f1>, <f2> .
DATA: BEGIN OF line ,
         a VALUE '1', b VALUE '2',
         c VALUE '3', d VALUE '4',
         e VALUE '5', f VALUE '6',
         g VALUE '7', h VALUE '8',
       END OF line .
DATA: off TYPE i .
DATA: len TYPE i VALUE 2 .
ASSIGN line TO <f2> .
WRITE:/ <f2> .
DO 2 TIMES .
   off = sy-index * 3 .
   ASSIGN line-a+off(1) TO <f1> .
   <f1> = 'XX'.
ENDDO .
ASSIGN line TO <f2> .
WRITE:/ <f2> .
输出结果为﹕12345678
123X56X8
可以看出在把<f1>的地址指向line时﹐<f1> = ‘XX’时就更改了<f>所指定的内存中的值



   2.动态分配(不是万不得以﹐不要使用这种方式,因其找<f>非常容易出错)
a. ASSIGN (<f>) TO <fs>
说明﹕ 1.如果分配是在子程序或功能模块中执行﹐程序将在局部的子程序或功能模块中搜索字
段<f>
              2.如果分配是在子程序或功能模块之外执行,或未找到字段<f>,程序在全局变量中搜索
                 字段<f>
              3.如在全局变量中都未找到字段<f>,则在工作程序Tables处声明的工作区中寻找
       注意﹕如果找到<f> ,则SY-SUBRC = 0 ,否则SY-SUBRC = 4

例如﹕
主程序Report1 .
REPORT1 .
TABLES : SBOOK .
SBOOK-FLDATE = ‘20031219’ .
PERFORM fomr1(Report2) .

子程序Report2 .
REPORT2 .
  FORM form1 .
     PERFORM form2(Report3) .
  ENDFORM .

字程序Report3 .
  REPORT3.
     FORM form2 .
          DATA: name(20) TYPE CVALUE ‘SBOOK-FLDATE’ .
          FIELD-SYMBOLS <f1>.
          ASSIGN (name) to<f1> .
          IF SY-SUBRC = 0 .
            WRITE:/ <f1> .
          ENDIF .
     ENDFORM .
  输出结果﹕19.12.2003

  说明﹕子程序Report3中引用了主程序的工作取区域的字段fldate,如果用静态Assign来无法实现﹐因为在子程序Report3无SBOOK-FLDATE ,语法检查会出现错误
  
b.表工作区的动态分配
   ASSIGN TABLE FIELD (<f>) TO <fs>
把主程序Tables处声明的工作区域指派给<fs>
例如﹕
TABLES : sbook .
DATA: name1(20) VALUE 'SBOOK-FLDATE' .
DATA: name2(20) VALUE 'name1' .
FIELD-SYMBOLS : <f1> .
ASSIGN TABLE FIELD (name1) TO <f1> .
WRITE:/ 'sy-subrc' , sy-subrc .
ASSIGN TABLE FIELD (name2) TO <f1> .
WRITE:/ 'sy-subrc' , sy-subrc .

输出结果﹕ sy-subrc 0
sy-subrc 4

3.将字段符号分配给其他字段符号
          ASSIGN<f1>[+<O>][(<l>)] TO <f2> .
       等同与下列动态分配
          ASSING TABLE FIELD(<f>) TO <f2> .
       其中<f>包含字段符号<f1>的名称
       说明﹕<f2>与<f1>可以是同一个字段符号
       例如﹕
DATA: BEGIN OF line1 ,
         a VALUE '1', b VALUE '2',
         c VALUE '3', d VALUE '4',
         e VALUE '5', f VALUE '6',
         g VALUE '7', h VALUE '8',
       END OF line1 .
DATA: off TYPE i .
FIELD-SYMBOLS : <f1> .
ASSIGN line1-a TO <f1> .
DO 4 TIMES .
   off = sy-index - 1 .
   ASSIGN <f1>+off(1) TO <f1> .
   WRITE: <f1> .
ENDDO .

输出结果﹕ 1 2 4 7
分析﹕
   首先<f1>指向line1-a地址
   循环中﹕
     off = 0时, <f1>à+0(1)  <f1> , <f1>指向line1-a地址值为﹕1
     off = 1时, <f1>à+1(1)  <f1> , <f1>指向line1-b地址值为﹕2
     off = 2时, <f1>à+2(1)  <f1> , <f1>指向line1-d地址值为﹕4
     off = 3时, <f1>à+2(1)  <f1> , <f1>指向line1-g地址值为﹕7

   4.分配字段串组件
     
      ASSIGN COMPONENT <comp> OF STRUCTURE<s> TO <fs> .
系统将字符串<s>的组件<comp>赋给字段符号<fs> ,可以指定<comp>为文字或变量
例如﹕
DATA: BEGIN OF line1,
         col1 TYPE i VALUE '11',
         col2 TYPE i VALUE '22',
         col3 TYPE i VALUE '33',
       END OF line1.
DATA: comp(10) TYPE c VALUE 'col3' .
FIELD-SYMBOLS : <f1>, <f2>, <f3> .
ASSIGN line1 TO <f1> .
ASSIGN comp TO <f2> .
DO 3 TIMES .
   ASSIGN COMPONENT sy-index OF STRUCTURE <f1> TO <f3> .
   WRITE: <f3> .
ENDDO .
ASSIGN COMPONENT <f2> OF STRUCTURE <f1> TO <f3> .
WRITE: / <f3> .

输出结果﹕ 11 22 33
                 33

(三) .定义字段符号的格式
1.定义字段符号的类型
        ASSIGN …. TO <fs> TYPE<t> .
    说明﹕a.如果<fs>没有定义类型﹐则<fs>不继承赋给它的变量的类型与长度﹐而类型为<t>
           b.如果<fs>定义了类型﹐则系统将赋给它的变量的类型转换成<t>在给<fs>,此时
注意类型转化的可兼容性
         例如﹕
DATA: text(8) TYPE c VALUE '20031221' .
DATA: t_type .
DATA: t_len TYPE i .
FIELD-SYMBOLS : <f1> .

ASSIGN text TO <f1> .
WRITE:/ <f1> .
DESCRIBE FIELD <f1> TYPE t_type
               LENGTH t_len .
WRITE: t_type , t_len .

ASSIGN text TO <f1> TYPE 'D' .
WRITE:/ <f1> .
DESCRIBE FIELD <f1> TYPE t_type
               LENGTH t_len .
WRITE: t_type , t_len .

输出结果﹕20031221 C 8
21122003 D 8

2.更改字段符号的小数位
     ASSIGN …. TO <fs> DECIMALS <d> .
  说明﹕<fs>的小数位为<d>位﹐这会导致字段符号的值与指派的变量的值不同。
         <d>可以是变量或常量﹐如果<d>不在0和14之间﹐或者指派的变量的类型不是P
型﹐将导致程序运行错误
   例如﹕
DATA: pack1 TYPE p DECIMALS 2 VALUE '400' .
DATA: pack2 TYPE p DECIMALS 2 .
DATA: pack3 TYPE p DECIMALS 2 .
FIELD-SYMBOLS: <f1> , <f2> .
WRITE:/1(8) 'Pack1', pack1 .
ASSIGN pack1 TO <f1> DECIMALS 1 .
WRITE:/1(8) '<f1>', <f1> .
pack2 = <f1> .
WRITE:/1(8) 'Pack2', pack2 .
ASSIGN pack2 TO <f2> DECIMALS 4 .
WRITE:/1(8) '<f2>', <f2> .
pack3 = <f1> + <f2> .
WRITE:/1(8) 'Pack3', pack3 .
<f2> = '1234.56779' .
WRITE:/1(8) '<f2>', <f2> .
WRITE:/1(8) 'Pack2', pack2 .

输出结果﹕
Pack1 400.00
<f1> 4,000.0
Pack2 4,000.00
<f2> 40.0000
Pack3 4,040.00
<f2> 1,234.5678
Pack2 123,456.78

(四) .运行检查﹐防止取指派变量定义取之外的数据
注意点﹕1.对于内表﹐存储区的大小由记录的行数的多少﹐这种表行数不固定﹐运行时存储区动态分配,
           容易造成取存储区之外的数据﹐应该注意
         2.对于DATA定义的变量﹐存储区固定﹐注意不要取存储区之外的数据
   例如﹕
DATA: BEGIN OF line1 ,
         col1(4) TYPE c VALUE '1234',
         col2(2) TYPE c VALUE '56',
       END OF line1 .
DATA: text1(1) TYPE c VALUE 'a' .
DATA: text2(2) TYPE c VALUE 'bc' .
DATA: text3(3) TYPE c VALUE 'def'.
FIELD-SYMBOLS : <f1> .
DO 6 TIMES .
   ASSIGN text1+sy-index(1) TO <f1> .
   WRITE: <f1> .
ENDDO.
程序运行错误,因为在循环中超出存储区域的范围

你可能感兴趣的:(FIELD-SYMBOLS)