Day 14

The write Statement


Chapter Objectives

After you complete this chapter, you will be able to:

Default Lengths and Formatting

If you do not specify any length or formatting options when you use the write statement, the system uses a default format and length based on the data type of each variable written. The following sections describe these defaults.

Default Lengths

The output length of a field is the number of characters used to display the value of that field. Output length is used by the write statement to allocate space on the output list for a field. Fields defined within a program via the data statement have a default output length as shown in Table 14.1.

Table 14.1  ABAP/4 Data Type Determines the Default Output Format and Length
Data
Justification
Format
Sign
Dflt Output
Type Length
i
RightZeros suppressed Trailing11
p
RightZeros suppressed Trailing2*fldlen or (2*fldlen)+1
f
NoneScientific notation Leading22
n
RightLeading zeros shown Nonefldlen
c
LeftLeading blanks suppressed  fldlen
d
LeftDetermined by user defaults  8
t
LeftHH:MM:SS  6
x
Left   2*fldlen

Fields from the Data Dictionary have DDIC data types such as DEC, CHAR, CURR, and so on. These are all based on ABAP/4 data types and they inherit default length and format from the ABAP/4 data type. To determine the ABAP/4 data type, and thus the default output format, look up the ABAP/4 keyword documentation for the tables statement. To do this, place your cursor on a tables statement within your code and press the F1 key.

In addition, DDIC fields have their output length and number of decimals defined in the domain. These fields override the default, and are shown in Figure 14.1.

Figure 14.1 : The Output Length and Decimal Places fields override the defaults inherited from the ABAP/4 data types.

The output length and decimal places are inherited by all fields that are created from a domain. For example, in Figure 14.1, the field length is 15, indicating that 15 digits can be stored in any field that uses this domain. The output length is 20, so the output enables enough room for a decimal point, a sign, and three thousands separators.

Packed Fields

The default output length of a type p field is twice the defined field length. If decimal places are defined, the default output length is increased by 1 so that it is 2 * field length + 1. Table 14.2 shows sample default output lengths for type p fields.

Table 14.2  Default Output Length for Packed Decimal Fields
Data Definition
Default Output Length
data f1(4) type p.
8
data f2(4) type p decimals 2.
9
data f3(5) type p.
10
data f4(5) type p decimals 3.
11

Default Formatting

The default format is derived from the data type of the variable. Table 14.1 described how the output will be formatted for each ABAP/4 data type. The output of numeric fields (types p, i, and f) is right-justified with leading zeros suppressed and the rest are left-justified. Additional type-specific formatting also applies.

Default Date Formatting

Date values are output according to the Date Format setting in the User Defaults as long as the output length is 10 or greater. The default output length is 8, so you must increase it to at least 10 before the separators can be seen. Defining a variable using like (for example, like sy-datum) causes the output length to be taken from the domain.

Default Time Formatting

Time values are output in HH:MM:SS format as long as the output length is 8 or greater. The default output length is 6, so you must increase it to at least 8 before the separators can be seen. Defining a variable using like (for example, like sy-uzeit) causes the output length to be taken from the domain.

Default Numeric Formatting

The population of North America writes a number as 1,234.56. In other countries, such as those in Europe, the same number is written as 1.234,56-the use of the comma and decimal are interchanged. R/3 enables each individual user to specify one of these formats via the user profile setting Decimal Notation (from any screen, choose the menu path System->User Profile->User Defaults).

Caution
You must sign off and sign back on again to the R/3 system before changes to user defaults take effect.

Table 14.3 shows the effect of the Decimal Notation setting on numeric output.

Table 14.3  Decimal Notation Setting in the User Defaults Affects Numeric Output Formats
Setting
Sample Output
Comma1,234.56
Period1.234,56

The default output format for floating-point (type f) variables is via scientific notation. This can be modified by using an edit mask or conversion exit.

Overflow Formatting

When dealing with numbers that are too big for the output field, the system puts an asterisk in the first column of output to indicate overflow. However, before that occurs, the system tries to output all the digits, if possible. Thousands separators are only output if there is enough room in the output field. If there isn't, they are dropped one at a time beginning from the left of the field and working to the right. If the number is positive and will fit in the output by using the sign field, the system will use it.

Sample Program Demonstrating Default Formatting

Listing 14.1 illustrates default length and formatting. It also illustrates handling of numbers that are close to overflowing the output field.


Listing 14.1  Default Formatting and Lengths

