Select data within specific month in SELECT-OPTIONS - select

This ABAP code works but it works only once. I run this code with different parameters but result data does not change. How can I solve it?
PARAMETERS : S_MONTH LIKE ISELLIST-MONTH OBLIGATORY.
SELECT-OPTIONS : S_DATE FOR SY-DATUM.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR S_MONTH.
PERFORM GET_DATES.
FORM GET_DATES.
DATA: MONTH LIKE ISELLIST-MONTH,
FIRST_DAY LIKE SY-DATUM,
LAST_DAY LIKE SY-DATUM.
MONTH = SY-DATUM+0(6). "default
CALL FUNCTION 'POPUP_TO_SELECT_MONTH'
EXPORTING
ACTUAL_MONTH = MONTH
IMPORTING
SELECTED_MONTH = MONTH.
IF SY-SUBRC <> 0.
"put some message
ENDIF.
CONCATENATE MONTH '01' INTO FIRST_DAY.
CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
EXPORTING
DAY_IN = FIRST_DAY
IMPORTING
LAST_DAY_OF_MONTH = LAST_DAY.
IF SY-SUBRC <> 0.
"put some message
ENDIF.
S_DATE-LOW = FIRST_DAY.
S_DATE-HIGH = LAST_DAY.
S_DATE-SIGN = 'I'.
S_DATE-OPTION = 'BT'.
APPEND S_DATE.
S_MONTH = MONTH.
ENDFORM.

Add REFRESH S_DATE. before the APPEND S_DATE. You are now just appending every selection you make.

Related

PowerPoint: Add Date of Yesterday and Tomorrow to a Slide

I want to have a table on my PowerPoint (2016) slide which should look like this:
sysdate - 1
sysdate
sysdate + 1
02.09.2021
03.09.2021
04.09.2021
To keep the slides intuitive, the dates should be updated automatically.
By using Insert -> Text -> Date & Time I can add a field containing the current date for the center column.
How do I add a dynamic field for yesterday and tomorrow?
First, follow the steps here to name your table. After that, insert a module (Alt+F11, Insert - Module) and add this piece of code:
Sub SetTableHeaders()
Const SlideNo = 1
Const TableName = "TableName Here"
Dim MyTable As Table
Set MyTable = ActivePresentation.Slides(SlideNo).Shapes(TableName).Table
MyTable.Rows(1).Cells(1).Shape.TextFrame.TextRange.Text = Format(Now - 1, "yyyy-mm-dd")
MyTable.Rows(1).Cells(2).Shape.TextFrame.TextRange.Text = Format(Now, "yyyy-mm-dd")
MyTable.Rows(1).Cells(3).Shape.TextFrame.TextRange.Text = Format(Now + 1, "yyyy-mm-dd")
End Sub
Replace the SlideNo and TableName values with the right ones. Run it (F5) to set the headers.

selecting daily revised hourly values for a month

