SAP query. Retrieve values basing on input on selection screen - abap

I am stuck with coding a SAP query..I am new to ABAP.
What I would like to achieve is a join between tables ESLL, EKPO, EKKO.
Specifically these are the steps I would like to achieve:
in the selection parameter every time I will enter the query I will
give a different value for ESLL-EXTSRVNO;
basing on that value the query automatically should select ESLL-PACKNO basing on ESLL-EXTSRVNO given;
then the query should put ESLL-SUB_PACKNO equal
to the ESLL-PACKNO values of the steps before;
then the query should
put the new ESLL-PACKNO values equal to EKPO-PACKNO and retrieve the
following fields: EKPO-EBELN, EKPO-EBELP, EKPO-MATKL.
I have already written some code inside the infoset, but I do not know how to fix it.
In the "data" section I have written:
DATA: it_esll TYPE TABLE OF esll.
DATA: it_esll2 TYPE TABLE OF esll.
DATA: it_ekpo TYPE TABLE OF ekpo.
In the "start-of-selection" section I have written:
SELECT packno
FROM esll
INTO TABLE it_esll.
IF sy-subrc EQ 0.
SELECT packno FROM esll
into TABLE it_esll2
for ALL ENTRIES IN it_esll
where sub_packno EQ it_esll-packno.
IF sy-subrc EQ 0.
SELECT ebeln ebelp bukrs werks matkl menge netpr peinh
FROM ekpo
into TABLE it_ekpo
for ALL ENTRIES IN it_esll2
WHERE packno EQ it_esll2-packno.
endif.
endif.
And, in order to display all the information I want, I have put the following joins:
ESLL-PACKNO --> EKPO-PACKNO --> EKPO-EBELN --> EKKO-EBELN
At then end I would like to display these information:
EKPO-EBELN
EKPO-EBELP
EKPO-MATKL
EKKO-BSART
EKPO-PACKNO
Could you please help me?

One option could be to use Alias table in your infoset, something like this:
First table: ESLL;
Second table ZESLL (Alias on ESLL) with join ZESLL-PACKNO = ESLL-SUB_PACKNO;
Third table: EKPO with join on EKPO-PACKNO = ZESLL-PACKNO;
Fourth table: EKKO with join on EBELN;
So you can avoid ABAP
Infoset Join

Related

How to join the tables KNBK and TIBAN?