1  report ztx1401.
2  data: t1    type t            value '123456',
3        t2    like sy-uzeit     value '123456',
4        d1    type d            value '19980201',
5        d2    like sy-datum     value '19980201',
6        f1    type f            value '-1234',
7        i1    type i            value '12345678-',
8        i2    type i            value '123456789-',
9        i3    type i            value '1123456789-',
10       i4    type i            value '1123456789',
11       n1(5) type n            value 123,
12       p1(5) type p            value '123456789-',
13       c1(5) type c            value 'ABC',
14       x1(2) type x value 'A0B0'.
15
16 write: /     t1,  26 'type t: default output length = 6',
17        /(8)  t1,  26 'type t: increased output length to 8',
18        /(12) t1,  26 'type t: increased output length to 12',
19        /     t2,  26 'type t: default output length = 8 (from domain)',
20        /     d1,  26 'type d: default output length = 8',
21        /(10) d1,  26 'type d: increased output length to 10',
22        /     d2,  26 'type d: default output length = 10 (from domain)',
23        /     f1,  26 'type f: default output length = 22',
24        /     i1,  26 'type i: default output length = 11',
25        /     i2,  26 'type i: same output length, more digits',
26        /     i3,  26 'type i: same output length, even more digits',
27        /(10) i3,  26 'type i: smaller output length, negative number',
28        /(10) i4,  26 'type i: smaller output length, positive number',
29        /     n1,  26 'type n: default output length = field length',
30        /     p1,  26 'type p: default output length = 2 * length = 10',
31        /(12) p1,  26 'type p: output length increased to 12',
32        /(15) p1,  26 'type p: output length increased to 15',
33        /     c1,  26 'type c: output length = field length (left just)',
34        /     x1,  26 'type x: default output length = 2 * length = 4'.

The code in Listing 14.1 produces this output:

123456                   type t: default output length = 6
12:34:56                 type t: increased output length to 8
12:34:56                 type t: increased output length to 12
12:34:56                 type t: default output length = 8 (from domain)
19980201                 type d: default output length = 8
1998/02/01               type d: increased output length to 10
1998/02/01               type d: default output length = 10 (from domain)
-1.234000000000000E+03   type f: default output length = 22
12,345,678-              type i: default output length = 11
123456,789-              type i: same output length, more digits
1123456789-              type i: same output length, even more digits
*23456789-               type i: smaller output length, negative number
1123456789               type i: smaller output length, positive number
00123                    type n: default output length = field length
123456789-               type p: default output length = 2 * length = 10
123,456,789-             type p: output length increased to 12
   123,456,789-          type p: output length increased to 15
ABC                      type c: output length = field length (left just)
A0B0                     type x: default output length = 2 * length = 4

Additions to the write Statement

This section details some of the specific output specifications that can be used with the write statement.

Syntax for the write Statement

The following is the syntax for the write statement.

write [at] [/p(l)] v1[+o(sl)]
       (1)  under v2 | no-gap
       (2)  using edit mask m | using no edit mask
       (3)  mm/dd/yy   | dd/mm/yy  
       (4)  mm/dd/yyyy | dd/mm/yyyy
       (5)  mmddyy     | ddmmyy     | yymmdd
       (6)  no-zero
       (7)  no-sign
       (8)  decimals n
       (9)  round n
       (10) currency c | unit u
       (11) left-justified | centered | right-justified

where:

The following points apply:

If no additions are specified and two write statements are executed (such as write: v1, v2.), the value of v2 appears on the same line as that of v1 separated from it by one space. If the value of v2 will not fit on the remainder of the current line, it appears on the next line. If the output length of v2 is greater than the line length, the output is truncated on the right. If the value is output right-justified (as with type p variables) before truncating it on the right, it will be shifted left as long as there are leading blanks to avoid truncating it. Separators are also removed, if necessary, to avoid truncation.

NOTE
A new line of output always begins at the start of a new event. Events are covered in Chapter 17, "Modularization: Events and Subroutines."

Understanding the Position Specification

Referring to the syntax given above, p specifies the output column. The output value can overwrite all or part of a preceding write. The program in Listing 14.2 illustrates the effect of a series of write statements. Table 14.4 shows the cumulative effect of each write, in sequence, to show how the output is arrived at.


Listing 14.2  A Series of write Statements to Illustrate the Effect of the Output Column Specification

1  report ztx1402.
2  data f1(4) type p value 1234.
3  write: / '----+----1----+--',
4         / '12345678901234567'.
5  skip.
6  write /1 'X'.
7  write    'YZ'.
8  write  2 'YZ'.
9  write  3 'ABC'.
10 write  4 f1.
11 write  7 f1.
12 write  'Z'.

The code in Listing 14.2 produces this output:

