Chapter 3: Make It Useful

Turning your first Python report into something that feels closer to a real SAP reporting tool

Chapter Goal

From Demo Script to Practical Report

In Chapter 2, you built a simple Python report that displayed material data in a browser-based table. That was the “hello world” version of an ALV-style report.

Now we make it useful. A report becomes valuable when users can narrow the data, sort it, export it, and understand the result quickly.

LoadRead material data
FilterKeep what matters
SortOrganize rows
ExportCreate Excel output
VisualizeAdd quick insight
ABAP mindset: We are adding the things users expect from ALV: filtering, sorting, exporting, and quick analysis.

Starting Dataset

We will keep using a small CSV file so the project is easy to run. Later chapters can replace this file with a database query, SAP RFC call, OData service, or API response.

materials.csv

matnr,maktx,mtart,matkl,plant,stock 1001,Demo Finished Product,FERT,001,1000,45 1002,Demo Semi Finished,HALB,002,1000,22 1003,Demo Raw Material,ROH,003,2000,120 1004,Demo Finished Product 2,FERT,001,2000,31 1005,Demo Trading Good,HAWA,004,3000,8 1006,Demo Finished Product 3,FERT,002,1000,67

What the user should see

Preview: Material Data
Material Description Type Plant Stock
1001Demo Finished ProductFERT100045
1002Demo Semi FinishedHALB100022
1003Demo Raw MaterialROH2000120
1004Demo Finished Product 2FERT200031

Because the goal is to learn the Python reporting pattern first. Once the pattern is clear, the data source can change. This avoids beginner blockers like authorizations, network issues, database drivers, API tokens, and SAP connectivity.

Step 1: Load the Data

In ABAP, your report often starts with a SELECT statement. In this beginner Python version, we start by reading a CSV.

ABAP Pattern

SELECT matnr, maktx, mtart, matkl FROM mara INTO TABLE @DATA(lt_materials) UP TO 100 ROWS.

Python Pattern

import pandas as pd df = pd.read_csv("materials.csv") print(df.head())
Python translation: The DataFrame named df is now your table-like structure.

Step 2: Filter Like a Selection Condition

ABAP developers are used to WHERE clauses and selection screens. In Python, the simplest beginner-friendly filter uses pandas conditions.

ABAP

SELECT matnr, mtart, plant FROM zmaterial_stock INTO TABLE @DATA(lt_materials) WHERE mtart = 'FERT'.

Python

filtered = df[df["mtart"] == "FERT"] print(filtered)

Expected filtered preview

Preview: Filter Applied
Filter: Material Type = FERT
Material Description Type Plant Stock
1001Demo Finished ProductFERT100045
1004Demo Finished Product 2FERT200031
1006Demo Finished Product 3FERT100067

Step 3: Sort the Result

A sorted result is easier to scan. This is the same idea as sorting an ALV column, except we do it before displaying the report.

Sort by Material

sorted_df = filtered.sort_values(by="matnr")

Sort by Stock Descending

sorted_df = filtered.sort_values( by="stock", ascending=False )
Tip: Sorting before display is useful when you want the report to open with the most important records first.

Step 4: Display the Improved Table with Bokeh

Now we display the filtered and sorted DataFrame in a Bokeh DataTable. This is the closest beginner-friendly replacement for a simple ALV table.

from bokeh.models import ColumnDataSource, DataTable, TableColumn from bokeh.io import show source = ColumnDataSource(sorted_df) columns = [ TableColumn(field="matnr", title="Material"), TableColumn(field="maktx", title="Description"), TableColumn(field="mtart", title="Type"), TableColumn(field="plant", title="Plant"), TableColumn(field="stock", title="Stock") ] table = DataTable( source=source, columns=columns, width=950, height=280, sortable=True ) show(table)

Expected browser result

Browser Preview: Bokeh DataTable
Material ▲▼ Description ▲▼ Type ▲▼ Plant ▲▼ Stock ▲▼
1006Demo Finished Product 3FERT100067
1001Demo Finished ProductFERT100045
1004Demo Finished Product 2FERT200031

Step 5: Export to Excel

A lot of practical reporting work still ends in Excel. That is not a failure; it is reality. Python can generate that file directly.

sorted_df.to_excel("filtered_materials.xlsx", index=False)
📄
Input

materials.csv

⚙️
Processing

filter + sort

📊
Output

filtered_materials.xlsx

Practical value: This one line can replace repeated manual exports, cleanup, and copy/paste routines.

Step 6: Add a Quick Chart

A table answers “what are the records?” A chart answers “what is the pattern?” For this example, we count how many records exist by material type.

from bokeh.plotting import figure, show counts = df["mtart"].value_counts() chart = figure( x_range=list(counts.index), title="Material Count by Type", height=350, width=700 ) chart.vbar( x=list(counts.index), top=list(counts.values), width=0.6 ) show(chart)

Expected chart preview

Preview: Material Count by Type
3
FERT
1
HALB
1
ROH
1
HAWA

Because many SAP reports stop at rows and columns. Python makes it easy to add quick visual summaries that help users understand the data faster.

Full Script: Improved Material Report

Here is the full beginner-friendly version. Save it as material_report.py in the same folder as your materials.csv file.

import pandas as pd from bokeh.io import show from bokeh.layouts import column from bokeh.models import ColumnDataSource, DataTable, TableColumn, Div from bokeh.plotting import figure # 1. Load data df = pd.read_csv("materials.csv") # 2. Filter to finished products filtered_df = df[df["mtart"] == "FERT"] # 3. Sort by stock descending sorted_df = filtered_df.sort_values(by="stock", ascending=False) # 4. Export filtered result to Excel sorted_df.to_excel("filtered_materials.xlsx", index=False) # 5. Build Bokeh table source = ColumnDataSource(sorted_df) columns = [ TableColumn(field="matnr", title="Material"), TableColumn(field="maktx", title="Description"), TableColumn(field="mtart", title="Type"), TableColumn(field="plant", title="Plant"), TableColumn(field="stock", title="Stock") ] table = DataTable( source=source, columns=columns, width=950, height=280, sortable=True ) # 6. Build chart counts = df["mtart"].value_counts() chart = figure( x_range=list(counts.index), title="Material Count by Type", height=350, width=700 ) chart.vbar( x=list(counts.index), top=list(counts.values), width=0.6 ) # 7. Show report title = Div(text="<h2>Material Report</h2><p>Filtered to FERT materials and sorted by stock.</p>") show(column(title, table, chart))
think-like-python-project/ │ ├── material_report.py ├── materials.csv └── filtered_materials.xlsx ← created after running the script

What You Should Have After Running This

🌐
Browser Report

A Bokeh page with a sortable table and a simple bar chart.

📊
Excel File

A filtered Excel export named filtered_materials.xlsx.

🧠
Reusable Pattern

Load data, filter it, sort it, export it, and visualize it.

Big idea: You did not just write Python syntax. You built the reporting pattern that will keep showing up throughout this book.

Try This

with pd.ExcelWriter("material_report.xlsx") as writer: df.to_excel(writer, sheet_name="All Materials", index=False) sorted_df.to_excel(writer, sheet_name="Filtered FERT", index=False)

Chapter 3 Checkpoint

Next: Before jumping to Flask and BTP, we should bridge one more ABAP concept: selection screens. The next chapter can show how Python scripts accept user input and parameters.
End of Chapter 3