I am trying to read the table TIBAN only in the cases when the field BANKN of the KNBK table contains the string "IBAN". The problem that I am having is reading the table TIBAN. For the KNBK table I used the key kunnr to search the table, but the table TIBAN does not contain this field. The code is as follows:
LOOP AT lt_data_bsec ASSIGNING <ls_data_bsec>.
READ TABLE lt_data_knbk ASSIGNING FIELD-SYMBOL(<ls_data_knbk>)
WITH KEY kunnr = <ls_data_bsec>-kunnr BINARY SEARCH .
IF <ls_data_knbk>-bankn_kn CS '<IBAN>'.
>>>>> READ TABLE lt_data_tiban ASSIGNING FIELD-SYMBOL(<ls_data_tiban>).
IF <ls_data_bsec> IS ASSIGNED
AND <ls_data_tiban> IS ASSIGNED
AND ( <ls_data_bsec>-banks_bs NE <ls_data_tiban>-banks_kn
OR <ls_data_bsec>-bankl_bs NE <ls_data_tiban>-bankl_kn
OR <ls_data_bsec>-bankn_bs NE <ls_data_tiban>-bankn_kn ).
ENDIF.
The declaration of the lt_data_knbk table is:
SELECT kunnr,
banks AS banks_kn,
bankl AS bankl_kn,
bankn AS bankn_kn
FROM knbk
INTO TABLE #DATA(lt_data_knbk)
FOR ALL ENTRIES IN #lt_data_bsec
WHERE kunnr = #lt_data_bsec-kunnr
ORDER BY PRIMARY KEY.
And the declaration of the lt_data_tiban is:
SELECT banks AS banks_tb,
bankl AS bankl_tb,
bankn AS bankn_tb
FROM tiban
INTO TABLE #DATA(lt_data_tiban).
Also the declaration of the lt_data_bsec is of the type gty_out:
BEGIN OF gty_out,
bukrs TYPE bukrs,
belnr TYPE belnr_d,
buzei TYPE buzei,
budat TYPE budat,
kunnr TYPE kunnr,
banks_kn TYPE banks,
bankl_kn TYPE bankk,
bankn_kn TYPE bankn,
banks_bs TYPE banks,
bankl_bs TYPE bankk,
bankn_bs TYPE bankn,
banks_tb TYPE banks,
bankl_tb TYPE bankk,
bankn_tb TYPE bankn,
END OF gty_out,
I am having an error in the line that I have marked in the code as it needs a key field to do the reading of the table.
May anyone know what type of field do I need to do a search of the TIBAN table, just like I did for the KNBK table?
I would recommend you to acquire your bank data by doing a LEFT OUTER JOIN with TIBAN.
SELECT knbk~kunnr AS kunnr,
knbk~banks AS banks_kn,
knbk~bankl AS bankl_kn,
knbk~bankn AS bankn_kn,
knbk~bkont AS bkont_kn,
tiban~iban AS iban
FROM knbk
LEFT OUTER JOIN tiban ON
tiban~banks = knbk~banks AND
tiban~bankl = knbk~bankl AND
tiban~bankn = knbk~bankn AND
tiban~bkont = knbk~bkont
INTO TABLE #DATA(lt_data_knbk)
FOR ALL ENTRIES IN #lt_data_bsec
WHERE knbk~kunnr = #lt_data_bsec-kunnr
ORDER BY knbk~banks knbk~bankl knbk~bankn knbk~bkont.
The result will be a table with all entries from KNBK, plus a field IBAN which will be filled from TIBAN if a corresponding row exists and be initial when no corresponding row exists.
Now you can just determine whether or not you have an IBAN like this:
LOOP AT lt_data_knbk ASSIGNING FIELD-SYMBOL(<ls_data_knbk>).
IF <ls_data_knbk>-iban IS INITIAL.
" classic bank number + account number account
ELSE.
" IBAN account
ENDIF.
ENDLOOP.
Your task is a perfect case where ABAP CDS associations aka Lazy Join come into play.
If you are on the recent version of ABAP and is able to create CDS, nothing prevents you from creating this
#AbapCatalog.sqlViewName: ‘ZCUST_TIBAN_SQL’
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #CHECK
#EndUserText.label: ‘TIBAN’
define view ZCUST_TIBAN as select from knbk as cus
association [0..1] to tiban as _an
on cus.kunnr = _an.kunnr
and cus.banks = _an.banks
and cus.bankl = _an.bankl
and cus.bankn = _an.bankn
and cus.bkont = _an.bkont
{
cus.kunnr,
cus.banks AS banks_kn,
cus.bankl AS bankl_kn,
cus.bankn AS bankn_kn,
cus.bkont AS bkont_kn,
_iban~
} WHERE cus.bankn like '%IBAN%'
Then you can use this association in all your further requirements:
SELECT banks_kn, bankl_kn, bankn_kn, bkont_kn
\_iban-iban AS IBAN,
\_iban-valid_from AS IBAN_validity
FROM zcust_tiban
WHERE kunnr IN #lr_customers
INTO TABLE #DATA(lt_data_knbk).
...
READ TABLE lt_data_knbk ASSIGNING FIELD-SYMBOL(<ls_data_knbk>)
WITH KEY kunnr = <ls_data_bsec>-kunnr BINARY SEARCH.
...
Key points to pay attention to:
an association with 0..1 cardinality like above does not do actual JOIN until the fields from the associated table TIBAN are requested like in the above SELECT. This can be more performant and more universal than LEFT OUTER JOIN approach suggested by Philipp.
it is reusable and can be used in further selects/associations as a source