----+----1----+--
12345678901234567
               
XYA  1  1,234  Z

Table 14.4  write Statement Examples and Corresponding Output
Statements
Cumulative Output
----+----1----+--
12345678901234567
write 1 'X'.X
write 'YZ'.X YZ
write 2 'YZ'.XYZZ
write 3 'ABC'.XYABC
write 4 f1.XYA 1,234
write 7 f1.XYA 1 1,234
write 'Z'.XYA 1 1,234 Z

Understanding the Length Specification

In the syntax description for the write statement, o specifies the output length. This is the number of characters on the output line used to hold the output value.

Position and length specifications are always optional. They can be specified using either a literal or a variable. If either one is a variable, it must be preceded by the word at. at is optional if the position and length are both literals, but it is required if either is a variable.

If a slash (/) precedes a position or length specification, there cannot be an intervening space between them. Listing 14.3 provides examples.


Listing 14.3  Illustrating the Use of the Position and Length Specifications

1  report ztx1403.
2  data: f1(4) type p value 1234,
3        p     type i value 5,
4        l     type i value 8.
5 
6  write: / '----+----1----+--',
7         / '12345678901234567'.
8  skip.
9  write /(2) 'XYZ'.
10 write /(4) 'XYZ'.
11 write      'ABC'.
12 write /5(4) f1.
13 write at /p(l) f1.

The code in Listing 14.3 produces this output:

----+----1----+--
12345678901234567
                 
XY               
XYZ  ABC         
    1234         
      1,234                 

Working with Subfields

You can specify a subfield in the write statement by using offset and length specifications immediately after the value without an intervening space. (If necessary, refer to the previous section on additions to the write statement.) You cannot use a subfield with a literal or a numeric field (types p, i, and f). Listing 14.4 provides examples.


Listing 14.4  Using Subfields

1  report ztx1404.
2  data f1(4) type c value 'ABCD'.
3 
4  write: / '----+----1----+--',
5         / '12345678901234567'.
6  skip.
7  write  / f1(2).
8  write  / f1+1(2).
9  write: /(2) f1+2(1), f1.

The code in Listing 14.4 produces this output:

----+----1----+--
12345678901234567 
                  
AB                
BC                
C  ABCD           

Using the under Addition

Using under causes the first character of the field to be positioned in the same column as the first character of a previously written field. You cannot use under with an explicit position specification. Listing 14.5 shows examples.


Listing 14.5  Using the under Addition

1  report ztx1405.
2  tables: ztxlfa1.
3 
4  select * up to 5 rows from ztxlfa1 order by lifnr.
5      write: /1  ztxlfa1-lifnr,
6              15 ztxlfa1-land1,
7              25 ztxlfa1-name1,
8             /   ztxlfa1-spras under ztxlfa1-land1,
9                 ztxlfa1-stras under ztxlfa1-name1.
10     skip.
11     endselect.

The code in Listing 14.5 produces this output:

1000          CA        Parts Unlimited        
              E         111 Queen St.          
                                               
1010          CA        Industrial Pumps Inc.  
              E         1520 Avenue Rd.        
                                               
1020          CA        Chemical Nation Ltd.   
              E         123 River Ave.         
                                               
1030          CA        ChickenFeed Ltd.       
              E         8718 Wishbone Lane     
                                               
1040          US        Motherboards Inc.      
              E         64 BitBus Blvd.        

Using the no-gap Addition

Using no-gap suppresses the intervening gap automatically placed after a field if the following field has no column specification. Listing 14.6 illustrates the use of no-gap.


Listing 14.6  Using no-gap

1  report ztx1406.
2  data f1(4) value 'ABCD'.
3 
4  write: / f1, f1,
5         / f1 no-gap, f1,
6         / '''', f1, '''',
7         / '''', 2 f1, 6 '''',
8         / '''' no-gap, f1 no-gap, ''''.

The code in Listing 14.6 produces this output:

ABCD ABCD
ABCDABCD 
' ABCD ' 
'ABCD'   
'ABCD'   

Using Edit Masks

Edit masks enable you to:

Anywhere within an edit mask, the underscore character (_) has special meaning. At the beginning of an edit mask, V, LL, RR, and == have special meaning. All other characters are transferred without change to the output.

Underscores within an edit mask are replaced one-by-one with the characters from the source field (the field you are writing out). The number of characters taken from the source field will be equal to the number of underscores in the edit mask. For example, if there are three characters in the edit mask, at most three characters from the source field will be output. All other characters in the edit mask are inserted into the output. You also usually need to increase the length of the output field to accommodate the extra characters inserted by the mask.

