Not condition dates also visible in output - abap

My requirement is that I should not display the data on a specific date.
Given the select query below it should not display the dates which are present in not condition but in my output I could still see the dates which are present in not condition.
REPORT Z_SANJAY_INTERNALTABLES_06.
Tables : EKKO.
Select-options : S_dates for ekko-bedat .
Data : Begin of WA_ekko ,
WA_EBELN type ekko-ebeln ,
WA_bedat type ekko-bedat ,
WA_lifnr type ekko-lifnr ,
WA_bukrs type ekko-bukrs ,
end of WA_ekko .
Data : IT_ekko like table of WA_ekko .
select ebeln bedat lifnr bukrs from ekko into table IT_ekko where bedat in S_dates and bedat <> '02.11.2000' .
Loop at IT_ekko into WA_ekko .
write :/ WA_ekko-WA_EBELN ,
WA_ekko-WA_LIFNR ,
WA_EKKO-WA_BUKRS ,
WA_ekko-WA_bedat .
endloop.

Related

Want to show all lines items in result list instead of the last line item

I have a SELECT query with the aggregate function group by. But my program shows only the last line items. I want to show all the line items.
Example of expected result:
{"numOfRec":"50",
"shipmentsDetails":[
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"OE8002L18",
"batchCode":"0000029927",
"qty":"108.000" } ,
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"OE8407L18",
"batchCode":"0000029928",
"qty":"36.000" } ,
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"SUE9433G1",
"batchCode":"0000029923",
"qty":"180.000" }]}
Example of actual result (in i_output):
{"numOfRec":"1",
"shipmentsDetails":[
{"orderNum":"1000101760",
"deliveryOrderNum":"0085099889",
"prodCode":"UE9101G5",
"batchCode":"20200101E",
"qty":"10.000" }]}
(although there are many line items, only the last line item is showing)
Here's my code:
IF NOT i_vttk IS INITIAL.
SELECT tknum
tpnum
vbeln
FROM vttp
INTO TABLE i_vttp
FOR ALL ENTRIES IN i_vttk
WHERE tknum = i_vttk-tknum.
IF sy-subrc EQ 0.
SORT i_vttp BY tknum tpnum.
ENDIF.
IF NOT i_vttp is INITIAL.
LOOP AT i_vttp INTO wa_vttp.
SELECT vbeln
matnr
charg
SUM( lgmng ) as lgmng
meins
FROM lips
INTO TABLE i_lips
WHERE vbeln = wa_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln matnr charg meins.
IF sy-subrc EQ 0.
"APPEND i_lips.
"CLEAR i_lips.
SORT i_lips BY vbeln matnr.
ENDIF.
ENDLOOP.
ENDIF.
LOOP AT i_lips INTO wa_lips.
READ TABLE i_vttp
INTO wa_vttp
WITH KEY vbeln = wa_lips-vbeln.
IF sy-subrc = 0.
wa_output-tknum = wa_vttp-tknum.
wa_output-vbeln = wa_lips-vbeln. " Added Delivery
wa_output-matnr = wa_lips-matnr.
wa_output-charg = wa_lips-charg.
wa_output-lgmng = wa_lips-lgmng.
ENDIF.
APPEND wa_output TO i_output.
CLEAR: wa_vttp, wa_lips, wa_output.
l_count = l_count + 1.
ENDLOOP.
Note that ideally, I would like to do the following query to sum up the total quantity (field lgmng), but ABAP doesn't allow to use group by with for all entries:
SELECT vbeln matnr charg SUM( lgmng ) as lgmng meins
FROM lips
INTO TABLE i_lips
FOR ALL ENTRIES IN i_vttp
WHERE vbeln = i_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln matnr charg meins.
Any help would be appreciated. Thank you.
There are several problems with your code:
A select in a loop is generally a bad idea since it increases database accesses(which you really don't want ) . Consider other options like joins.
The reason why you get only the last line is that in every loop pass( in the loop where you do a select ) the internal table i_lips gets overwritten and hence on exiting the loop, you get only the last selected entries. To solve this you could modify your select query as follows:
SELECT vbeln
matnr
charg
SUM( lgmng ) as lgmng
meins
FROM lips
APPENDING TABLE i_lips
WHERE vbeln = wa_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln, matnr, charg, meins.

Value in dropdown box isn't refreshed

I have a dynpro screen with two input fields:
The sales order n°
The sales order line n° (in a dropdown list)
My problem is that the sales order line isn't refreshed after a different sales order n° is input. However the other output fields relating to the sales order line are properly refreshed with the expected data.
Program behavior:
"Document vente" is "Sales order". "Poste" is "Line number".
From this screen, If I request sales order number 1, the order line 10 remains active and shows up in the dropdown list, despite order number 1 not having a line number 10. The other output fields are updated with the data of line 20. If I pick line orders 20, 30 or 70, the value 10 disappears from the list.
The dynpro screen fields are named as their corresponding fields from the VBAK and VBAP tables, so that their values are copied automatically from one to another.
The code followed by the comment "Set order line to first one in the order" doesn't seem to work. I expect it to replace the value of the line number field with the first line number in the new order.
The code:
MODULE REFRESH_ALL_FIELDS INPUT.
DATA temp_vbeln TYPE VBAK-VBELN.
temp_vbeln = VBAK-VBELN.
CLEAR: VBAK, VBAP.
SELECT VBELN KUNNR BSTNK NETWR WAERK
FROM VBAK
INTO CORRESPONDING FIELDS OF VBAK
WHERE VBAK~VBELN = temp_vbeln.
ENDSELECT.
" Fill dropdown list with order line numbers.
TYPE-POOLS VRM.
DATA it_posnr TYPE VRM_VALUES.
REFRESH it_posnr.
SELECT POSNR
FROM VBAP
INTO TABLE it_posnr
WHERE VBAP~VBELN = VBAK-VBELN.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
ID = 'VBAP-POSNR'
VALUES = it_posnr
* EXCEPTIONS
* ID_ILLEGAL_NAME = 1
* OTHERS = 2
.
IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
" Set order line number as first in the order.
SELECT SINGLE POSNR
FROM VBAP
INTO VBAP-POSNR
WHERE VBAP~VBELN = VBAK-VBELN.
PERFORM REFRESH_ITEM_FIELDS.
ENDMODULE. " REFRESH_ALL_FIELDS INPUT
MODULE REFRESH_ITEM_FIELDS INPUT.
PERFORM REFRESH_ITEM_FIELDS.
ENDMODULE. " REFRESH_ITEM_FIELDS INPUT
FORM REFRESH_ITEM_FIELDS .
SELECT SINGLE MATNR ARKTX KWMENG
FROM VBAP
INTO CORRESPONDING FIELDS OF VBAP
WHERE VBAP~VBELN = VBAK-VBELN
AND VBAP~POSNR = VBAP-POSNR.
ENDFORM. " REFRESH_ITEM_FIELDS
Flow logic:
PROCESS BEFORE OUTPUT.
PROCESS AFTER INPUT.
FIELD VBAK-VBELN MODULE REFRESH_ALL_FIELDS ON REQUEST.
FIELD VBAP-POSNR MODULE REFRESH_ITEM_FIELDS ON REQUEST.
How can I fix this ?
The dynpro flow logic statement FIELD vbak-vbeln MODULE ... ON REQUEST permits only to change "easily" the value of the screen field VBAK-VBELN, i.e. the value of the global variable VBAK-VBELN will be "transported" in both directions, from the screen to the ABAP program, and vice versa.
If you want to change another screen field, like VBAP-POSNR, you must call the function module DYNP_VALUES_UPDATE:
TYPES tt_dynpread TYPE STANDARD TABLE OF dynpread WITH DEFAULT KEY.
DATA(dynpfields) = VALUE ty_dynpread_s(
( fieldname = 'VBAP-POSNR'
fieldvalue = vbap-posnr ) ).
CALL FUNCTION 'DYNP_VALUES_UPDATE'
EXPORTING
dyname = sy-repid
dynumb = sy-dynnr
TABLES
dynpfields = dynpfields
EXCEPTIONS
OTHERS = 8.
Another solution is to declare a "chain" of fields, you may then change those fields directly inside the module without calling DYNP_VALUES_UPDATE:
CHAIN.
FIELD: vbak-vbeln, vbap-posnr.
MODULE ... ON REQUEST.
ENDCHAIN.
But that would require to execute the same code for both fields.
Here is the way how you can do it without creating a dynpro, just with pure selection screen:
TYPES: BEGIN OF ty_order,
vbeln TYPE vbak-vbeln,
erdat TYPE vbak-erdat,
netwr TYPE vbak-netwr,
kunnr TYPE vbak-kunnr,
END OF ty_order,
BEGIN OF ty_pos,
vbeln TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
matnr TYPE vbap-matnr,
arktx TYPE vbap-arktx,
kwmeng TYPE vbap-kwmeng,
END OF ty_pos.
DATA: i_order TYPE TABLE OF ty_order WITH EMPTY KEY,
i_pos TYPE TABLE OF ty_pos WITH EMPTY KEY,
i_aux TYPE TABLE OF ty_pos WITH EMPTY KEY,
list TYPE vrm_values.
PARAMETERS: order TYPE vbak-vbeln AS LISTBOX VISIBLE LENGTH 80 USER-COMMAND ord,
position TYPE vbap-posnr AS LISTBOX VISIBLE LENGTH 80 USER-COMMAND art.
INITIALIZATION.
SELECT vbeln erdat netwr kunnr
FROM vbak AS ak
INTO TABLE i_order
WHERE vbeln = ANY ( SELECT vbeln FROM vbap WHERE vbeln = ak~vbeln GROUP BY vbeln HAVING COUNT( * ) > 1 ).
IF i_order IS NOT INITIAL.
SELECT vbeln posnr matnr arktx kwmeng
FROM vbap
INTO TABLE i_pos
FOR ALL ENTRIES IN i_order
WHERE vbeln = i_order-vbeln.
ENDIF.
LOOP AT i_order INTO DATA(wa).
APPEND VALUE vrm_value( key = |{ wa-vbeln ALPHA = OUT }| text = |{ wa-erdat DATE = USER }| ) TO list.
ENDLOOP.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'order'
values = list.
CLEAR list.
AT SELECTION-SCREEN.
CHECK sy-ucomm = 'ORD'.
CLEAR position.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'position'
values = list.
CLEAR list.
AT SELECTION-SCREEN ON order.
CHECK sy-ucomm = 'ORD' AND order IS NOT INITIAL.
i_aux = VALUE #( FOR pos IN i_pos WHERE ( vbeln = |{ order ALPHA = IN }| ) ( pos ) ).
LOOP AT i_aux INTO DATA(aux).
APPEND VALUE vrm_value( key = |{ aux-posnr ALPHA = OUT }| text = |{ aux-matnr ALPHA = OUT }| ) TO list.
ENDLOOP.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'position'
values = list.
After each selection in order dropdown all the order-related data will be collected to i_aux table which you can use for populating output fields.
The closest solution was to update a working area in the PAI, and update the actual screen fields in the PBO, from the values of the WA.

List of BUKRS which the current user is allowed to see

Is there a way to get a list of all BUKRS which the current user is allowed to see?
I want to use this list as a filter in open sql. Imagine the result of the method I search stored the result in bk_list. Then I could use bk_list like this:
SELECT * FROM some_table WHERE bukrs IN bk_list
Another way to do it, based on the class CL_AUTH_OBJECTS_TO_SQL (officially supported, as of ABAP 7.50, as explained in the documentation of AUTHORITY-CHECK), here the program reads the flights from the read-authorized airline carriers :
DATA(authsql) = cl_auth_objects_to_sql=>create_for_open_sql( ).
authsql->add_authorization_object( EXPORTING
iv_authorization_object = 'S_CARRID'
it_activities = VALUE #( ( auth_field = 'ACTVT' value = '03' ) )
it_field_mapping = VALUE #(
( auth_field = 'CARRID'
view_field = VALUE #( table_ddic_name = 'SFLIGHT' field_name = 'CARRID' ) ) ) ).
DATA(where) = authsql->get_sql_condition( ).
SELECT * FROM sflight INTO TABLE #data(sflights) WHERE (where).
I am afraid you can do it one by one only. Roughly:
SELECT bukrs
INTO TABLE #DATA(lt_t001)
FROM t001
WHERE ... . "Selection critera, if necessary
LOOP AT lt_t001
ASSIGNING FIELD-SYMBOL(<ls_t001>).
DATA(lv_tabix) = sy-tabix.
AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
ID 'BUKRS' FIELD <ls_t001>-bukrs
ID 'ACTVT' FIELD '03'. "Here you need the proper activity (display '03' /change '02' / etc.)
IF sy-subrc <> 0. "Auth check failed
DELETE lt_t001 INDEX lv_tabix.
ENDIF.
ENDLOOP.
At the end lt_t001 contains only the company codes, for which the user has authorization.

How can I sum up or collect the data on the same field?

Hi ABAP users I would like to ask if what process I can make to COLLECT the data on the same field? all I want to do is to sum up or collect the data in dmbtr that belongs to same date, (date field monat) (werks to plant codes)
it_zfi_vbrp_bseg_1-num3 = it_zfi_vbrp_bseg_1-werks.
it_zfi_vbrp_bseg_1-num2 = it_zfi_vbrp_bseg_1-dmbtr.
COLLECT it_zfi_vbrp_bseg_1.
DELETE ADJACENT DUPLICATES FROM it_zfi_vbrp_bseg_1 COMPARING ALL FIELDS.
Sort it_zfi_vbrp_bseg_1 by werks.
LOOP AT it_zfi_vbrp_bseg_1 into wa_zfi_vbrp_bseg_1 WHERE monat = '01'.
IF wa_zfi_vbrp_bseg_1-werks EQ '4030'.
WRITE:/, AT pos wa_zfi_vbrp_bseg_1-dmbtr.
ENDIF.
ENDLOOP.
Any configuration in my codes guys?
Suppose, you already extended standard bseg table with monat field, then you should do like this:
TYPES: BEGIN OF ty_zfi_vbrp_bseg_1,
werks TYPE bseg-werks,
monat TYPE monat,
dmbtr TYPE bseg-dmbtr,
END OF ty_zfi_vbrp_bseg_1.
DATA: it_zfi_vbrp_bseg_1 TYPE TABLE OF ty_zfi_vbrp_bseg_1,
is_zfi_vbrp_bseg_1 TYPE ty_zfi_vbrp_bseg_1.
SELECT werks, monat, dmbtr
INTO TABLE #DATA(lt_bseg)
FROM bseg
WHERE werks = '4030'.
* summation of months
LOOP AT lt_bseg ASSIGNING FIELD-SYMBOL(<fs_line>).
CLEAR: is_zfi_vbrp_bseg_1.
MOVE-CORRESPONDING <fs_line> TO is_zfi_vbrp_bseg_1.
COLLECT is_zfi_vbrp_bseg_1 INTO it_zfi_vbrp_bseg_1.
ENDLOOP.
* output the results
LOOP AT it_zfi_vbrp_bseg_1 ASSIGNING FIELD-SYMBOL(<zfi_line>).
IF <zfi_line>-werks EQ '4030'.
WRITE: / <zfi_line>-werks, <zfi_line>-monat, <zfi_line>-dmbtr.
ENDIF.
ENDLOOP.
Couple of notes to your incorrect code:
COLLECT doesn't work like single statement and should be executed in loop.
To sum with COLLECT statement you should declare work area so that all non-key fields would be numeric. Key fields (even if it is implicit key) can be of any type, as opposed to what Ray said. N type is also OK.
DELETE ADJACENT DUPLICATES is redundant here, because after COLLECT (which makes summation by primary key) you won't have any dups.
This all comes down to how you define your internal table it_zfi_vbrp_bseg_1
For COLLECT to work, you need to define it with character type keys followed by packed field types:
data: begin of it_zfi_vbrp_bseg_1 occurs 0,
werks type werks,
month(2) type c,
dmbtr type dmbtr,
end of it_zfi_vbrp_bseg_1.
That will work.
This will not:
data: begin of it_zfi_vbrp_bseg_1 occurs 0.
include structure vbrp.
data: monat type monat,
dmbtr type dmbtr,
end of it_zfi_vbrp_bseg.
Read the help on COLLECT and define your summary table accordingly.

using multiple parameters in append query in Access 2010

I have been trying to get an append query to work but I keep getting an error stating that 0 rows are being appended whenever I use more than 1 parameter in the query. This is for a
The table in question has 1 PK which is a GUID [which is generating values with newid()] and one required field (Historical) which I am explictly defining in the query.
INSERT INTO dbo_sales_quotas ( salesrep_id
, [year]
, territory_id
, sales_quota
, profit_quota
, product_super_group_uid
, product_super_group_desc
, class_9
, Historical
, sales_quotas_UID )
SELECT dbo_sales_quotas.salesrep_id
, dbo_sales_quotas.Year
, dbo_sales_quotas.territory_id
, dbo_sales_quotas.sales_quota
, dbo_sales_quotas.profit_quota
, dbo_sales_quotas.product_super_group_uid
, dbo_sales_quotas.product_super_group_desc
, dbo_sales_quotas.class_9
, dbo_sales_quotas.Historical
, dbo_sales_quotas.sales_quotas_UID
FROM dbo_sales_quotas
WHERE (((dbo_sales_quotas.salesrep_id)=[cboSalesRepID])
AND ((dbo_sales_quotas.Year)=[txtYear])
AND ((dbo_sales_quotas.territory_id)=[txtTerritoryID])
AND ((dbo_sales_quotas.sales_quota)=[txtSalesQuota])
AND ((dbo_sales_quotas.profit_quota)=[txtProfitQuota])
AND ((dbo_sales_quotas.product_super_group_uid)=[cboProdSuperGroup])
AND ((dbo_sales_quotas.product_super_group_desc)=[txtProductSuperGroupDesc])
AND ((dbo_sales_quotas.class_9)=[cboClass9])
AND ((dbo_sales_quotas.Historical)='No')
AND ((dbo_sales_quotas.sales_quotas_UID)='newid()'));
Even if I assign specific values, I still get a 0 rows error except when I reduce the number of parameters to 1 (which it then works perfectly regardless of which parameter) I have verified that the parameters have the correct formats.
Can anyone tell me what I'm doing wrong?
Break out the SELECT part of your query and examine it separately. I'll suggest a simplified version which may be easier to study ...
SELECT
dsq.salesrep_id,
dsq.Year,
dsq.territory_id,
dsq.sales_quota,
dsq.profit_quota,
dsq.product_super_group_uid,
dsq.product_super_group_desc,
dsq.class_9,
dsq.Historical,
dsq.sales_quotas_UID
FROM dbo_sales_quotas AS dsq
WHERE
dsq.salesrep_id=[cboSalesRepID]
AND dsq.Year=[txtYear]
AND dsq.territory_id=[txtTerritoryID]
AND dsq.sales_quota=[txtSalesQuota]
AND dsq.profit_quota=[txtProfitQuota]
AND dsq.product_super_group_uid=[cboProdSuperGroup]
AND dsq.product_super_group_desc=[txtProductSuperGroupDesc]
AND dsq.class_9=[cboClass9]
AND dsq.Historical='No'
AND dsq.sales_quotas_UID='newid()';
I wonder about the last 2 conditions in the WHERE clause. Is the Historical field type bit instead of text? Does the string 'newid()' match sales_quotas_UID in any rows in the table?