DTP routine to find timestamp range - abap

I am working on a DTP filter routine for a timestamp field in the format of YYYYMMDDhhmmss. I am trying to declare the range as ({timestamp 3 months ago} to {current timestamp}). I am very new to ABAP and basically have the code set up right now so it doesn't have any syntax errors. I am currently having trouble getting the correct timestamp to be filled when I assign it to "l_ts".
*$*$ begin of routine - insert your code only below this line *-*
BREAK-POINT.
DATA: l_idx LIKE sy-tabix,
l_ts TYPE rstimestmp,
l_ts2 TYPE rstimestmp.
READ TABLE l_t_range WITH KEY
fieldname = 'TIMESTAMP'.
l_idx = sy-tabix.
* Capture the Current Date
l_ts = sy-datlo + sy-timlo.
l_ts2 = ( sy-datlo + sy-timlo ) - 93.
IF l_idx <> 0.
* fill the Selection table.
l_t_range-low = l_ts.
l_t_range-sign = 'I'.
l_t_range-option = 'BT'.
l_t_range-high = l_ts2.
MODIFY l_t_range INDEX l_idx.
ELSE.
* fill the Selection table.
l_t_range-fieldname = 'TIMESTAMP'.
l_t_range-low = l_ts.
l_t_range-high = l_ts2.
l_t_range-sign = 'I'.
l_t_range-option = 'BT'.
APPEND l_t_range.
ENDIF.
p_subrc = 0.
*$*$ end of routine - insert your code only before this line *-*

You're mixing up timestamps and discrete date and time calculations - won't work this way. What you'll really want is probably something like this:
DATA: l_date TYPE d,
l_time TYPE t,
l_ts TYPE rstimestmp.
FIELD-SYMBOLS: <ls_param> LIKE LINE OF l_t_range.
* ensure that the parameter exists
READ TABLE l_t_range ASSIGNING <ls_param> WITH KEY fieldname = 'TIMESTAMP'.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO l_t_range ASSIGNING <ls_param>.
<ls_param>-fieldname = 'TIMESTAMP'.
ENDIF.
<ls_param>-sign = 'I'.
<ls_param>-option = 'BT'.
* "from" date = three months ago, more or less - probably the start of the day?
l_date = sy-datlo - 93.
l_time = '000000'. " or sy-timlo.
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_ts TIME ZONE sy-zonlo.
<ls_param>-low = l_ts.
* "to" date = today - probably the end of the day?
l_date = sy-datlo.
l_time = '235959'. " or sy-timlo.
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_ts TIME ZONE sy-zonlo.
<ls_param>-high = l_ts.

Related

Enhance performance of ABAP report when using OpenSQL query and function call

I have an issue with my ABAP report for it being very slow and taking a long time to complete.
My original report had a query to MARA to get all materials into an iTab, loop over it and then query additional tables for each material and store the necessary data and a function call to READ_TEXT in an output iTab.
Since this process takes very long to compete I changed the code to rely more on the database to handle data access instead of making queries for additionoal data each at a time. But still the time to complete is very long for the amount of data to be fetched.
Current code looks like this
report z_test_report.
types:
begin of _output,
matnr type mara-matnr,
text01 type c length 40,
text02 type c length 40,
ntgew type mara-ntgew,
matkl type mara-matkl,
ean11 type mara-ean11,
preis type p length 6 decimals 2,
bstd type mbew-lbkum,
laeng type marm-laeng,
breit type marm-breit,
hoehe type marm-hoehe,
volum type marm-volum,
end of _output,
t_output type _output.
data:
gt_output type table of t_output,
gs_output like line of gt_output,
gr_table type ref to cl_salv_table,
gr_funct type ref to cl_salv_functions,
gr_columns type ref to cl_salv_columns_table,
gr_column type ref to cl_salv_column.
selection-screen begin of block b01 with frame.
parameters: pa_date type d obligatory.
parameters: pa_kschl type t685-kschl obligatory.
parameters: pa_pltyp type t189-pltyp obligatory.
selection-screen end of block b01.
start-of-selection.
select
m~matnr,
m~ntgew,
m~matkl,
m~ean11,
t~maktx,
b~lbkum,
l~laeng,
l~breit,
l~hoehe,
l~volum
from
mara as m
left join
makt as t
on
m~matnr = t~matnr
and
t~spras = 'D'
left join
mbew as b
on
b~matnr = m~matnr
and
b~bwkey = '1100'
left join
marm as l
on
l~matnr = m~matnr
and
l~meinh = m~meins
into
#data(wa_daten)
order by
m~matnr.
gs_output = corresponding #( wa_daten ).
select single
*
from
a908
where
a908~kappl = 'V'
and
a908~kschl = #pa_kschl
and
a908~vkorg = '1100'
and
a908~pltyp = #pa_pltyp
and
a908~matnr = #wa_daten-matnr
and
a908~datab < #sy-datum
and
a908~datbi > #sy-datum
into
#data(gs_a908).
if ( sy-subrc = 0 ).
select single
*
from
konp
where
konp~knumh = #gs_a908-knumh
into
#data(gs_knop).
if ( sy-subrc = 0 ).
gs_output-preis = gs_knop-kbetr.
endif.
endif.
data:
material_name like stxh-tdname,
textlines like tline occurs 0,
textline like line of textlines.
material_name = gs_output-matnr.
call function 'READ_TEXT'
exporting
id = 'GRUN'
language = 'D'
name = material_name
object = 'MATERIAL'
tables
lines = textlines
exceptions
id = 1
language = 2
name = 3
not_found = 4
object = 5
reference_check = 6
wrong_access_to_archive = 7
others = 8.
if ( sy-subrc = 0 ).
loop at textlines into textline.
concatenate gs_output-text02 textline-tdline into gs_output-text02.
endloop.
endif.
condense gs_output-text02.
append gs_output to gt_output.
endselect.
try.
cl_salv_table=>factory(
exporting
list_display = if_salv_c_bool_sap=>false
importing
r_salv_table = gr_table
changing
t_table = gt_output
).
catch cx_salv_msg.
endtry.
gr_funct = gr_table->get_functions( ).
gr_funct->set_all( abap_true ).
gr_table->display( ).
I think this code can be improved since reading 17k entries from MARA and joining them with the other tables should not be the bottle neck. Changing the old code to the current one reduced the runtime from about 45s down to 30s, removing the READ_TEXT only made the report take about 5s less.
If anyone has an idea it would be really appreciated. Or if anyone knows a tool to measure report performance to find out about bottle necks.