For example, the statement write (6) 'ABCD' using edit mask '_:__:_' writes A:BC:D. Characters are taken from the source field one at a time, and characters from the edit mask are inserted at the points indicated by the mask. The statement write 'ABCD' using edit mask '_:__:_' only writes A:BC because the default output length is equal to the length of the source field (4).

If there are fewer underscores in the mask than there are in the source field, the default is to take the left-most n characters from the source field, where n equals the number of underscores in the edit mask. This can also be explicitly specified by preceding the edit mask with LL. For example, write 'ABCD' using edit mask 'LL__:_' takes the left-most three characters and writes out AB:C. Using RR instead takes the right-most three characters, so write 'ABCD' using edit mask 'RR__:_' will write out BC:D.

If there are more underscores than there are source field characters, the effect of LL is to left-justify the value in the output; RR right-justifies the value (see Listing 14.7 for an example).

An edit mask beginning with a V, when applied to a numeric field (types i, p, and f), causes the sign field to be displayed at the beginning. If applied to a character field, a V is actually output.


Listing 14.7  The Effect of Various Edit Masks

1  report ztx1407.
2  data: f1(4) value 'ABCD',
3        f2    type i value '1234-'.
4 
5  write: / ' 5. ', f1,
6         / ' 6. ', (6) f1 using edit mask '_:__:_',
7         / ' 7. ', f1 using edit mask 'LL_:__',
8         / ' 8. ', f1 using edit mask 'RR_:__',
9         / ' 9. ', f2 using edit mask 'LLV______',
10        / '10. ', f2 using edit mask 'RRV______',
11        / '11. ', f2 using edit mask 'RRV___,___',
12        / '12. ', f2 using edit mask 'LLV___,___',
13        / '13. ', f1 using edit mask 'V___'.

The code in Listing 14.7 produces this output:

 5.  ABCD      
 6.  A:BC:D    
 7.  A:BC      
 8.  B:CD      
 9.  -1234     
10.  -  1234   
11.  -  1,234  
12.  -123,4    
13.  VABC      

Using Conversion Exits

A conversion exit is a called routine that formats the output. An edit mask that begins with == followed by a four-character ID calls a function module that formats the output. That four-character ID is known as a conversion exit, or conversion routine. (Function modules are covered in a subsequent chapter, but, for now, think of a function module as a subroutine within another program.) The name of the function module will be CONVERSION_EXIT_XXXX_OUTPUT, where XXXX is the four-character id that follows ==. For example, write '00001000' using edit mask '==ALPHA' calls the function module CONVERSION_EXIT_ALPHA_OUTPUT. The write statement passes the value first to the function module, which changes it in any desired way and then returns the changed value, and that value is written out. This particular exit (ALPHA) examines the value to determine whether it consists entirely of numbers. If it does, leading zeros are stripped and the number is left-justified. Values containing non-numerics are not changed by ALPHA. SAP supplies about 60 conversion exits for various formatting tasks. After Chapter 19, "Modularization: Function Modules, Part 1," on function modules, you will know enough to be able to create your own conversion exits.

Conversion exits are particularly useful for complex formatting tasks that are needed in more than one program. To illustrate, the conversion exit CUNIT automatically converts the code representing a unit of measure into a description meaningful in the current logon language. For example, within R/3, the code for a crate of materials is KI. (KI is an abbreviation of kiste, the German word for "box.") However, CUNIT converts KI to the English mnemonic CR. Therefore, when logged on in English, write: '1', 'KI' using edit mask '==CUNIT'. writes 1 CR. For a user signed on in German, the output would be 1 KI. Using such a conversion exit enables a standard set of codes stored in the database to be automatically converted to be meaningful to the current logon language whenever output to a report.

Conversion Routines within a Domain

A conversion exit can also be placed into the Convers. Routine field in a domain. The exit is inherited by all fields that use that domain, and will be automatically applied when the value is written out. Figure 14.2 shows that domain ztxlifnr uses the conversion routine ALPHA.

Figure 14.2 : Notice the contents of the Convers. Routine field.

Therefore, whenever ztxlfa1-lifnr is written, the value first passes through the function module CONVERSION_EXIT_ALPHA_OUTPUT, which strips leading zeros from numeric values.

A conversion exit within a domain can be turned off by specifying using no edit mask on the write statement.

Listing 14.8 illustrates the use of conversion exits.


Listing 14.8  Using Conversion Exits

