Try OpenEdge Now
skip to main content
Programming Interfaces
Input/Output Processes : Creating Reports : Using the PUT statement
 

Using the PUT statement

The PUT statement is another useful ABL element for generating reports, especially when you want to customize certain parts of a report. The PUT statement has no default framing services, making it useful for writing data to a file or overriding default framing. Since PUT has no framing defaults, your procedures must contain explicit code for formatting your output.
The PUT statement outputs data one field at a time and uses the format of the field or variable. To include line breaks in the output, you must use the SKIP option. Additionally, the UNFORMATTED option of PUT displays all the data of the field or variable, regardless of format and without spaces between fields.
Why would you use PUT instead of DISPLAY? For every DISPLAY statement, ABL needs a frame. To execute a DISPLAY statement, the AVM builds a frame capable of handling the expected output, using default services and your explicit instructions. PUT on the other hand, simply outputs data one line at a time, with no default formatting. DISPLAY is most useful when you want automatic formatting. PUT is most useful when you want complete control over output.
This is a partial syntax for the PUT statement:

Syntax

PUT [ STREAM stream | STREAM-HANDLE handle ] [ UNFORMATTED ]
[ expression [ FORMAT string ]
[ AT expression | TO expression ]
| SKIP [ ( expression ) ]
| SPACE [ ( expression ) ]
] ...
One common task that the PUT statement can help with is mailing labels. Since mailing labels must conform to a compact physical layout and be uniform, using PUT is a good idea. Suppose that the All Around Sports accounting department wants to send notices to customers with large balances. They need a procedure that creates mailing labels for the notices.
To see an example that uses the PUT statement:
1. Open i-10-11.p and run it.
2. Click Report. The Report Output dialog box appears:
The editor shows the mailing list as it appears in a text file. Note that the output has the following problems:
*For simple addresses, there is a blank line between the street address line and the city, state, postal code line. Some addresses need this blank line for extra information.
*There is too much space between the state and postal code.
3. Click OK, then Exit, and then press SPACEBAR to return to the Procedure Editor.
Here is the code for this procedure:
i-10-11.p
{i-10-in.i} /* Common Interface Setup Code */

    /********** DEFINE TRIGGERS **********/
ON CHOOSE of b-rep DO:
/*1*/ OUTPUT TO "tut-temp.txt".
      FOR EACH Customer WHERE Customer.Balance >= 1400
        BY Customer.PostalCode:
/*2*/   PUT
          Customer.Contact SKIP
          Customer.Name SKIP
          Customer.Address SKIP
          Customer.Address2 SKIP
          Customer.City Customer.State Customer.PostalCode SKIP(1).
      END.
      OUTPUT CLOSE.

      ASSIGN Rep-Editor:READ-ONLY IN FRAME Dialog1 = TRUE
Rep-Editor:SENSITIVE IN FRAME Dialog1 = TRUE
             FRAME Dialog1:TITLE                   = "Report Output"
lStat = Rep-Editor:READ-FILE("tut-temp.txt") IN FRAME Dialog1.

      IF lStat THEN DO:
        ENABLE Rep-Editor b-ok WITH FRAME Dialog1.
        WAIT-FOR GO OF FRAME Dialog1.
        HIDE FRAME Dialog1.
      END.
END.

    /********** MAIN LOGIC **********/
ENABLE ALL WITH FRAME Frame1.
WAIT-FOR CHOOSE OF b-exit.
This procedure contains the following points of interest:
1. The OUTPUT TO statement directs the output from this procedure to a text file named tut-temp.txt.
2. You can use the PUT statement in addition to the DISPLAY statement when sending data to a file or to a printer (any destination other than the screen).
To improve this procedure, you can:
*Remove the blank line from simple addresses that do not use the extra space.
*Tighten up the spacing.
If you run i-10-12.p, you can see the modified version of this procedure.
i-10-12.p
{i-10-in.i} /* Common Interface Setup Code */

/********** DEFINE TRIGGERS **********/
ON CHOOSE of b-rep DO:
      OUTPUT TO "tut-temp.txt".
      FOR EACH Customer WHERE Customer.Balance >= 1400
        BY Customer.PostalCode WITH STREAM-IO:
        PUT
          Customer.Contact SKIP
          Customer.Name SKIP
/*1*/     Customer.Address SKIP.

/*2*/   IF Customer.Address2 NE "" THEN
          PUT Customer.Address2 SKIP.

/*3*/   PUT Customer.City + "," + Customer.State + " " +
          STRING(Customer.PostalCode, "99999") FORMAT "x(23)" SKIP(1).

/*4*/   IF Customer.Address2 EQ "" THEN PUT SKIP(1).
      END. /* FOR EACH Customer */
      OUTPUT CLOSE.

      ASSIGN Rep-Editor:READ-ONLY IN FRAME Dialog1 = TRUE
Rep-Editor:SENSITIVE IN FRAME Dialog1 = TRUE
FRAME Dialog1:TITLE                   = "Report Output"
lStat = Rep-Editor:READ-FILE("tut-temp.txt") IN FRAME Dialog1.

      IF lStat THEN DO:
        ENABLE Rep-Editor b-ok WITH FRAME Dialog1.
        WAIT-FOR GO OF FRAME Dialog1.
        HIDE FRAME Dialog1.
      END.
END. /* ON CHOOSE OF b-rep */

    /********** MAIN LOGIC **********/
ENABLE ALL WITH FRAME Frame1.
WAIT-FOR CHOOSE OF b-exit.
The following is the output of i-10-12.p:
The following notes help explain the techniques used in the procedure:
1. The first PUT statement outputs and formats the part of the mailing label that is common to all labels.
2. The first IF statement determines whether the second address line has data. If it does, it outputs the data.
3. When you create a character expression, like the one in this PUT statement, the AVM removes trailing blanks from the fields. So this output tightens up the extra white space that showed up in the first mailing list example.
4. Finally, the second IF statement determines whether there is second address line data. If not, the PUT statement sends a blank line at the end of the address. This statement keeps the label data together and keeps the individual labels correctly spaced from each other.
* Using PUT for printer control