displaying data in dropdownlist using sql with querystring

I have three tables:
tbprd -- prdcod int PK, prdtit v(100), prddefuom int FK to prduomcod (tbprduom)
tbuom -- uomcod int PK, uomnam v(100)
tbprduom -- prduomcod int PK, prduomprdcod int FK prdcod(tbprd), prduomuomcod int FK uomcod(tbuom)
What I need is to display uomnam in dropdownlist display field and uomcod in data value field from prdcod which I have passed through query string but if the chosen prdcod is 4 then the dropdownlist should display all the uomnam matching w.r.t all matching prdtit
Query I am using:
select uomcod, uomnam
from tbuom, tbprd, tbprduom
where prdcod = 4
and prduomuomcod = uomcod
and prddefprduomcod = prduomcod
Look at the images for more clearer idea about what I want and table data
https://drive.google.com/drive/folders/17p3d1WXMppndIq1bXf6EwShLWBrh-IsC?usp=sharing
Based on what I understand, you want to get all products that have the same title as the product with the given prdcod. If that's correct, then here's one way to do it:
Write a query to get the prdtit value for prdcod = 4 (return one column from one row):
SELECT prdtit
FROM ...
Use this value to filter the rest of the rows in the tbprd table:
SELECT *
FROM tbrpd
WHERE prdtit = (<Query in Step 1>)
Add two joins to the tbprduom and tbuom tables to Step #2 to get the remaining info:
SELECT tbuom.uomcod, tbuom.uomnam
FROM tbrpd
WHERE prdtit = (<Query in Step 1>)
LEFT JOIN tbprduom ON ... <PK/FK fields) -- Get uomcod for products
LEFT JOIN tbuom ON ... <PK/FK fields) -- Get "uom" fields to return
Give it a try and see how far you get. If you get stuck on a step, just let me know.

Combining 2 tables without losing any data

My first table (actually a view) is:
SELECT * FROM VW_MAIN_INFO
My second table is:
SELECT * FROM TBL_POINTS_AND_CYCLES
In a query, I combine both like this:
SELECT TP.TYPE,VMI.*
FROM VW_MAIN_INFO VMI,
TBL_POINTS_AND_CYCLES TP
WHERE VMI.START_INLET_TEMP=TP.TEMP1
AND VMI.START_OUTLET_TEMP=TP.TEMP2
AND VMI.TIME_FORMATTED=CONVERT(DATETIME, TP.DATE, 101)
What you can tell, what really matters for me in the second table (TBL_POINTS_AND_CYCLES) is the field "TYPE".
What do I need help with:
I need to return everything from VW_MAIN_INFO and TYPE (from TBL_POINTS_AND_CYCLES).
However, if I cannot find a type in TBL_POINTS_AND_CYCLES, I should return a specific value (for example, "EMPTY" or null).
How can I achieve? Is the best path to use "minus" like this?
Finally, my problem with minus is that I don't have the same structure in both tables.
Any help? Ideas?
Thank you.
SELECT TP.TYPE ,
VMI.*
FROM VW_MAIN_INFO VMI
LEFT JOIN TBL_POINTS_AND_CYCLES TP ON VMI.START_INLET_TEMP = TP.TEMP1
AND VMI.START_OUTLET_TEMP = TP.TEMP2
AND VMI.TIME_FORMATTED = CONVERT(DATETIME, TP.DATE, 101);

SQL Server 2012 Filtering Results Based on One Table and Appending Info