1  report ztx1408.
2  tables: ztxlfa1, ztxmara.
3  data: f1(10) value '0000001000'.
4 
5  write: / f1,
6         / f1 using edit mask '==ALPHA'.
7 
8  skip.
9  select * from ztxlfa1 where lifnr = '00000010000'
10                          or lifnr = 'V1'
11                       order by lifnr.
12     write: / ztxlfa1-lifnr,      "domain contains convers. exit ALPHA
13            / ztxlfa1-lifnr using no edit mask.
14     endselect.
15
16 skip.
17 select single * from ztxmara where matnr = 'M103'.
18 write: /      ztxmara-matnr,
19          (10) ztxmara-brgew,
20               ztxmara-gewei.      "domain contains convers. exit CUNIT
21 set locale language 'D'.
22 write: /      ztxmara-matnr,
23          (10) ztxmara-brgew,
24               ztxmara-gewei.      "domain contains convers. exit CUNIT

The code in Listing 14.8 produces this output:

0000001000                      
1000                            
                                
1000                            
0000001000                      
V1                              
V1                              
                                
M103                  50.000  CR
M103                  50.000  KI

Displaying Existing Conversion Exits

To display the existing conversion exits, use the following procedure.

Start the ScreenCam "How to Display Existing Conversion Exits" now.

  1. From the Development Workbench screen, choose the menu path Overview->Repository Infosys. The ABAP/4 Repository Information System screen is displayed.
  2. Click on the plus (+) beside Programming. The tree expands.
  3. Click on the plus (+) beside Function Library. The tree expands.
  4. Double-click on the line Function Modules. The ABAP/4 Repository Information System: Function Module screen is displayed.
  5. In the Function Module field, enter CONVERSION_EXIT_*_OUTPUT (the field is scrollable; you can enter more characters into it than it can display).
  6. Press the Execute button on the Application toolbar. The Function Modules screen is displayed. All of the conversion exits that can be used on the write statement will be listed here.

Working with Date Formatting

Date formatting specifications, for the most part, do not do what you think they will. Most pull their format from the Date Format specification in the user defaults (menu path System->User Profile->User Defaults).

Table 14.5 contains a description of the effect of each.

Table 14.5  Effects of the Date Format Specifications
Format
Effect
mm/dd/yyyy dd/mm/yyyyWrites out the date using the format specified in the user's profile. This is the default, so these formats do not actually do anything.
mm/dd/yy
dd/mm/yy
Writes out the date with a two-character year using the format specified in the user's profile. They both do the same thing.
Mmddyy
ddmmyy
Writes out the date using a two-character year using the format specified in the user's profile, without separators. They both do the same thing.
YymmddWrites out the date in yymmdd format without separators.

TIP
Conversion exits IDATE and SDATE provide alternate date formats. Also, the function module RH_GET_DATE_DAYNAME returns the name of the day of the week for a given date and language. As an alternative, DATE_COMPUTE_DAY returns a number representing the day of the week.

Listing 14.9 illustrates the use of the date format specifications.


Listing 14.9  Using Date Format Specifications

1  report ztx1409.
2  data: f1 like sy-datum value '19981123',
3        begin of f2,
4            y(4),
5            m(2),
6            d(2),
7            end of f2,
8        begin of f3,
9            d(2),
10           m(2),
11           y(4),
12           end of f3,
13       begin of f4,
14           m(2),
15           d(2),
16           y(4),
17           end of f4.
18
19 write: / f1,            "user profile sets format
20        / f1 mm/dd/yyyy, "user profile sets format
21        / f1 dd/mm/yyyy, "user profile sets format
22        / f1 mm/dd/yy,   "user profile fmt, display with 2-digit year
23        / f1 dd/mm/yy,   "user profile fmt, display with 2-digit year
24        / f1 mmddyy,     "user profile fmt, 2-digit year, no separators
25        / f1 ddmmyy,     "user profile fmt, 2-digit year, no separators
26        / f1 yymmdd,     "yymmdd format, no separators
27        / f1 using edit mask '==IDATE',
28        /(11) f1 using edit mask '==SDATE'.
29
30 f2 = f1.
31 move-corresponding f2 to: f3, f4.
32 write: /(10) f3 using edit mask '__/__/____', "dd/mm/yyyy format
33        /(10) f4 using edit mask '__/__/____'. "mm/dd/yyyy format

The code in Listing 14.9 produces this output:

1998/11/23   
1998/11/23   
1998/11/23   
98/11/23     
98/11/23
981123       
981123       
981123       
1998NOV23    
1998/NOV/23  
23/11/1998   
11/23/1998   

Using the no-zero and no-sign Additions

The no-zero addition suppresses leading zeros when used with type c or type n variables. In the case of a zero value, the output is all blanks.