weekly event select into file with different filenames depending on the variables(MariaDB)

I've always been a silent reader here until now.
Now I would like to ask for your expertise and post my ver first question here.
I have to achieve the following task on a weekly basis in my MariaDB via Events:
Every Week on Saturday night at midnight, i want to save the results of a certain view in an excel file (xlsx). The filename should be variable depending on the site_id and the current timestamp.
After saving the results into the file I want to cleanup the DB Tables with another Event, but the previous event must be successfully finished as a condition to start the cleanup event.
e.g.filename:
viewname_[site_id]_timestamp.xlsx
overall_weekly _3_01082022.xlsx
This is what I have so far:
EVENT 1(saving results into file):
CREATE EVENT overall_weekly
ON SCHEDULE EVERY 1 WEEK
STARTS TRUNCATE(CURRENT_TIMESTAMP) + '00:00:00' HOUR_SECONDS
ON COMPLETION PRESERVE
ENABLE
DO
DECLARE #path = char
DECLARE #view = char
DECLARE #site_id = int(3)
DECLARE #timestamp = timestamp
DECLARE #filetype = char(5)
DECLARE #full_filename = char
SET #path = "/home/reports/"
SET #view = "overall_traffic_weekly"
SET #site_id = 3
SET #timestamp = current_timestamp
SET #filetype = ".xlsx"
SET #full_filename = CONCAT(#path,#view,#site_id,#timestamp,#filetype)
SELECT * FROM
(
SELECT 'Column_name_1','Column_name2', ...
UNION ALL
(
SELECT * FROM overall_weekly
WHERE site_id = 3
)
) resulting_set
INTO OUTFILE #full_filename
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '/n';
EVENT 2(cleanup):
EVENT 1 must be SUCCESSFULLY finished for event 2 to start.
IF event 1 finishes with errors, cleanup must not start.
CREATE EVENT cleanup
ON SCHEDULE EVERY 1 WEEK
STARTS TRUNCATE(CURRENT_TIMESTAMP) + '03:00:00' HOUR_SECONDS
ON COMPLETION PRESERVE
ENABLE
DO
TRUNCATE sourcetable1,
TRUNCATE Sourcetable2
;
Many thanks for reading.
Problem solved:
I used 2 tables instead and matched the 2 records together in a third table

How to check if the field TFK is maintained in the table