I've been trying to search for a similar query on stackoverflow to modify to get what I need but I can't seem to get it right. I hope someone here can help.
I have two tables located in two different databases. Both databases are configured on the same server. Table 1 called 'DiscreteLive' and located in Database 'Runtime'. Table 2 is called 'v_DiscreteHistory' and located in Database 'WWALMDB'.
They have the following fields
DiscreteLive
Tagname (type String)
Value (type Integer --> can only ever be 1 or 0)
'v_DiscreteHistory'
Tagname (type String)
Value (type String --> can only ever be true of false)
EventStamp (type datetime)
Description (type String)
The 'DiscreteLive' table can only ever have one unique tagname line. An external software will overwrite to each tagname's corresponding Value field. It's basically showing the live values of the system. Example shown below. For example, you would never find Device1.Commfail twice in this table.
Device1.Commfail
Device1.Auto
Device1.Man
Device2.Commfail
Device2.Auto
Device2.Man
Device3.Commfail
Device3.Auto
Device3.Man
Device4.commfail
Device4.Auto
Device4.Man
Device5.Commfail
Device5.Auto
Device5.Man
etc.
The 'v_DiscreteHistory' table is the history of the specific tag. There can be multiple entries of the same tag along with its Description and EventStamp (Time the even happened).
What I'm trying to do is to filter out the 'DiscreteLive' table to show only the tag values where the tagname is a %.CommFail and the Value is 1. Then I would like to take the result of that initial query and attach the latest EventStamp and Description for those tags in the initial query from 'v_DiscreteHistory'.
Not sure if this can be done. Let me know if you need more clarification.
SQL Server: This might be what you are looking for
SELECT
D.TagName
,D.Value
,V.Tagname
,V.Value,V.EventStamp
,V.Description
,MAX(V.EventStamp) AS 'LatestDate'
FROM
SERVER.Runtime.dbo.DiscreteHistory D
INNER JOIN
SERVER.WWALMDB.dbo.v_DiscreteHistory V
ON
D.Tagname = V.Tagname
WHERE
D.Value = 1
AND
V.Value LIKE '%.CommFail'
GROUP BY
D.TagName
,D.Value
,V.Tagname
,V.Value,V.EventStamp
,V.Description

When same BELNR value, report only gets info from the first line

I have a report that is getting info from bsis, bsas, bsid, bsad, vbrk, bkpf and bset. the problem is when there are two invoices with the same number, the report copies the info from the first line to the second. So, if invoice no.4100111596 has a tax total of 2.140,20 in the first line, the same invoice number has the same tax toal in the second, but the value is 40.140,64.
What can I do? do I have to use the buzei field some where?
Heres de code:
SELECT SINGLE kbetr fwste hwste
FROM bset
INTO (<fs_main>-kbetr, <fs_main>-fwste, <fs_main>-hwste)
WHERE belnr = <fs_main>-belnr
AND bukrs IN bukrs
AND gjahr IN gjahr.
I tried getting the buzei and it still gives me the same line twice.
Here's the code, that I do before the code above:
SELECT c~kunnr a~belnr d~spart c~bldat c~waers c~wrbtr a~hwaer c~dmbtr c~buzei
INTO CORRESPONDING FIELDS OF TABLE lt_data
FROM ( ( ( bsis AS f
INNER JOIN bkpf AS a ON f~belnr = a~belnr )
INNER JOIN bsid AS c ON c~belnr = a~belnr )
INNER JOIN vbrk AS d ON d~vbeln = c~belnr )
WHERE a~gjahr IN gjahr
AND a~bukrs IN bukrs
AND a~blart = 'R1'
AND f~hkont = '0034930020'
AND ( c~mwskz = 'L0' OR c~mwskz = 'L1' OR c~mwskz = 'L2' ).
-You have to use all key fields on your condition part of your "SELECT" in order to get a "SINGLE" line. Otherwise table might not return you a single line but you'll get the first line.
-So you have to use BUZEI field too on your condition in your select.
Hope it was helpful
Talha
Found the problem. I was doing the selection os the wrong fields i the wrong table. BKPF only gave me one line and BSET gave me two lines. So, I change the tables that was getting the fields from and it work just fine. Thank you.