After you complete this chapter, you will be able to:
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.
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.
Type Length | ||||
Right | Zeros suppressed | Trailing | 11 | |
Right | Zeros suppressed | Trailing | 2*fldlen or (2*fldlen)+1 | |
None | Scientific notation | Leading | 22 | |
Right | Leading zeros shown | None | fldlen | |
Left | Leading blanks suppressed | fldlen | ||
Left | Determined by user defaults | 8 | ||
Left | HH:MM:SS | 6 | ||
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.
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.
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.
data f1(4) type p. | |
data f2(4) type p decimals 2. | |
data f3(5) type p. | |
data f4(5) type p decimals 3. |
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.
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.
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.
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.
Comma | 1,234.56 |
Period | 1.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.
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.
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
This section details some of the specific output specifications that can be used with 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." |
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
----+----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 |
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
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 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 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'
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
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.
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
To display the existing conversion exits, use the following procedure.
Start the ScreenCam "How to Display Existing Conversion Exits" now.
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.
mm/dd/yyyy dd/mm/yyyy | Writes 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. |
Yymmdd | Writes 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
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
Two statements perform rounding:
Three statements are used to specify the number of decimal places in the output:
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.
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). |
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
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.
30.1 | 30.1 | ||
30.1 | 30.10 | ||
30.1 | 30.100 | ||
30.1234 | 30.123400 | ||
30 | 30 | ||
30 | 30 | ||
30.1 | 30.1 | ||
30.11 | 30.11 | ||
30.11 | 30.11 | ||
30.11 | 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.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
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
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. |
I noticed that there are also function modules that have names like CONVERSION_EXIT_XXXXX_INPUT. What are these for? | |
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. | |
How do I create a conversion exit? | |
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. |
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."
Write a program that produces the following output:
....+....1....+....2....+....3....+....4 First December January First