How to fix data type conversion SQL error in ABAP when using VBRK and VBRP - sql

I want to get the sum of quantities billed in a fixed period and a defined organisation but It either prints 0 or I get an SQL error as in the screenshot.
I used tables VBRK for Organisation and data and VBRP for quantity and currency.
Tables: VBRK,
lips,
VBRP.
TYPES: Begin of itab5,
VKORG TYPE VBRK-VKORG,
FKDAT TYPE VBRK-FKDAT,
ARKTX TYPE LIPS-ARKTX,
FKIMG TYPE VBRP-FKIMG,
VRKME TYPE VBRP-VRKME,
End of itab5.
DATA: wa_ma5 TYPE itab5,
it_ma5 TYPE STANDARD TABLE OF itab5,
quan TYPE VBRP-FKIMG,
curr TYPE vbrp-vrkme.
SELECT-OPTIONS: DATE FOR VBRK-FKDAT.
SELECT-OPTIONS: Organ FOR VBRK-VKORG.
APPEND date.
APPEND Organ.
START-OF-SELECTION.
SELECT VKORG FKDAT FKIMG VRKME FROM VBRK
inner JOIN VBRP ON VBRP~netwr = VBRK~WAERK
INTO CORRESPONDING FIELDS OF TABLE it_ma5
WHERE VBRK~FKDAT IN DATE AND VBRK~VKORG IN Organ.
END-OF-SELECTION.
quan = 0.
LOOP AT it_ma5 INTO wa_ma5.
* if sy-subrc = 0.
quan = quan + wa_ma5-fkimg.
* endif.
ENDLOOP.
WRITE: 'the quantity', quan.

This is not that complicated.
You are doing join between the two tables using VBRP-NETWR and VBRK-WAERK which doesn't make sense (and they are different data types).
VBRK is linked with VBRP by VBELN field (one is billing header and one billing items), so the correct JOIN is:
START-OF-SELECTION.
SELECT vkorg fkdat fkimg vrkme
FROM vbrk
INNER JOIN vbrp
ON vbrp~vbeln = vbrk~vbeln
INTO CORRESPONDING FIELDS OF TABLE it_ma5
WHERE vbrk~fkdat IN date
AND vbrk~vkorg IN organ.

Related

SD Invoice with amount 0 EUR not to be transmitted to FI

I am trying to fix a certain already developed function with the goal that the SD Invoice with amount 0 EUR should not be transmitted to FI. As I understood, the below code is used to select the data from FI and SD:
* select order-related invoices
SELECT * FROM vbfa AS v INTO TABLE gt_vbfa_inv
FOR ALL ENTRIES IN gt_vbak
WHERE vbelv = gt_vbak-vbeln
AND vbtyp_n IN ('M', 'O', 'P', '5', '6')
AND stufe = '00'
AND NOT EXISTS ( SELECT * FROM vbfa
WHERE vbelv = v~vbeln
AND posnv = v~posnn
AND vbtyp_n IN ('N', 'S')
AND stufe = '00' ) .
IF sy-subrc = 0.
* select invoice head status
SELECT DISTINCT * FROM vbuk APPENDING TABLE gt_vbuk_inv
FOR ALL ENTRIES IN gt_vbfa_inv
WHERE vbeln = gt_vbfa_inv-vbeln. "#EC CI_SUBRC
ENDIF.
SORT gt_vbuk_inv BY vbeln.
DELETE ADJACENT DUPLICATES FROM gt_vbuk_inv COMPARING vbeln.
IF me->gv_items = abap_true AND gt_vbuk_inv IS NOT INITIAL.
SELECT * FROM vbrp INTO TABLE gt_vbrp
FOR ALL ENTRIES IN gt_vbuk_inv
WHERE vbeln = gt_vbuk_inv-vbeln. "#EC CI_SUBRC
ENDIF.
As far as I can understand from the above written code, is that the table VBFA is used to get the data for FI, while the table VBRP is used to get the data for SD. What I want to achieve is that when the invoice number does not have a FI document, then the invoice number will be empty.
If the tables BKPF(for the FI) and VBRK(for the SD) would be used, then I could have tried the relation:
vbrk-xblnr=bkpf-xblnr.
However, those tables are not used in the function. May I please ask you, how can I fix the code so that when the invoice number does not have a FI document, thus the invoices with a value of 0 EUR will not generate an FI document, then the invoice number will be empty.
Thank you all in advance!
Since the goal is
the SD Invoice with amount 0 EUR should not be transmitted to FI
I suppose your code is in some user-exit or standard program modification when releasing the SD invoice to Accounting. If so, the BKPF is not created yet and there's no reason in selecting it.
The select from VBFA is not extracting data from FI. Starting from the Sales Order it is extracting the following SD documents (first document flow level only)
M Invoice
N Invoice Cancellation
P Debit Memo
5 Intercompany Invoice
6 Intercompany Credit Memo
And excluding those invoices that have a subsequent cancellation
N Invoice Cancellation
S Credit Memo Cancellation
Those documents can be found in VBRK table (SD invoice header) with the following select
SELECT DISTINCT * FROM vbrk APPENDING TABLE gt_vbrk
FOR ALL ENTRIES IN gt_vbfa_inv
WHERE vbeln = gt_vbfa_inv-vbeln.
Btw: I don't know the reason for the VBUK select since you're not using any document status information
If you're asking for the SD invoices with zero amount with the purpose to not release them to accounting (since otherwise they would produce an error in FI) you don't have to select BKPF but check VBRK-NETWR = 0 for every entry in gt_vbrk table

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

Migration of KNKK select query to S/4HANA?

I have the following SELECT in one of my programs, and I need to modify it due a migration to SAP S/4HANA.
SELECT kunnr klimk
FROM knkk UP TO 1 ROWS
INTO (knkk-kunnr,knkk-klimk)
WHERE kunnr = p_kunnr.
How can I modify that for it become valid for S4HANA?
KNKK-KLIMK I can replace with UKMBP_CMS_SGM-CREDIT_LIMIT but what about KNKK-KUNNR?
Thanks in advance!
Old Coding:
CLEAR knkk.
SELECT kunnr klimk
FROM knkk UP TO 1 ROWS
INTO (knkk-kunnr,knkk-klimk)
WHERE kunnr = p_kunnr.
New Coding:
DATA: z_bp TYPE bu_partner_guid.
SELECT partner_guid
FROM cvi_cust_link UP TO 1 ROWS
INTO z_bp
WHERE customer = p_kunnr.
ENDSELECT.
IF z_bp NE ukmbp_cms_sgm-partner.
CLEAR ukmbp_cms_sgm.
SELECT partner credit_sgmnt
FROM ukmbp_cms_sgm UP TO 1 ROWS
INTO ( ukmbp_cms_sgm-partner, ukmbp_cms_sgm-credit_sgmnt )
WHERE partner = z_bp.
ENDIF.

SAP query. Retrieve values basing on input on selection screen

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

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.