ABAP Classic — SAP Programming from Scratch/Reports & User Interfaces

Classical Reports — WRITE Statement Formatting

Format ABAP report output with WRITE: column alignment, headers, totals, colors, horizontal lines, and page breaks.

Classical Reports — WRITE Statement Formatting

What You'll Learn

  • Formatting output with column positions and widths
  • Creating headers and underlines
  • Adding color to output
  • Page breaks and page headers
  • Building a complete formatted report

Column-Aligned Output

REPORT z_classical_report LINE-SIZE 100.

* Header
WRITE: / 'Emp ID' COLOR COL_HEADING,
     20 'Name' COLOR COL_HEADING,
     50 'Department' COLOR COL_HEADING,
     75 'Salary' COLOR COL_HEADING.
ULINE.  " Horizontal line

* Data rows
WRITE: / '001', 20 'Alice Johnson', 50 'Engineering', 75 '120,000.00'.
WRITE: / '002', 20 'Bob Smith', 50 'Marketing', 75 '95,000.00'.
WRITE: / '003', 20 'Charlie Brown', 50 'Engineering', 75 '130,000.00'.

ULINE.
WRITE: / 'Total:', 75 '345,000.00' COLOR COL_TOTAL.

Expected Output

Emp ID              Name                              Department             Salary
────────────────────────────────────────────────────────────────────────────────────
001                 Alice Johnson                     Engineering            120,000.00
002                 Bob Smith                         Marketing               95,000.00
003                 Charlie Brown                     Engineering            130,000.00
────────────────────────────────────────────────────────────────────────────────────
Total:                                                                      345,000.00

The number after the variable (e.g., 20 'Name') is the column position. ULINE draws a horizontal line. COLOR adds background highlighting.

WRITE Formatting Options

DATA: lv_amount TYPE p DECIMALS 2 VALUE '123456.78',
      lv_date   TYPE d VALUE '20260412',
      lv_pct    TYPE p DECIMALS 1 VALUE '85.5'.

WRITE: / 'Amount:', lv_amount.                           " Default: 123,456.78
WRITE: / 'No sign:', lv_amount NO-SIGN.                  " Remove negative sign
WRITE: / 'Left aligned:', lv_amount LEFT-JUSTIFIED.      " Left-align (default is right)
WRITE: / 'Date formatted:', lv_date DD/MM/YYYY.          " 12/04/2026
WRITE: / 'Date ISO:', lv_date YYYYMMDD.                  " 20260412
WRITE: / 'Percentage:', lv_pct, '%'.

Colors

* Available colors
WRITE: / 'COL_HEADING' COLOR COL_HEADING.     " Blue/grey header
WRITE: / 'COL_NORMAL' COLOR COL_NORMAL.       " Normal background
WRITE: / 'COL_TOTAL' COLOR COL_TOTAL.         " Yellow — for totals
WRITE: / 'COL_KEY' COLOR COL_KEY.             " Blue-green — for key fields
WRITE: / 'COL_POSITIVE' COLOR COL_POSITIVE.   " Green — good values
WRITE: / 'COL_NEGATIVE' COLOR COL_NEGATIVE.   " Red — bad values
WRITE: / 'COL_GROUP' COLOR COL_GROUP.         " Purple — group headers

A Complete Formatted Report

REPORT z_employee_report LINE-SIZE 120 NO STANDARD PAGE HEADING.

TYPES: BEGIN OF ty_employee,
         id         TYPE n LENGTH 10,
         name       TYPE string,
         department TYPE string,
         salary     TYPE p DECIMALS 2,
       END OF ty_employee.

DATA: lt_employees TYPE TABLE OF ty_employee,
      lv_total     TYPE p DECIMALS 2,
      lv_count     TYPE i.

PARAMETERS: p_dept TYPE c LENGTH 30 DEFAULT 'Engineering'.

TOP-OF-PAGE.
  WRITE: / 'EMPLOYEE SALARY REPORT' COLOR COL_HEADING CENTERED.
  WRITE: / |Department: { p_dept }| COLOR COL_HEADING,
        80 |Date: { sy-datum DATE = USER }| COLOR COL_HEADING,
       105 |Page: { sy-pagno }| COLOR COL_HEADING.
  ULINE.
  WRITE: / 'ID' COLOR COL_HEADING,
        15 'Name' COLOR COL_HEADING,
        50 'Department' COLOR COL_HEADING,
        80 'Salary' COLOR COL_HEADING.
  ULINE.

START-OF-SELECTION.
  lt_employees = VALUE #(
    ( id = '0000000001' name = 'Alice Johnson' department = 'Engineering' salary = '120000.00' )
    ( id = '0000000003' name = 'Charlie Brown' department = 'Engineering' salary = '130000.00' )
    ( id = '0000000006' name = 'Frank Wilson'  department = 'Engineering' salary = '145000.00' )
  ).

  LOOP AT lt_employees INTO DATA(ls_emp).
    WRITE: / ls_emp-id,
          15 ls_emp-name,
          50 ls_emp-department,
          80 ls_emp-salary.
    lv_total = lv_total + ls_emp-salary.
    lv_count = lv_count + 1.
  ENDLOOP.

END-OF-SELECTION.
  ULINE.
  WRITE: / 'Total:' COLOR COL_TOTAL,
        80 lv_total COLOR COL_TOTAL.
  WRITE: / |Employees: { lv_count }| COLOR COL_TOTAL.
  SKIP 1.
  WRITE: / |Report generated by { sy-uname } at { sy-uzeit TIME = USER }|.

When to Use Classical Reports

Classical WRITE-based reports are simple and fast to build. Use them for:

  • Quick ad-hoc reports
  • Simple list output
  • Debugging (writing intermediate values)
  • Legacy maintenance (many existing reports use this style)

For professional reports, use ALV (next lesson). ALV provides sorting, filtering, column reordering, export to Excel, and a modern look — all built in. Classical reports require you to code all of this manually.

Common Mistakes

  • Not setting LINE-SIZE. Default line width is 83 characters — too narrow for most reports. Use LINE-SIZE 120 or LINE-SIZE 200 in the REPORT statement.
  • Hardcoding column positions that overlap. If you put name at position 15 and department at position 30, a name longer than 15 characters bleeds into the department column. Test with long values.
  • Forgetting NO STANDARD PAGE HEADING. By default, SAP adds its own page header (program name, page number). If you use TOP-OF-PAGE for custom headers, add NO STANDARD PAGE HEADING to the REPORT statement to suppress the default.

Key Takeaways

  • Classical reports use WRITE with column positions for formatted output.
  • ULINE draws horizontal lines. SKIP adds blank lines. COLOR adds background highlighting.
  • TOP-OF-PAGE creates page headers. LINE-SIZE sets the output width.
  • For professional output, use ALV reports (next lesson) instead of classical WRITE.
  • Classical reports are still useful for debugging and quick ad-hoc output.

Next Lesson

Classical reports require manual formatting for everything. In Lesson 21: ALV Reports, we'll learn the modern way to display data — with built-in sorting, filtering, totals, and Excel export.