I have two queries
first one return latest Revision number for each date for a month
select max(a.wdcm_revision_no)
from wb_declared_capacity_master a, wb_declared_capacity_det_unit b
where a.wdcm_internal_id = b.wdcd_ref_id and b.wdcm_unit = 'HSY_Unit1' and to_char(a.wdcm_date,'MM YYYY')='08 2019' group by a.wdcm_date
And second query which returns all the data irrespective of any revision
select a1.wdcm_date, b1.wdcd_block_no, c1.wdcd_capacity, c1.wdcd_approval, a1.wdcm_revision_no
from wb_declared_capacity_master a1, wb_declared_capacity_det_unit b1, wb_declared_capacity_detail c1
where a1.wdcm_internal_id = b1.wdcd_ref_id and a1.wdcm_internal_id = c1.wdcd_ref_id and b1.wdcm_unit = 'HSY_Unit1' and to_char(a1.wdcm_date,'MM YYYY')='08 2019'and b1.wdcd_block_no = c1.wdcd_block_no
Now I want to pass each date's latest revision from first query in where condition of second query expecting to return all the values based on those latest revision number
You can combine then into 1 query. The 1st becoming a CTE which is then fed into the 2nd. I believe the following is close, but as you didn't actually indicate where you wanted to "pass in the result" I'm making assumption that seems likely, but it's still an assumption.
with latest (revision) as
-- first query
( select max(a.wdcm_revision_no)
from wb_declared_capacity_master a
, wb_declared_capacity_det_unit b
where a.wdcm_internal_id = b.wdcd_ref_id
and b.wdcm_unit = 'HSY_Unit1'
and to_char(a.wdcm_date,'MM YYYY')='08 2019'
group by a.wdcm_date
)
-- And second query which returns all the data irrespective of any revision
select a1.wdcm_date
, b1.wdcd_block_no
, c1.wdcd_capacity
, c1.wdcd_approval
, a1.wdcm_revision_no
from wb_declared_capacity_master a1
, wb_declared_capacity_det_unit b1
, wb_declared_capacity_detail c1
, latest
where a1.wdcm_internal_id = b1.wdcd_ref_id
and a1.wdcm_internal_id = c1.wdcd_ref_id
and b1.wdcm_unit = 'HSY_Unit1'
and to_char(a1.wdcm_date,'MM YYYY')='08 2019'
and b1.wdcd_block_no = c1.wdcd_block_no
and a1.wdcm_revision_no = latest.revision; ---- you didn't actually say where to "pass it in" this seems likely
I've kept the join format you used but you really should begin using the modern ANSI/ISO standard join format. (Modern meaning being in ONLY since 1992 or so).

SELECT with substring in ON clause?