The no-sign addition, when used with variables of type i, p, or f, suppresses the output of the sign character. In other words, negative numbers will not have a sign and will appear as if they were positive.

Listing 14.10 illustrates the use of these two additions.


Listing 14.10  Using no-zero and no-sign

1  report ztx1410.
2  data: c1(10) type c value '000123',
3        n1(10) type n value 123,
4        n2(10) type n value 0,
5        i1     type i value '123-',
6        i2     type i value 123.

7  write: / c1,         20 'type c',
8         / c1 no-zero, 20 'type c using no-zero',
9         / n1,         20 'type n',
10        / n1 no-zero, 20 'type n using no-zero',
11        / n2,         20 'type n: zero value',
12        / n2 no-zero, 20 'type n: zero value using no-zero',
13        / i1,         20 'type i',
14        / i2 no-sign, 20 'type i using no-sign'.

The code in Listing 14.10 produces this output:

000123             type c                          
   123             type c using no-zero            
0000000123         type n                          
       123         type n using no-zero            
0000000000         type n: zero value              
                   type n: zero value using no-zero
       123-        type i                          
        123        type i using no-sign            

Specifying Decimals and Rounding

Two statements perform rounding:

Three statements are used to specify the number of decimal places in the output:

Using the decimals and round Additions

The decimals n addition can be used to increase or decrease the number of decimal places displayed in the output list. If you decrease the number of decimal places, the value is rounded before being written to the list. The source variable value is not changed, only the output appears differently. If you increase the number of decimals, zeros are appended to the end of the value. Negative values of n move the decimal to the right, effectively multiplying the number by factors of 10 and then rounding before display.

The round n addition causes the output to be scaled by factors of 10 and then rounded before display. This has the same effect as multiplying by 10**n. Positive n values move the decimal to the left, and negative values move it to the right. This is useful, for example, when you want to output values to the nearest thousand.

The difference between decimals and round is that decimals changes the number of digits seen after the decimal point to n and then performs rounding. round moves the decimal point left or right by n, maintaining the number of digits after the decimal, and then performs rounding to the number of decimal digits displayed.

Listing 14.11 illustrates the use of decimals and round.


Listing 14.11  Using the decimals and round Additions

1  report ztx1411.
2  data f1 type p decimals 3 value '1575.456'.
3  write: / f1,                    20 'as-is',
4         / f1 decimals 4,         20 'decimals 4',
5         / f1 decimals 3,         20 'decimals 3',
6         / f1 decimals 2,         20 'decimals 2',
7         / f1 decimals 1,         20 'decimals 1',
8         / f1 decimals 0,         20 'decimals 0',
9         / f1 decimals -1,        20 'decimals -1',
10        / f1 round 4,            20 'round 4',
11        / f1 round 3,            20 'round 3',
12        / f1 round 2,            20 'round 2',
13        / f1 round 1,            20 'round 1',
14        / f1 round 0,            20 'round 0',
15        / f1 round -1,           20 'round -1',
16        / f1 round -2,           20 'round -2',
17        / f1 round 3 decimals 1, 20 'round 3 decimals 1',
18        / f1 round 3 decimals 3, 20 'round 3 decimals 3'.

The code in Listing 14.11 produces this output:

1,575.456   as-is             
      1,575.4560   decimals 4        
       1,575.456   decimals 3        
        1,575.46   decimals 2        
         1,575.5   decimals 1        
           1,575   decimals 0        
             158   decimals -1       
           0.158   round 4           
           1.575   round 3           
          15.755   round 2           
         157.546   round 1           
       1,575.456   round 0           
      15,754.560   round -1          
     157,545.600   round -2          
             1.6   round 3 decimals 1
           1.575   round 3 decimals 3

On line 8, the decimals 0 addition does not round up because the fractional part of the number is less than .5.

Using the currency and unit Additions

The additions currency and unit are an alternate way of indicating the position of the decimal point for a type p field. They cannot be used with the decimals addition.

