ALV (ABAP List Viewer) is the standard way to display tabular data in SAP reports. Instead of writing plain lists with the WRITE statement, ALV gives your users a professional grid with sorting, filtering, totals, and export to Excel — all with very little extra code.
This guide walks you through creating an ALV report step by step, covering both the classic function module approach and the modern object-oriented approach.
What Is ALV?
ALV is a set of SAP tools for displaying data in a structured, interactive list. When you run an ALV report, the user gets:
- A spreadsheet-like grid of rows and columns
- Click-to-sort on any column header
- Built-in filtering
- Subtotals and grand totals
- Export to Excel or other formats
- Layout variants (users can save their own column arrangements)
Writing all of this from scratch would take hundreds of lines of code. With ALV, you fetch your data into an internal table and hand it to the ALV engine — it handles the display.
The Two Main Approaches
There are two common ways to build an ALV report:
- Function module approach — using
REUSE_ALV_GRID_DISPLAY(orREUSE_ALV_LIST_DISPLAY). This is the classic, widely-used method, especially in older codebases and quick reports. - Object-oriented approach — using the class
CL_SALV_TABLE. This is the modern, SAP-recommended method: less code, automatic field catalog generation, and cleaner syntax.
Both are worth knowing. The function module approach appears constantly in existing customer code you will maintain, while CL_SALV_TABLE is what you should reach for in new development. This guide shows both, starting with the simpler OO version.
Prerequisites
Before you start, you need:
- Access to an SAP system with ABAP development authorization
- Basic ABAP knowledge (internal tables,
SELECTstatements) - A data source to display — we will use flight data table SFLIGHT in the examples, since it exists in most SAP demo systems
Step-by-Step: ALV with CL_SALV_TABLE (Recommended)
Step 1: Create the Program
In transaction SE38, create a new program (type: Executable program). Give it a name in the customer namespace, e.g. Z_ALV_DEMO.
Step 2: Declare Your Data
Define the internal table that will hold the report data:
REPORT z_alv_demo.
DATA: gt_flights TYPE TABLE OF sflight.
Step 3: Select the Data
Fetch the data with a straightforward SELECT. Keep the selection small for a demo:
START-OF-SELECTION.
SELECT * FROM sflight
INTO TABLE gt_flights
UP TO 50 ROWS.
IF gt_flights IS INITIAL.
MESSAGE 'No data found' TYPE 'I'.
RETURN.
ENDIF.
Step 4: Create the ALV Object and Display It
This is where the magic happens — just a few lines:
DATA: lo_alv TYPE REF TO cl_salv_table.
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = gt_flights ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_msg).
MESSAGE lx_msg->get_text( ) TYPE 'I'.
ENDTRY.
Run the program (F8), and you get a full interactive ALV grid — sorting, filtering, and export included — from about 25 lines of code. The class automatically builds the field catalog from the structure of your internal table.
Step 5 (Optional): Enable Standard Functions
To give users the full toolbar (sort, filter, totals, Excel export), enable the default functions:
DATA(lo_functions) = lo_alv->get_functions( ).
lo_functions->set_all( abap_true ).
Add this before lo_alv->display( ).
Step-by-Step: ALV with REUSE_ALV_GRID_DISPLAY (Classic)
The function module approach requires you to build a field catalog manually — a table describing each column (field name, heading text, length, and so on).
Step 1–3: Same as Above
Create the program, declare the internal table, and select the data exactly as in the OO version.
Step 4: Build the Field Catalog
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv,
ls_fieldcat TYPE slis_fieldcat_alv.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'CARRID'.
ls_fieldcat-seltext_m = 'Airline'.
APPEND ls_fieldcat TO gt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'CONNID'.
ls_fieldcat-seltext_m = 'Connection'.
APPEND ls_fieldcat TO gt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'FLDATE'.
ls_fieldcat-seltext_m = 'Flight Date'.
APPEND ls_fieldcat TO gt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'PRICE'.
ls_fieldcat-seltext_m = 'Price'.
ls_fieldcat-do_sum = 'X'.
APPEND ls_fieldcat TO gt_fieldcat.
Each entry maps one field of your internal table to a column, with display settings. (In real programs, the helper function module REUSE_ALV_FIELDCATALOG_MERGE can generate this catalog automatically from a structure — worth learning once you are comfortable.)
Step 5: Set the Layout (Optional)
DATA: ls_layout TYPE slis_layout_alv.
ls_layout-zebra = 'X'. " striped rows
ls_layout-colwidth_optimize = 'X'. " auto-adjust column widths
Step 6: Call the Function Module
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
is_layout = ls_layout
it_fieldcat = gt_fieldcat
TABLES
t_outtab = gt_flights
EXCEPTIONS
program_error = 1
OTHERS = 2.
The grid appears with your custom column headings, zebra striping, and a totals-capable price column.
Field Catalog Basics You Should Know
Whether you build it manually or generate it, the field catalog controls how each column behaves. The most useful settings are:
- fieldname — the field in your internal table (must match exactly)
- seltext_l / seltext_m / seltext_s — column heading texts (long, medium, short)
- do_sum — set to ‘X’ to allow totals on numeric columns
- no_out — set to ‘X’ to hide a column by default
- edit — set to ‘X’ to make a column editable
- hotspot — set to ‘X’ to make values clickable (with event handling)
- just — column alignment: ‘L’, ‘C’, or ‘R’
Layout Options Worth Using
The layout structure (slis_layout_alv for the function module, or the layout object for CL_SALV_TABLE) controls the grid’s overall appearance:
- zebra — alternating row colors for readability
- colwidth_optimize — sizes columns to fit their content
- no_colhead — hides column headings (rarely wanted)
- totals_text — custom label for the totals row
Practical Tips
Performance
- Never SELECT without a WHERE clause on large tables. Always restrict your data selection — ALV is a display tool, not a substitute for proper data filtering.
- Select only the fields you need. A field list (
SELECT carrid connid fldate ...) is faster thanSELECT *on wide tables. - Avoid nested SELECTs in loops. If you need related data, fetch it with
FOR ALL ENTRIESor a JOIN before displaying.
Layout Variants
Users can save their own ALV layouts (column order, hidden columns, sorts) as variants. As a developer, you can allow this by passing the variant structure to the function module — a small effort that users greatly appreciate in production reports.
Editable ALVs
Both approaches support editable columns, but editable ALVs add complexity (data_changed events, validation). For simple data-entry screens, consider whether a module pool or Fiori app is more appropriate before building a heavily editable ALV.
When to Use Which Approach
| Situation | Recommended |
|---|---|
| New report development | CL_SALV_TABLE — less code, SAP’s direction |
| Maintaining existing code | Whatever the program already uses (often REUSE_ALV_GRID_DISPLAY) |
| Need maximum control over columns | Function module with manual field catalog |
| Quick prototype or demo | CL_SALV_TABLE — fastest path to a working grid |
Frequently Asked Questions
Q1. What does ALV stand for?
ALV stands for ABAP List Viewer. It is SAP’s standard toolset for displaying tabular data in interactive lists and grids.
Q2. What is the difference between REUSE_ALV_GRID_DISPLAY and REUSE_ALV_LIST_DISPLAY?
REUSE_ALV_GRID_DISPLAY shows data in a spreadsheet-like grid (Control-based), while REUSE_ALV_LIST_DISPLAY shows a classic hierarchical list. The grid version is far more common in modern reports because of its Excel-like behavior.
Q3. Do I always need a field catalog?
With CL_SALV_TABLE, no — the class generates the field catalog automatically from your internal table structure. With the function module approach, you must supply one (manually or via REUSE_ALV_FIELDCATALOG_MERGE).
Q4. How do users export ALV data to Excel?
The standard ALV toolbar includes an export function. Enabling all standard functions (as shown in Step 5 of the OO version) gives users export, sorting, filtering, and totals out of the box.
Q5. Can ALV columns be made editable?
Yes, both approaches support editable columns, but handling the changes requires event handling code. Keep editable ALVs simple, or consider a dedicated maintenance dialog for complex data entry.
Q6. Is ALV still relevant with Fiori and S/4HANA?
Yes. ALV remains heavily used in classic ABAP reports and is still the fastest way to build an interactive list in ABAP. For new Fiori UX, SAP recommends Fiori elements and OData, but countless production reports run on ALV and will for years.
The Bottom Line
Creating an ALV report boils down to three steps: select your data into an internal table, hand it to the ALV engine, and display it. The modern CL_SALV_TABLE class does this in a handful of lines, while the classic REUSE_ALV_GRID_DISPLAY function module gives you fine-grained control through the field catalog and layout.
Learn the OO approach for new work, recognize the function module approach in legacy code, and always remember: ALV displays data — it does not replace good data selection. Filter early, select lean, and your reports will be fast.
Building reports on materials data? Check our SAP MM tables complete list to find the right tables for your SELECT statements.