SAP ABAP Yeni Sözdizimi: Kapsamlı Bir Rehber
Emre Göçmen
Yazar

SAP ABAP Yeni Sözdizimi: Kapsamlı Bir Rehber
İçindekiler
- Giriş
- Temel Yeni Sözdizimi Özellikleri
- Pratik Uygulama Örnekleri
- İleri Düzey Konular
- Performans İyileştirmeleri
- Sonuç
- Ek Kaynaklar
1. Giriş
SAP ABAP (Advanced Business Application Programming), SAP sistemlerinde iş uygulamalarını geliştirmek için kullanılan güçlü ve esnek bir programlama dilidir. SAP S/4HANA ve modern SAP teknolojilerinin ortaya çıkışıyla birlikte, ABAP dili de önemli ölçüde gelişerek modern programlama paradigmalarını desteklemek için yeni sözdizimi özellikleri kazanmıştır.
ABAP'ın yeni sözdizimi (genellikle "ABAP Modern Syntax" veya "ABAP 7.4+" olarak anılır), daha okunabilir, sürdürülebilir ve verimli kod yazmanıza olanak tanıyan çeşitli yapılar ve operatörler sunar. Bu yenilikler sayesinde geliştiriciler daha az kod yazarak daha güçlü uygulamalar oluşturabilir, böylece geliştirme süresi kısalır ve kod kalitesi artar.
Bu rehberde, ABAP'ın yeni sözdizimi özelliklerini detaylı bir şekilde inceleyecek, pratik örneklerle bu özelliklerin nasıl kullanılacağını gösterecek ve modern ABAP programlama tekniklerini ele alacağız.
2. Temel Yeni Sözdizimi Özellikleri
2.1 Yerel Veri Bildirimleri
Klasik ABAP'ta, bir değişken tanımlayıp değer atamak için iki ayrı ifade kullanılırdı. Yeni sözdizimi ile birlikte, değişkenleri tanımlarken aynı zamanda değer atayabilirsiniz. Bu, kod yazımını daha özlü ve anlaşılır hale getirir.
Eski Sözdizimi:
DATA: lv_number TYPE i,
lv_text TYPE string.
lv_number = 42.
lv_text = 'Merhaba Dünya'.
Yeni Sözdizimi:
DATA(lv_number) = 42.
DATA(lv_text) = 'Merhaba Dünya'.
ABAP derleyicisi, atanan değere göre veri türünü otomatik olarak çıkarır. Bu, değişken bildirimine olan ihtiyacı azaltır ve kodun daha kısa ve okunabilir olmasını sağlar.
Yerel Değişken Bildiriminin Sınırlamaları:
- Yerel değişkenler sadece program içerisinde kullanılabilir; sınıf üyeleri veya global değişkenler için bu yöntem kullanılamaz.
- DATA(...) değişkeni, aynı kapsamda birden fazla kez bildirilemez.
- İlk değer ataması yapılmalıdır; DATA(lv_var) gibi boş bir bildirim geçersizdir.
2.2 Satır İçi Bildirimler
Yeni sözdiziminin en güçlü özelliklerinden biri, SQL sorgularında, dahili tablo işlemlerinde ve döngülerde satır içi değişken bildirimi yapabilme yeteneğidir.
SQL Sorgularında Satır İçi Bildirimler:
SELECT carrid, connid, fldate, price
INTO TABLE @DATA(lt_flights)
FROM sflight
WHERE carrid = 'LH'.
LOOP İfadelerinde Satır İçi Bildirimler:
LOOP AT lt_flights INTO DATA(ls_flight).
WRITE: / |Uçuş: { ls_flight-connid }, Tarih: { ls_flight-fldate }|.
ENDLOOP.
READ TABLE İfadelerinde Satır İçi Bildirimler:
READ TABLE lt_flights INTO DATA(ls_first_flight) INDEX 1.
IF sy-subrc = 0.
WRITE: / |İlk uçuş: { ls_first_flight-connid }|.
ENDIF.
2.3 String Şablonları (String Templates)
String şablonları, metin ve değişkenleri kolay ve okunabilir bir şekilde birleştirmenize olanak tanır. Bu özellik, birden çok CONCATENATE ifadesi kullanmak yerine tek bir satırda metin oluşturmanızı sağlar.
DATA(lv_firstname) = 'Ahmet'.
DATA(lv_lastname) = 'Yılmaz'.
" Klasik yöntem
CONCATENATE 'Merhaba ' lv_firstname ' ' lv_lastname INTO DATA(lv_greeting_old).
" String şablonu kullanımı
DATA(lv_greeting_new) = |Merhaba { lv_firstname } { lv_lastname }|.
" Formatlanmış çıktı
DATA(lv_price) = 1250.55.
DATA(lv_order_date) = '20210515'.
DATA(lv_order_output) = |Sipariş Tarihi: { lv_order_date DATE = USER } - Tutar: { lv_price DECIMALS = 2 } TL|.
WRITE: / lv_greeting_new,
/ lv_order_output.
Şablon Formatları:
DATE = USER/ISO/RAW: Tarih biçimlendirmeTIME = USER/ISO/RAW: Saat biçimlendirmeDECIMALS = n: Ondalık basamak sayısıWIDTH = n: Sabit genişlikALIGN = LEFT/CENTER/RIGHT: HizalamaCASE = UPPER/LOWER: Büyük/küçük harf
2.4 VALUE Operatörü
VALUE operatörü, yapıları ve iç tabloları tek bir ifadede doldurmanıza olanak tanır. Bu, kod okunabilirliğini artırır ve yapılandırılmış verilerin daha düzgün işlenmesini sağlar.
Yapı Oluşturma:
TYPES: BEGIN OF ty_employee,
id TYPE i,
first_name TYPE string,
last_name TYPE string,
hire_date TYPE d,
END OF ty_employee.
DATA(ls_employee) = VALUE ty_employee(
id = 12345
first_name = 'Ahmet'
last_name = 'Yılmaz'
hire_date = '20210101'
).
İç Tablo Oluşturma:
DATA(lt_employees) = VALUE tt_employee(
( id = 1 first_name = 'Ali' last_name = 'Kaya' hire_date = '20200101' )
( id = 2 first_name = 'Ayşe' last_name = 'Demir' hire_date = '20200315' )
( id = 3 first_name = 'Mehmet' last_name = 'Şahin' hire_date = '20200610' )
( id = 4 first_name = 'Zeynep' last_name = 'Çelik' hire_date = '20201201' )
).
Mevcut Yapıları Kopyalama ve Değiştirme (BASE):
DATA(ls_employee_updated) = VALUE ty_employee(
BASE ls_employee
first_name = 'Ahmet Can'
hire_date = '20210201'
).
2.5 REDUCE Operatörü
REDUCE operatörü, bir iç tablodaki değerleri özetlemek ve bir toplamdaki (aggregate) değeri hesaplamak için kullanılır.
TYPES: BEGIN OF ty_sales,
product_id TYPE string,
quantity TYPE i,
price TYPE p DECIMALS 2,
END OF ty_sales.
DATA(lt_sales) = VALUE tt_sales(
( product_id = 'A001' quantity = 5 price = 10.50 )
( product_id = 'B002' quantity = 2 price = 25.75 )
( product_id = 'A001' quantity = 3 price = 10.50 )
( product_id = 'C003' quantity = 1 price = 99.99 )
).
" Toplam satış tutarını hesaplama
DATA(lv_total_sales) = REDUCE decfloat34(
INIT total = 0
FOR ls_sale IN lt_sales
NEXT total = total + ( ls_sale-quantity * ls_sale-price )
).
WRITE: / |Toplam Satış Tutarı: { lv_total_sales DECIMALS = 2 } TL|.
2.6 FOR İfadesi
FOR ifadesi, tablolardaki verileri işlemek ve filtrelemek için kullanılır. Hem VALUE hem de diğer işlemci operatörleriyle birlikte kullanılabilir.
Sıralı Sayılar Oluşturma:
DATA(lt_numbers) = VALUE tt_i(
FOR i = 1 THEN i + 1 UNTIL i > 10
( i )
).
Filtrelenmiş Tablo Oluşturma:
DATA(lt_lh_flights) = VALUE tt_flights(
FOR ls_flight IN lt_flights
WHERE ( carrid = 'LH' )
( ls_flight )
).
Dönüştürülmüş Tablo Oluşturma:
DATA(lt_prices) = VALUE tt_price(
FOR ls_flight IN lt_flights
( carrier_id = ls_flight-carrid
flight_id = ls_flight-connid
amount = ls_flight-price * '1.19' "KDV eklenmiş fiyat
currency = ls_flight-currency )
).
2.7 FILTER Operatörü
FILTER operatörü, bir iç tabloyu belirli bir koşula göre filtrelemek için kullanılır. Bu, belirli kriterlere göre tablo alt kümesi oluşturmak için kullanışlıdır.
DATA(lt_lh_flights) = FILTER #( lt_flights WHERE carrid = 'LH' ).
DATA(lt_expensive_flights) = FILTER #( lt_flights WHERE price > 500 ).
EXCEPT ve IN Seçenekleri:
" 'LH' ve 'LX' dışındaki uçuşlar
DATA(lt_other_flights) = FILTER #( lt_flights EXCEPT WHERE carrid = 'LH' OR carrid = 'LX' ).
" Belirli uçuş numaralarını içeren uçuşlar
DATA(lt_selected_connids) = VALUE tt_connid( ( '0400' ) ( '0401' ) ( '0402' ) ).
DATA(lt_selected_flights) = FILTER #( lt_flights IN lt_selected_connids WHERE connid = table_line ).
2.8 Lambda İfadeleri
Lambda ifadeleri, sık kullanılan işlemleri gerçekleştirmek için kullanılır. Özellikle büyük kod bloklarını basitleştirerek kodun daha okunabilir olmasını sağlar.
DATA(lv_total) = REDUCE i(
INIT s = 0
FOR i = 1 UNTIL i > 10
NEXT s = s + i
).
" Lambda ifadesiyle sayıların karelerinin toplamını hesaplama
DATA(lv_sum_of_squares) = REDUCE i(
INIT s = 0
FOR i = 1 UNTIL i > 10
LET square = i * i IN
NEXT s = s + square
).
WRITE: / |1'den 10'a kadar sayıların toplamı: { lv_total }|.
WRITE: / |1'den 10'a kadar sayıların karelerinin toplamı: { lv_sum_of_squares }|.
3. Pratik Uygulama Örnekleri
3.1 Müşteri Sipariş Raporlama
TYPES: BEGIN OF ty_customer,
id TYPE i,
name TYPE string,
city TYPE string,
country TYPE string,
END OF ty_customer.
TYPES: BEGIN OF ty_order,
order_id TYPE i,
customer_id TYPE i,
order_date TYPE d,
total TYPE p DECIMALS 2,
currency TYPE c LENGTH 3,
status TYPE string,
END OF ty_order.
" Örnek veri oluşturma
DATA(lt_customers) = VALUE tt_customer(
( id = 1 name = 'ABC Şirketi' city = 'İstanbul' country = 'TR' )
( id = 2 name = 'XYZ Ltd. Şti.' city = 'Ankara' country = 'TR' )
( id = 3 name = 'MNO GmbH' city = 'Berlin' country = 'DE' )
).
DATA(lt_orders) = VALUE tt_order(
( order_id = 1001 customer_id = 1 order_date = '20210101' total = 1250.75 currency = 'TRY' status = 'Tamamlandı' )
( order_id = 1002 customer_id = 1 order_date = '20210115' total = 750.50 currency = 'TRY' status = 'Tamamlandı' )
( order_id = 1003 customer_id = 2 order_date = '20210120' total = 2500.00 currency = 'TRY' status = 'İşleniyor' )
( order_id = 1004 customer_id = 3 order_date = '20210125' total = 900.00 currency = 'EUR' status = 'Tamamlandı' )
( order_id = 1005 customer_id = 1 order_date = '20210210' total = 1800.25 currency = 'TRY' status = 'İşleniyor' )
).
" 1. Müşteri siparişlerini birleştiren ve raporlayan program
LOOP AT lt_customers INTO DATA(ls_customer).
WRITE: / |Müşteri: { ls_customer-name } ({ ls_customer-city }, { ls_customer-country })|.
" Müşterinin tüm siparişlerini filtrele
DATA(lt_customer_orders) = FILTER #( lt_orders WHERE customer_id = ls_customer-id ).
" Toplam sipariş tutarını hesapla
DATA(lv_total_try) = REDUCE decfloat34(
INIT t = 0
FOR ls_order IN lt_customer_orders WHERE ( currency = 'TRY' )
NEXT t = t + ls_order-total
).
" Her bir siparişi listele
LOOP AT lt_customer_orders INTO DATA(ls_order).
WRITE: /5 |Sipariş: { ls_order-order_id } - { ls_order-order_date DATE = USER } - { ls_order-total DECIMALS = 2 } { ls_order-currency } - Durum: { ls_order-status }|.
ENDLOOP.
WRITE: / |Toplam TRY Siparişleri: { lv_total_try DECIMALS = 2 } TRY|.
SKIP 1.
ENDLOOP.
3.2 Veri Dönüştürme ve Analiz
" Satış verileri
TYPES: BEGIN OF ty_sales_data,
region TYPE string,
product TYPE string,
quantity TYPE i,
sales TYPE p DECIMALS 2,
currency TYPE c LENGTH 3,
sale_date TYPE d,
END OF ty_sales_data.
DATA(lt_sales_data) = VALUE tt_sales_data(
( region = 'Marmara' product = 'Laptop' quantity = 5 sales = 25000.00 currency = 'TRY' sale_date = '20210105' )
( region = 'Ege' product = 'Telefon' quantity = 10 sales = 15000.00 currency = 'TRY' sale_date = '20210110' )
( region = 'Marmara' product = 'Telefon' quantity = 8 sales = 12000.00 currency = 'TRY' sale_date = '20210115' )
( region = 'İç Anadolu' product = 'Tablet' quantity = 3 sales = 6000.00 currency = 'TRY' sale_date = '20210120' )
( region = 'Marmara' product = 'Tablet' quantity = 6 sales = 12000.00 currency = 'TRY' sale_date = '20210125' )
( region = 'Ege' product = 'Laptop' quantity = 4 sales = 20000.00 currency = 'TRY' sale_date = '20210130' )
).
" 1. Ürüne göre toplam satış analizi
TYPES: BEGIN OF ty_product_sales,
product TYPE string,
quantity TYPE i,
sales TYPE p DECIMALS 2,
END OF ty_product_sales.
DATA(lt_product_sales) = VALUE tt_product_sales(
FOR GROUPS product OF ls_sale IN lt_sales_data
GROUP BY ls_sale-product
LET total_quantity = REDUCE i( INIT q = 0
FOR gs IN GROUP product
NEXT q = q + gs-quantity )
total_sales = REDUCE decfloat34( INIT s = 0
FOR gs IN GROUP product
NEXT s = s + gs-sales )
IN ( product = product
quantity = total_quantity
sales = total_sales )
).
WRITE: / 'Ürüne Göre Satış Analizi:'.
LOOP AT lt_product_sales INTO DATA(ls_product_sales).
WRITE: / |Ürün: { ls_product_sales-product } - Adet: { ls_product_sales-quantity } - Toplam Satış: { ls_product_sales-sales DECIMALS = 2 } TRY|.
ENDLOOP.
SKIP 1.
" 2. Bölgeye göre toplam satış analizi
TYPES: BEGIN OF ty_region_sales,
region TYPE string,
quantity TYPE i,
sales TYPE p DECIMALS 2,
END OF ty_region_sales.
DATA(lt_region_sales) = VALUE tt_region_sales(
FOR GROUPS region OF ls_sale IN lt_sales_data
GROUP BY ls_sale-region
LET total_quantity = REDUCE i( INIT q = 0
FOR gs IN GROUP region
NEXT q = q + gs-quantity )
total_sales = REDUCE decfloat34( INIT s = 0
FOR gs IN GROUP region
NEXT s = s + gs-sales )
IN ( region = region
quantity = total_quantity
sales = total_sales )
).
WRITE: / 'Bölgeye Göre Satış Analizi:'.
LOOP AT lt_region_sales INTO DATA(ls_region_sales).
WRITE: / |Bölge: { ls_region_sales-region } - Adet: { ls_region_sales-quantity } - Toplam Satış: { ls_region_sales-sales DECIMALS = 2 } TRY|.
ENDLOOP.
4. İleri Düzey Konular
4.1 ABAP Nesne Yönelimli Programlama
Yeni sözdizimi özellikleri, nesne yönelimli ABAP programlamasını daha güçlü ve esnek hale getirir.
CLASS lcl_product_manager DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_product,
id TYPE string,
name TYPE string,
price TYPE p DECIMALS 2,
category TYPE string,
stock_level TYPE i,
END OF ty_product.
TYPES: tt_products TYPE TABLE OF ty_product WITH KEY id.
METHODS:
constructor,
add_product IMPORTING is_product TYPE ty_product,
get_products RETURNING VALUE(rt_products) TYPE tt_products,
get_available_products RETURNING VALUE(rt_products) TYPE tt_products,
calculate_inventory_value RETURNING VALUE(rv_value) TYPE decfloat34.
PRIVATE SECTION.
DATA: mt_products TYPE tt_products.
ENDCLASS.
CLASS lcl_product_manager IMPLEMENTATION.
METHOD constructor.
" Örnek ürünleri başlat
mt_products = VALUE #(
( id = 'P001' name = 'Laptop Pro' price = 12500.00 category = 'Elektronik' stock_level = 10 )
( id = 'P002' name = 'Akıllı Saat' price = 2450.75 category = 'Giyilebilir' stock_level = 15 )
( id = 'P003' name = 'Kulaklık' price = 850.50 category = 'Aksesuar' stock_level = 0 )
( id = 'P004' name = 'Tablet Max' price = 5750.25 category = 'Elektronik' stock_level = 8 )
).
ENDMETHOD.
METHOD add_product.
APPEND is_product TO mt_products.
ENDMETHOD.
METHOD get_products.
rt_products = mt_products.
ENDMETHOD.
METHOD get_available_products.
" Stokta olan ürünleri filtrele
rt_products = FILTER #( mt_products WHERE stock_level > 0 ).
ENDMETHOD.
METHOD calculate_inventory_value.
" Tüm envanter değerini hesapla
rv_value = REDUCE decfloat34(
INIT value = 0
FOR ls_product IN mt_products
NEXT value = value + ( ls_product-price * ls_product-stock_level )
).
ENDMETHOD.
ENDCLASS.
" Sınıfı kullanma
START-OF-SELECTION.
DATA(lo_product_manager) = NEW lcl_product_manager( ).
" Yeni ürün ekle
lo_product_manager->add_product( VALUE #(
id = 'P005'
name = 'Dış Disk'
price = 1250.00
category = 'Depolama'
stock_level = 12
) ).
" Mevcut ürünleri listele
WRITE: / 'Tüm Ürünler:'.
LOOP AT lo_product_manager->get_products( ) INTO DATA(ls_product).
WRITE: / |{ ls_product-id } - { ls_product-name } - { ls_product-price DECIMALS = 2 } TL - Stok: { ls_product-stock_level }|.
ENDLOOP.
SKIP 1.
" Stokta olan ürünleri listele
WRITE: / 'Stokta Olan Ürünler:'.
LOOP AT lo_product_manager->get_available_products( ) INTO ls_product.
WRITE: / |{ ls_product-id } - { ls_product-name } - { ls_product-price DECIMALS = 2 } TL - Stok: { ls_product-stock_level }|.
ENDLOOP.
SKIP 1.
" Toplam envanter değerini göster
DATA(lv_inventory_value) = lo_product_manager->calculate_inventory_value( ).
WRITE: / |Toplam Envanter Değeri: { lv_inventory_value DECIMALS = 2 } TL|.
4.2 ABAP CDS (Core Data Services)
ABAP CDS, veri modelleme ve HANA veritabanı özelliklerinden tam olarak yararlanmak için kullanılan modern bir yaklaşımdır.
@AbapCatalog.sqlViewName: 'ZSALESREPORT'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Satış Raporu'
define view Z_SALES_REPORT
as select from vbak as SalesHeader
inner join vbap as SalesItem on SalesHeader.vbeln = SalesItem.vbeln
inner join mara as Material on SalesItem.matnr = Material.matnr
inner join kna1 as Customer on SalesHeader.kunnr = Customer.kunnr
{
key SalesHeader.vbeln as SalesDocument,
key SalesItem.posnr as SalesDocumentItem,
SalesHeader.erdat as CreationDate,
Customer.kunnr as CustomerId,
Customer.name1 as CustomerName,
Customer.land1 as Country,
Material.matnr as MaterialNumber,
Material.maktx as MaterialDescription,
@Semantics.quantity.unitOfMeasure: 'OrderUnit'
SalesItem.kwmeng as OrderQuantity,
SalesItem.meins as OrderUnit,
@Semantics.amount.currencyCode: 'DocumentCurrency'
SalesItem.netwr as NetAmount,
SalesHeader.waerk as DocumentCurrency,
// Hesaplanan alanlar
case SalesHeader.faksk
when 'A' then 'Sipariş'
when 'B' then 'Teklif'
else 'Diğer'
end as DocumentType,
// Vergi dahil tutar hesaplama
@Semantics.amount.currencyCode: 'DocumentCurrency'
case
when SalesItem.mwskz = 'A1' then SalesItem.netwr * 1.18
when SalesItem.mwskz = 'A2' then SalesItem.netwr * 1.08
else SalesItem.netwr
end as GrossAmount
}
where SalesHeader.vbtyp = 'C' // Sadece siparişleri seç
4.3 AMDP (ABAP Managed Database Procedures)
AMDP, ABAP koduyla entegre edilmiş HANA SQLScript veya SQL kullanarak veritabanı düzeyinde kod pushdown sağlar.
CLASS zcl_sales_analysis DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES: if_amdp_marker_hdb.
TYPES: BEGIN OF ty_sales_by_region,
region_id TYPE string,
region_name TYPE string,
total_sales TYPE p LENGTH 15 DECIMALS 2,
currency TYPE c LENGTH 3,
END OF ty_sales_by_region.
TYPES: tt_sales_by_region TYPE TABLE OF ty_sales_by_region.
METHODS: get_sales_by_region
IMPORTING VALUE(iv_year) TYPE numc4
EXPORTING VALUE(et_sales) TYPE tt_sales_by_region
VALUE(ev_total_sales) TYPE decfloat34.
ENDCLASS.
CLASS zcl_sales_analysis IMPLEMENTATION.
METHOD get_sales_by_region BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY.
-- HANA SQLScript ile bölgeye göre satışları hesapla
lt_sales = SELECT reg.region_id,
reg.region_name,
SUM(si.netwr) AS total_sales,
sh.waerk AS currency
FROM vbak AS sh
INNER JOIN vbap AS si ON sh.vbeln = si.vbeln
INNER JOIN kna1 AS cust ON sh.kunnr = cust.kunnr
INNER JOIN zregions AS reg ON cust.regio = reg.region_id
WHERE SUBSTRING(sh.erdat, 1, 4) = :iv_year
AND sh.vbtyp = 'C' -- Sadece siparişler
GROUP BY reg.region_id, reg.region_name, sh.waerk
ORDER BY total_sales DESC;
-- Toplam satışları hesapla
lv_total = SELECT SUM(total_sales) AS grand_total
FROM :lt_sales;
-- Sonuçları döndür
et_sales = SELECT * FROM :lt_sales;
ev_total_sales = :lv_total.grand_total;
ENDMETHOD.
ENDCLASS.
4.4 RAP (RESTful ABAP Programming Model)
RAP, SAP Fiori uygulamaları ve SAP API Hub üzerinden OData servisleri sağlamak için kullanılan modern bir programlama modelidir.
" RAP İş Nesnesi Davranışı
managed implementation in class zbp_i_product unique;
define behavior for ZI_Product alias Product
persistent table zproduct
lock master
authorization master ( instance )
etag master LastChangedAt
{
create;
update;
delete;
field ( readonly ) ProductUUID;
field ( mandatory ) ProductID, ProductName, Price;
field ( readonly ) CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
validation validatePrice on save { field Price; }
validation validateProductID on save { field ProductID; }
determination setInitialValues on modify { create; }
mapping for zproduct
{
ProductUUID = product_uuid;
ProductID = product_id;
ProductName = product_name;
Category = category;
Price = price;
Currency = currency;
Description = description;
StockQuantity = stock_quantity;
UnitOfMeasure = unit_of_measure;
CreatedBy = created_by;
CreatedAt = created_at;
LastChangedBy = last_changed_by;
LastChangedAt = last_changed_at;
}
}
5. Performans İyileştirmeleri
Yeni ABAP sözdizimi, kodunuzu sadece daha okunabilir ve sürdürülebilir hale getirmekle kalmaz, aynı zamanda performansını da önemli ölçüde artırabilir. İşte bazı önemli performans iyileştirme teknikleri:
5.1 İç Tablo İşlemlerinde Performans İyileştirme
" 1. LOOP...WHERE yerine FILTER operatörü kullanma
" Kötü performans:
LOOP AT lt_flights INTO DATA(ls_flight) WHERE carrid = 'LH'.
" İşlemler
ENDLOOP.
" İyi performans:
LOOP AT FILTER #( lt_flights WHERE carrid = 'LH' ) INTO DATA(ls_flight).
" İşlemler
ENDLOOP.
" 2. İç içe döngüler yerine FOR...IN ifadesi kullanma
" Kötü performans:
LOOP AT lt_flights INTO DATA(ls_flight).
LOOP AT lt_bookings INTO DATA(ls_booking) WHERE carrid = ls_flight-carrid
AND connid = ls_flight-connid.
" İşlemler
ENDLOOP.
ENDLOOP.
" İyi performans:
DATA(lt_combined) = VALUE tt_combined(
FOR ls_flight IN lt_flights
FOR ls_booking IN lt_bookings
WHERE ( carrid = ls_flight-carrid AND connid = ls_flight-connid )
( carrid = ls_flight-carrid
connid = ls_flight-connid
fldate = ls_flight-fldate
bookid = ls_booking-bookid
customid = ls_booking-customid )
).
LOOP AT lt_combined INTO DATA(ls_combined).
" İşlemler
ENDLOOP.
5.2 Kod Pushdown (HANA Optimizasyonu)
SAP HANA veritabanının gücünden yararlanmak için, olabildiğince çok işlemi veritabanı katmanına "itmek" (push down) önemlidir.
" 1. ABAP içinde hesaplama yerine CDS görünümlerinde hesaplama
" Kötü performans (ABAP katmanında hesaplama):
SELECT carrid, connid, fldate, price, currency
FROM sflight
INTO TABLE @DATA(lt_flights)
WHERE carrid = 'LH'.
DATA(lv_total) = REDUCE decfloat34(
INIT sum = 0
FOR ls_flight IN lt_flights
NEXT sum = sum + ls_flight-price
).
" İyi performans (veritabanı katmanında hesaplama):
SELECT SINGLE SUM( price ) AS total
FROM sflight
WHERE carrid = 'LH'
INTO @DATA(lv_total).
" 2. GROUP BY ile veritabanı katmanında gruplama
" Kötü performans (ABAP katmanında gruplama):
SELECT carrid, connid, fldate, price, currency
FROM sflight
INTO TABLE @DATA(lt_flights).
DATA: lt_carriers TYPE TABLE OF t_carrier,
ls_carrier TYPE t_carrier.
LOOP AT lt_flights INTO DATA(ls_flight).
READ TABLE lt_carriers ASSIGNING FIELD-SYMBOL()
WITH KEY carrid = ls_flight-carrid.
IF sy-subrc <> 0.
ls_carrier-carrid = ls_flight-carrid.
ls_carrier-total = ls_flight-price.
APPEND ls_carrier TO lt_carriers.
ELSE.
-total = -total + ls_flight-price.
ENDIF.
ENDLOOP.
" İyi performans (veritabanı katmanında gruplama):
SELECT carrid,
SUM( price ) AS total
FROM sflight
GROUP BY carrid
INTO TABLE @DATA(lt_carriers).
6. Sonuç
ABAP yeni sözdizimi, SAP geliştirme süreçlerini daha modern, verimli ve sürdürülebilir hale getiren önemli bir gelişimdir. Bu rehberde ele alınan özellikler, kod yazımında daha az çaba ile daha yüksek kalite elde etmenize yardımcı olur.
Yeni sözdiziminin sunduğu avantajlar şunlardır:
- Daha özlü ve okunabilir kod
- Daha az tekrarlayan kod bloğu
- Daha güçlü tip güvenliği
- Daha iyi veritabanı entegrasyonu
- Daha yüksek kod performansı
- Modern programlama paradigmalarıyla uyum
SAP geliştirme projelerinizde yeni sözdizimi özelliklerini kullanarak, daha kaliteli ve sürdürülebilir uygulamalar geliştirebilirsiniz. Bu özellikler, özellikle S/4HANA ve SAP Cloud Platform projelerinde büyük önem taşımaktadır.
7. Ek Kaynaklar
Yorumlar
Henüz yorum bulunmamaktadır.
İlk yorumu yapan siz olun.