NOTE
The DDIC types CURR and QUAN are based on the ABAP/4 data type p (packed decimal).
Using the currency Addition
When you write out a currency amount, you should also use the currency addition. Such amounts are usually retrieved from a type CURR field in a database table.
Use currency instead of decimals to specify the number of decimal places for currency amount fields. Unlike decimals, on which you specify the number of decimal places, you instead specify a currency code, such as USD (U.S. Dollars), ITL (Italian Lira), or JPY (Japanese Yen). The system then looks up that currency code in table TCURX to determine the number of decimal places that should be used to display the value. If the currency code is not found in TCURX, a default of two decimal places is used.
The currency code is usually also stored either in the same database table or another, related one. For example, the currency key for type CURR fields (saldv, solll, and habnl) in table ztxlfc3 is stored in the field ztxt001-waers. You can find this out by double-clicking on any of these fields. For example, if you double-click on ztxlfc3-saldv, you will see the Display Field ZTXLFC3-SALDV screen shown in Figure 14.3.
Figure 14.3 : A double-click on field saldv in table ztxlfc3 displays this screen.
The reference table and reference field indicate that ztxt001-waers contains the currency key.
The table ztxt001 itself contains the attributes of all company codes; its primary key is bukrs. If you take the value from ztxlfc3-bukrs and look up the single row in ztxt001 that matches, waers will contain the currency key. Listing 14.12 illustrates.


Listing 14.12  Using the currency Addition

1  report ztx1412.
2  tables: ztxlfc3.

3  data: f1 type p decimals 1 value '12345.6'.
4
5  write: / f1,
6         / f1 currency 'USD', 'USD',      "US Dollars
7         / f1 currency 'ITL', 'ITL'.      "Italian Lira
8 
9  skip.
10 select * from ztxlfc3 where gjahr = '1997'
11                       and saldv >= 100
12                       order by bukrs.
13     on change of ztxlfc3-bukrs.
14         select single * from ztxt001 where bukrs = ztxlfc3-bukrs.
15         endon.
16     write: / ztxlfc3-saldv currency ztxt001-waers, ztxt001-waers.
17     endselect.

The code in Listing 14.12 produces this output:

        123,456
       1,234.56  USD
        123,456  ITL

            100.00  USD
            100.00  USD 
            100.00  USD 
            100.00  USD 
           100,000  ITL 
            25,050  ITL 
           100,000  ITL 
           100,000  JPY 
           300,000  JPY 
            250.50  CAD 
            200.00  CAD 
          1,000.00  CAD 
            100.00  CAD 

Using the unit Addition
The unit addition is used to specify the number of decimals displayed for a quantity field. Units, such as cm (centimeters) or lb (pounds), determine the number of decimal places displayed. The code, such as '%' (percent) or 'KM' (kilometers) is specified after unit is looked up automatically in table t006. The fields decan and andec then determine how many decimal places are displayed. They both contain a numeric value.
decan specifies the number of zero-valued decimal values to truncate. It removes trailing zeros; it will never truncate nonzero decimal places. It also never increases the number of decimal places displayed. For example, if the value is 12.30 and decan is 1, the output will be 12.3. If the value is 12.34 and decan is 1, the output will be 12.34.
andec appends zeros after decan has been applied. The number of decimal digits displayed must be a multiple of andec. If necessary, andec will pad the value on the right with zeros. If andec is zero, no zeros are appended. For example, if the value is 12.34 after decan has been applied, and the value of andec is 3, there must be 0, 3, 6, or 9 (or any other multiple of 3) decimal digits. The output value will therefore be padded with zeros to become 12.340. If the value after decan is 12.3456, the output will be 12.345600. If the value after decan is 12.30 and andec is 2, the output will be 12.30.
Table 14.6 contains more examples of the effects of decan and andec on the output format.

Table 14.6  How the decan and andec Fields from Table t006 Affect the Output Formatting of a Field
Input
decan
andec
Result
30.1
1
0
30.1
30.1
1
2
30.10
30.1
1
3
30.100
30.1234
1
3
30.123400
30
1
3
30
30
2
0
30
30.1
2
0
30.1
30.11
2
0
30.11
30.11
2
2
30.11
30.11
2
4
30.1100

The unit addition is typically used with fields of type QUAN that are stored in the database. Each field must have a reference field of type UNIT. The unit of measurement for the value in the QUAN field is stored there. Figure 14.4 shows that the reference field for ztxmara-brgew is ztxmara-gewei.

Figure 14.4 : If you double-click on the ztxmara-brgew field, you will see a screen indicating the reference table and field.

Listing 14.13 illustrates the use of this addition.


Listing 14.13  Using the unit Addition