I have the following select statement in ABAP:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
INTO corresponding fields of table GT_INSTMUNIC_F
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN EVER AS EV on
MUNIC~POD = EV~VREFER(9).
"where EV~BSTATUS = '14' or EV~BSTATUS = '32'.
My problem with the above statement is that does not recognize the substring/offset operation on the 'ON' clause. If i remove the '(9) then
it recognizes the field, otherwise it gives error:
Field ev~refer is unknown. It is neither in one of the specified tables
nor defined by a "DATA" statement. I have also tried doing something similar in the 'Where' clause, receiving a similar error:
LOOP AT gt_instmunic.
clear wa_gt_instmunic_f.
wa_gt_instmunic_f-mandt = gt_instmunic-mandt.
wa_gt_instmunic_f-bis = gt_instmunic-bis.
wa_gt_instmunic_f-ab = gt_instmunic-ab.
wa_gt_instmunic_f-zzelecdate = gt_instmunic-zzelecdate.
wa_gt_instmunic_f-ZZCERTDATE = gt_instmunic-ZZCERTDATE.
wa_gt_instmunic_f-CONSYEAR = gt_instmunic-CONSYEAR.
wa_gt_instmunic_f-ZDIMO = gt_instmunic-ZDIMO.
wa_gt_instmunic_f-ZZONE_M = gt_instmunic-ZZONE_M.
wa_gt_instmunic_f-ZZONE_T = gt_instmunic-ZZONE_T.
wa_gt_instmunic_f-USAGE_M = gt_instmunic-USAGE_M.
wa_gt_instmunic_f-USAGE_T = gt_instmunic-USAGE_T.
temp_pod = gt_instmunic-pod.
SELECT vrefer
FROM ever
INTO wa_gt_instmunic_f-vrefer
WHERE ( vrefer(9) LIKE temp_pod ). " PROBLEM WITH SUBSTRING
"AND ( BSTATUS = '14' OR BSTATUS = '32' ).
ENDSELECT.
WRITE: / sy-dbcnt.
WRITE: / 'wa is: ', wa_gt_instmunic_f.
WRITE: / 'wa-ever is: ', wa_gt_instmunic_f-vrefer.
APPEND wa_gt_instmunic_f TO gt_instmunic_f.
WRITE: / wa_gt_instmunic_f-vrefer.
ENDLOOP.
itab_size = lines( gt_instmunic_f ).
WRITE: / 'Internal table populated with', itab_size, ' lines'.
The basic task i want to implement is to modify a specific field on one table,
pulling values from another. They have a common field ( pod = vrefer(9) ). Thanks in advance for your time.
If you are on a late enough NetWeaver version, it works on 7.51, you can use the OpenSQL function LEFT or SUBSTRING. Your query would look something like:
SELECT munic~mandt VREFER BIS AB ZZELECDATE ZZCERTDATE CONSYEAR ZDIMO ZZONE_M ZZONE_T USAGE_M USAGE_T M2MC M2MT M2RET EXEMPTMCMT EXEMPRET CHARGEMCMT
FROM ZCI00_INSTMUNIC AS MUNIC
INNER JOIN ever AS ev
ON MUNIC~POD EQ LEFT( EV~VREFER, 9 )
INTO corresponding fields of table GT_INSTMUNIC_F.
Note that the INTO clause needs to move to the end of the command as well.
field(9) is a subset operation that is processed by the ABAP environment and can not be translated into a database-level SQL statement (at least not at the moment, but I'd be surprised if it ever will be). Your best bet is either to select the datasets separately and merge them manually (if both are approximately equally large) or pre-select one and use a FAE/IN clause.
They have a common field ( pod = vrefer(9) )
This is a wrong assumption, because they both are not fields, but a field an other thing.
If you really need to do that task through SQL, I'll suggest you to check native SQL sentences like SUBSTRING and check if you can manage to use them within an EXEC_SQL or (better) the CL_SQL* classes.

Merge rows with connecting dates

I've got a large Excel sheet with customer and subscription data. From this table I would like to merge records/rows with connection stop_ and start_dates and show the result in a new worksheet. A simplified version of the data is shown below.
Customer_id subscription_id start_date stop_date
1034 RV4 30-4-2012 30-1-2015
1035 AB7 30-1-2014 30-3-2014
1035 AB6 30-1-2014 30-3-2014
1035 AB7 30-12-2013 30-1-2014
1035 AB7 12-12-2012 30-12-2013
1035 AB7 12-9-2010 14-1-2011
So, the formula has to check the customer_id and the subscription_id. When there is a match between two or more rows in the sheet and the stop_date of one of the rows overlaps with the start_date of the other row, then after the extraction and merging, one new row must be shown with the start_date of the first and the stop_date of the other row. This also has to work if there are multiple rows with connecting dates. All the rows that don't match these criteria stay the same after the extraction. So the result will be like this:
Customer_id subscription_id start_date stop_date
1034 RV4 30-4-2012 30-1-2015
1035 AB6 30-1-2014 30-3-2014
1035 AB7 12-12-2012 30-3-2014
1035 AB7 12-9-2010 14-1-2011
A dynamic solution would be ideal while new data will be added to the original sheet. While I know this is possible when you're certain that the rows you're looking for are always below each other, this is not the case here and it wouldn't give you a very dynamic solution.
So some kind of array function would be needed in Excel I guess but after searching a lot I couldn't find a suitable solution. I've also got MATLAB available but no clue where to start in that program with a problem like this.
A dynamic solution may be possible, but if the dataset it large it might bog things down quite a bit because you'd need it to run every time a cell was changed.
Basically the best way I can see to approach this is to create unique keys out your customer_id and subscription_id, then collect all of the date ranges under that key and merge them.
Something like this should get you started (requires a reference to Microsoft Scripting Runtime):
Public Sub LinkSubscriptionDates()
Dim data As Dictionary, source As Worksheet, target As Worksheet
Set source = ActiveSheet
Set data = GetSubscriptions(source)
Set target = source.Parent.Worksheets.Add
'Copy headers
target.Range(target.Cells(1, 1), target.Cells(1, 4)).Value = _
source.Range(source.Cells(1, 1), source.Cells(1, 4)).Value
Dim row As Long
row = 2
Dim key As Variant, item As Variant
For Each key In data.Keys
For Each item In data(key)
target.Cells(row, 1) = Split(key, "|")(0)
target.Cells(row, 2) = Split(key, "|")(1)
target.Cells(row, 3) = Split(item, "|")(0)
target.Cells(row, 4) = Split(item, "|")(1)
row = row + 1
Next item
Next key
End Sub
Private Function GetSubscriptions(source As Worksheet) As Dictionary
Dim subscrips As Dictionary
Set subscrips = New Dictionary
Dim row As Long
Dim cust As String, subs As String, starting As String, ending As String
'Gather all the data as pairs of customer|subscription, starting|ending
For row = 2 To source.UsedRange.Rows.Count
Dim dates() As String
cust = source.Cells(row, 1).Value
subs = source.Cells(row, 2).Value
'Valid customer/subscription?
If cust <> vbNullString And subs <> vbNullString Then
starting = source.Cells(row, 3).Value
ending = source.Cells(row, 4).Value
'Has an ending and starting date?
If starting <> vbNullString And ending <> vbNullString Then
Dim key As String
key = cust & "|" & subs
'New combo?
If Not subscrips.Exists(key) Then
subscrips.Add key, New Collection
subscrips(key).Add starting & "|" & ending
Else
subscrips(key).Add starting & "|" & ending
Set subscrips(key) = MergeDates(subscrips(key))
End If
End If
End If
Next row
Set GetSubscriptions = subscrips
End Function
Private Function MergeDates(dates As Collection) As Collection
Dim candidate As Long, index As Long
Dim values() As String, test() As String
Dim merge As Boolean
For index = 1 To dates.Count
values = Split(dates(index), "|")
'Check to see if it can be merged with any other row.
For candidate = index + 1 To dates.Count
test = Split(dates(candidate), "|")
If CDate(test(0)) >= CDate(values(0)) And _
CDate(test(0)) <= CDate(values(1)) Or _
CDate(test(1)) >= CDate(values(0)) And _
CDate(test(1)) <= CDate(values(1)) Then
dates.Remove candidate
merge = True
Exit For
End If
Next candidate
If merge Then Exit For
Next index
If merge Then
'Pull both rows out of the collection.
dates.Remove index
values(0) = IIf(CDate(test(0)) < CDate(values(0)), _
CDate(test(0)), CDate(values(0)))
values(1) = IIf(CDate(test(1)) > CDate(values(1)), _
CDate(test(1)), CDate(values(1)))
'Put the merged date range back in.
dates.Add values(0) & "|" & values(1)
'Recurse.
Set MergeDates = MergeDates(dates)
End If
Set MergeDates = dates
End Function
It really needs to be fleshed out with data validation, error trapping, etc., and it currently just puts the resulting data on a new worksheet. All the work gets done in the GetSubscriptions function, so you can just grab returned Dictionary from that and do whatever you need to do with that data in it.

For each loop for a table in OpenEdge 10.2b takes more time

Below for each loop takes more time and i cant able to trace index usage using XREF as the table uses Oracle Schema.Please Help me.
Need to generate report for different Report Type ( Report type is the input parameter in my code ).Single report type may contain more than 50,000 records how to access all the record within minute.Index detail also mentioned below for each loop.
FOR EACH Report
FIELDS(EXTRACTDATE STATUS MailingType ReportType ReportNumber
RequestID CustID)
WHERE Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND (Report.MailingType = "LETTER"
OR Report.MailingType = "Mail") NO-LOCK:
< Statements >
.
.
END.
**Index Detail**
CREATE INDEX "TYPE_IDX1" ON "Report" ("EXTRACTDATE" DESC, "ReportTYPE", "STATUS", "MailingTYPE", "PROGRESS_RECID")
CREATE INDEX "REQ_IDX1" ON "Report" ("REQUESTID", "PROGRESS_RECID")
CREATE INDEX "RTTYP_IDX1" ON "Report" ("ReportTYPE","PROGRESS_RECID")
The "OR" at the end will slow things down considerably - the AVM does better if you split it up into two sets of AND statements and OR the result, like so:
WHERE (Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND Report.MailingType = "LETTER")
OR
(Report.EXTRACTDATE < Today
AND Report.ReportType = 'Customer Report'
AND Report.STATUS = 'Pending'
AND Report.MailingType = "Mail")