I am trying to display an error message for certain conditions. The goal is that from table COST, for an object number (that contains TEST + cost center + activity type), gjahr, value type(WRTTP) and version(VERSN), to check if for a certain fixed price per unit measure(TFK001-016) there is data in the table. Thus, if TFKXXX is not maintained in the COST table it will show an error message.
Now what I have done, is using a Call Function, to get the three number period for the TFK field, thus based on the exporting parameter of date/monmit/periv we will get the field of lv_poper which is the period. Then I have done a merge of TFK and lv_poper. Now what I want to do is to check whether a TFK001-016 field is maintained for the key parameters. I cannot do <ls_co_data>-lv_tfkxxx as it does not exist in the table COST. Does anyone have any idea on how can I check if the field TFK001-016 is maintained in the table COST?
CALL FUNCTION 'DATE_TO_PERIOD_CONVERT'
EXPORTING
i_date = lv_date
i_monmit = lv_monmit
i_periv = lv_periv
IMPORTING
e_buper = lv_poper
e_gjahr = lv_gjahr
EXCEPTIONS
input_false = 1
t009_notfound = 2
t009b_notfound = 3
OTHERS = 4.
lv_objnr = 'TEST' + <ls_co_data>-send_cctr + <ls_co_data>-acttype.
lv_tkfxxx = 'TKF' + lv_poper.
LOOP AT lt_cost ASSIGNING FIELD-SYMBOL(<ls_cost>)
WHERE objnr = lv_objnr
AND gjahr = lv_gjahr
AND wrttp = 1
AND versn = 0.
IF lv_tkfxxx IS NOT INITIAL. "The lv_tkfxxx should be checked in the cost table
lv_text = 'Not maintained in ' + lv_objnr + ' for the date ' + <ls_co_data>-postgdate.
ENDIF.
ENDLOOP.
Thank you all in advance!
...
LOOP AT lt_cost ASSIGNING FIELD-SYMBOL(<ls_cost>)
WHERE objnr = lv_objnr
AND gjahr = lv_gjahr
AND wrttp = 1
AND versn = 0.
ASSIGN COMPONENT lv_tkfxxx OF STRUCTURE <ls_cost> TO FIELD-SYMBOL(<v_tkfxxx>).
IF sy-subrc = 0 AND <v_tkfxxx> IS NOT INITIAL.
lv_text = 'Not maintained in ' + lv_objnr + ' for the date ' + <ls_co_data>-postgdate.
ENDIF.
ENDLOOP.

can't calculate a mean that excludes the current observation using .each block and sqlite3

I've done my best to strip down code to bare minimum and provided concise explanation of problem (I hope)
I have a db scheme as indicated below.
def a_method(info_hash)
...
db.execute2 "create table if not exists Table1(Id INTEGER PRIMARY KEY, Item TEXT, Amount FLOAT, Type TEXT, AvgInc FLOAT, AvgX FLOAT, Total FLOAT)"
...
end
This creates my schema. Once I populate the database, I run the following method which gives me the #{#total} value grouped by my Type column:
def get_total(info_hash)
...
get_amt = db.execute2 "SELECT sum(Amount) from Table1 WHERE Type = :Type", info_hash[:category]
puts "foo"
db.execute2 "UPDATE Table1 SET Total = :Total WHERE Type = :Type", get_amt[1][0], info_hash[:category]
#total=get_amt[1][0]
...
#total
end
I want to run the following method to compute an Item average in the event the item did not exist. Basically the impact each Item has on the Type average.
Please see the in code comment for where I think my logic is faulty
def method_excluding(info_hash)
...
get_num = db.execute2 "SELECT Amount from Table1 WHERE Type = :Type", info_hash[:category]
i = 0
get_num.each do |item|
#purpose of block to compute an average value for Type as if #{item} did not exist. So: the average value for Type EXLCUDING #{item}
if i == 1
#avgx = (#total - get_num[1][0]) / i
elsif i > 1
#avgx = (#total - get_num[i][0]) / (i - 1)
end
i+=1
db.execute2 "UPDATE Table1 SET AvgX = :AvgX WHERE Type = :Type", #avgx, info_hash[:category]
...
end
Please advise on how I can get to my desired outcome.

Create new Character variables from Date variable in sas

I have the following data set:
Date
May2005
May2005
May2005
June2005
.
.
.
May2006
May2006
May2006
.
.
.
May2007
May2007
May2007
I am trying to create three new variables such that Date05 = May2005 when Date1 = May2005, Date06 = May2006 when Date1 = May2006, and so on.
I thought of the following code, but it doesn't work:
data new;
set afinaldelaware;
if (Date1 EQ '01May2005'd or Date1 EQ '01May2006'd or Date1 EQ '01May2007'd)
then do;
Date05 = '01May2005';
Date06 = "01May2006';
Date07 = 'May2007';
end;
run;
Since your dates are formatted as mmyyy7. you don't know the exact date which is likely why your comparison fails. You can compare the month and year using the respective functions instead of date literals. Note that you're creating character variables not SAS date variables, which may be what you intend.
data new;
set afinaldelaware;
if (month(date1)=5 and year(date1) in (2005 2006 2007))
then do;
Date05 = '01May2005';
Date06 = "01May2006';
Date07 = 'May2007';
end;
run;