1  report ztx1413.
2  tables: ztxmara, t006.
3  data: f1 type p decimals 4 value '99.0000',
4        f2 type p decimals 4 value '99.1234',
5        f3 type p decimals 4 value '99.1200',
6        f4 type p decimals 1 value '99.1'.
7 
8  write: / f1,           'as-is',
9         / f1 unit 'ML', 'ml - milliliters decan 3 andec 3',
10        / f1 unit '%',  '%  - percent     decan 2 andec 0',
11        / f1 unit '"',  '"  - inches      decan 0 andec 3',
12        /,
13        / f2,           'as-is',
14        / f2 unit '%',  '%',
15        / f3,           'as-is',
16        / f3 unit '%',  '%',
17        / f4,           'as-is',
18        / f4 unit '%',  '%'.
19
20 skip.
21 write: /12 'brgew as-is',
22        31 'with units',
23        48 'ntgew as-is',
24        67 'with units',
25        79 'units',
26        85 'decan',
27        91 'andec'.
28 uline.
29 select * from ztxmara.
30     select single * from t006 where msehi = ztxmara-gewei.
31     write: /(5) ztxmara-matnr,
32              ztxmara-brgew,
33              ztxmara-brgew unit ztxmara-gewei,
34              ztxmara-ntgew,
35              ztxmara-ntgew unit ztxmara-gewei,
36              ztxmara-gewei,
37           85 t006-decan,
38           91 t006-andec.
39     endselect.

The code in Listing 14.13 produces this output:

         99.0000  as-is                                                
          99.000  ml - milliliters decan 3 andec 3                     
           99.00  %  - percent     decan 2 andec 0                     
              99  "  - inches      decan 0 andec 3                     
                                                                       
         99.1234  as-is                                                
         99.1234  %                                                    
         99.1200  as-is                                                
           99.12  %                                                    
            99.1  as-is                                                
            99.1  %                                                    
                                                                       
       brgew as-is    w/units   ntgew as-is  w/units  units decan andec
---------------------------------------------------------------------
M100       102.560    102.560       100.000      100  M3     0     3   
M101        10.100     10.100        10.000       10  PAL    0     0   
M102         1.000          1         0.000        0  ROL    0     0   
M103        50.000         50         0.000        0  CR     0     0   

Shifting Justification

Using left-justified, centered, and right-justified, you can shift the output value within the space allotted for the output field. Listing 14.14 illustrates.


Listing 14.14  Using the Justification Additions to the write Statement

1  report ztx1414.
2  data: f1(6) value 'AB'.
3  write: /     '....+....1',
4         /     '1234567890',
5         /     f1,
6         /     f1 left-justified,
7         /     f1 centered,
8         /     f1 right-justified,
9         /     '....+....1....+....2....+....3....+....4',
10        /     '1234567890123456789012345678901234567890',
11        /(40) f1 left-justified,
12        /(40) f1 centered,
13        /(40) f1 right-justified.

The code in Listing 14.14 produces this output:

....+....1                               
1234567890                               
AB                                       
AB                                       
  AB                                     
    AB                                   
....+....1....+....2....+....3....+....4 
1234567890123456789012345678901234567890 
AB                                       
                   AB                    
                                      AB

Summary

DO
DON'T
DO enable users to specify their own date formats. DON'T hard-code decimals 2 for dollar amounts. Use the currency addition instead.
DO use conversion exits to perform repetitive formatting tasks, especially if they are complex. DON'T hard-code two decimal places for % or any other unit of measure. Use the unit addition instead.

Q&A

Q
I noticed that there are also function modules that have names like CONVERSION_EXIT_XXXXX_INPUT. What are these for?
A
The INPUT function module is called whenever a value is entered into a field, provided the domain for that field specifies a conversion exit. The INPUT conversion exit converts the user's input into a new format before the program receives it. It is used to reduce the amount of repetitive code that is needed to reformat an input value so that the program that uses it doesn't have to.
Q
How do I create a conversion exit?
A
If you don't know how to create a function module, you'll need to read that chapter first. If you do know how to create one, create one with the name CONVERSION_EXIT_XXXXX_OUTPUT where XXXXX is a five-character name you make up. There must be one import parameter named INPUT and one export parameter named OUTPUT. The original value passed from the write statement is received via the INPUT parameter. You can reformat it, and at the end of the function module, assign the new value to the OUTPUT parameter. A good way to start is to copy an existing one.

Workshop

The Workshop provides two ways for you to affirm what you've learned in this chapter. The Quiz section poses questions to help you solidify your understanding of the material covered and the Exercise section provides you with experience in using what you have learned. You can find answers to the quiz questions and exercises in Appendix B, "Answers to Quiz Questions and Exercises."

Quiz

  1. What do you have to do to make sure changes to user defaults take effect?
  2. What happens when an edit mask beginning with a V is applied to a numeric field or character field?
  3. What variable types can the no-sign addition be used with to make a negative number appear as if it were positive?

Exercise 1

Write a program that produces the following output:

....+....1....+....2....+....3....+....4
First                                  December
               January
                              First