Is it possible to change the date range (between date1 and date2) of a query using a button? Basically I have one Card that shows the total sales depending on which of these buttons, Today, This Week, This Month is selected. I'd like to use ONLY 1 card to display the result. Not the dirty way of hiding the other cards.
This applies to Oracle Apex 5.x
Thanks.
You could create two hidden items (suppose it is page 1), P1_DATE_FROM and P1_DATE_TO and set their values by pressing those buttons (for example, via a dynamic action, using "Set Value").
Then the query would be
where date_column between :P1_DATE_FROM and :P1_DATE_TO
Alternatively, if you switch from 3 buttons to a radio button group with 3 radio buttons (whose values are 1 = today, 2 = this week, 3 = this month), then you could rewrite it as
where date_column between
case when :P1_RADIO = 1 then trunc(sysdate)
when :P1_RADIO = 2 then trunc(sysdate) - 7
when :P1_RADIO = 3 then trunc(sysdate, 'mm')
end
--
and
--
case when :P1_RADIO = 1 then trunc(sysdate) + 1
when :P1_RADIO = 2 then trunc(sysdate) + 1
when :P1_RADIO = 3 then add_months(trunc(sysdate, 'mm'), 1)
end
Those values might need to be changed, depending on what your DATE_COLUMN really contains, and what would "today" or "this week" or "this month" really be.
Okay so I tried this with a select list instead of a radio button group. This is now my current query
TRUNC(SS.EODATE) BETWEEN
(CASE
WHEN :P1_CO_SELECT_LIST = 1 THEN TRUNC(SYSDATE) -1
WHEN :P1_CO_SELECT_LIST = 2 THEN TRUNC(SYSDATE) -8
WHEN :P1_CO_SELECT_LIST = 3 THEN TRUNC(SYSDATE, 'MM')
WHEN :P1_CO_SELECT_LIST = 4 THEN TRUNC(SYSDATE, 'YY')
END)
AND SYSDATE
And this is what my what select list static values
STATIC:Yesterday;1,This Week;2,This Month;3,This Year;4
I am getting correct values when trying each line and not using a case statement so I guess the modification I did from your comment is working.
My problem is refreshing my Classic Report (Card template) without refreshing the whole page. I created a Dynamic Action on the Change event of the select list, then added a Refresh action with below settings...
Action: Refresh
Selection Type: Region
Region: My Report Region
I have set my Select List a Default value = 3 which works. My report queries the This Month date.
Now, when I try to change my selection in the select list, the report region changes data but not the expected data I need. And when I try to change again, it reloads the report region but the values doesn't change.
I'm sure I'm missing something here.
Related
I'm looking for a way to display row number in my cross-tab.
I tried searching online for the answer on how to do it but I haven't found anything useful.
So I'm turning to the good people on Stack Overflow.
The reason that I want to do this, if it's even possible, is because many clients in the company I started working at asked to have a row number in the cross-tab.
I am using Visual Studio 2013 and Crystal Reports.
So is there any basic ( easy ) way to do this in Crystal Reports?
For example, I have a cross-tab that displays unit of measure and amounts.
https://imgur.com/a/lOjCq
But I would like my cross-tab to be like:
Amount
1. Total -38
2. KG
3. kut 9
4. LIT. 4
5. m -32
6. proc
7. KoŠ¼ -19
Please keep in mind that I only started working with Crystal Reports this week, so this is all new to me. And the cross-tab in the picture is just a random one I made to explain what I need.
Thank You in advance.
In order to show Row Number in your CrossTab you will need to first put Row Number in the Stored Procedure that sends data to your report.
In order to understand it better i will first show you how my data looks before i add a Row number(Pic 1).
Code:
select
a.S_ID as ID,
osn.sifra as BasicGoodsCode,
osn.naziv as BasicGoods,
null,
a.RobaSifra as GoodsCode,
a.Roba as Goods,
a.Detalj as Detail,
a.DetaljDodatak as DetailsAddon
from NP_Stavke s
left join RobaGrupe osn on osn.id = s.RobaId
left join #A a on a.S_ID = s.Id
order by BasicGoodsCode, ID
Pic 1: As you can see I have 3 different Ids for BasicGoods which means that I have 3 Rows in my CrossTab
Columns ID, BasicGoodsCode and BasicGoods are going to be Rows in my CrossTab.
Values from column DetailsAddon are going to be my columns in CrossTab.
Columns GoodsCode, Goods and Detail are going to be values in my CrossTab.
Column Pieces is not important.
Now that you know how everything looks we can start with adding a Row Number to our CrossTab.
Step 1:
First thing that you need to do is to add a Row number in table in your stored procedure.
To do this I used DENSE_RANK()
depending on your data you might need to use ROW_NUMBER() or maybe even something else. I used DENSE_RANK() because I needed my row number to change once S_ID changes.
Code:
select
a.S_ID as ID,
DENSE_RANK() OVER (ORDER BY osn.sifra, s.Id asc) as BasicGoodsRowNo, // THIS IS ADDED
osn.sifra as BasicGoodsCode,
osn.naziv as BasicGoods,
null as Pieces,
a.RobaSifra as GoodsCode,
a.Roba as Goods,
a.Detalj as Detail,
a.DetaljDodatak as DetailsAddon
from NP_Stavke s
left join RobaGrupe osn on osn.id = s.RobaId
left join #A a on a.S_ID = s.Id
order by BasicGoodsCode, ID
Lets take a look at how our data looks now(Pic 2)
As you can see we added a Row Number that changes when Id changes.
IMPORTANT: Row Number has to be ether Integer or Decimal in the DataTable that you are using in your report if it's not it will not work correctly.
Step 2:
We've done the 'hard' part now it's time to put Row number in our CrossTab.
When you create a CrossTab or when right click CrossTab and then click on 'Cross-Tab Expert...' it will open a window like this one and in it in the Row section you will insert your Row Number Column(in my case and as you can see in the code above the name of my Row Number Column is 'BasicGoodsRowNo').
Step 3:
Since you don't want to show only the Row number in the report left click on your Row and then click on 'Group Options...'(Pic 4)
Once the new window appears click on 'Options' tab then check the 'Customise group name field' then click on 'Use a formula as group name' and then on 'x-2'(Pic 5)
Step 4:
Enter a formula like this one:
toText( {myTbl.BasicGoodsRowNo}, 0, "" ) + '. ' + {myTbl.BasicGoodsCode} + ' ' + {myTbl.BasicGoods}
Of course your formula will not be exactly like mine since you will not have the same columns as I do. The only part of this formula that you HAVE to have is toText( {myTbl.BasicGoodsRowNo}, 0, "" ) where instead of {myTbl.BasicGoodsRowNo} you will put your row number column. You will need toText since if you dont have that and you want to show a String after your Row Number it will give you an error because RowNumber is an integer field.
GJ YOU ARE ALL DONE AND IT WASN'T THAT HARD WAS IT
How My CrossTab looks once RowNumber is added
Now there is a way to simplify this process and that is:
Step 1:
In your stored procedure create 2 columns. One will show Row Number and the other will show Value that will be displayed as CrossTab row.
Code:
select
a.S_ID as ID,
DENSE_RANK() OVER (ORDER BY osn.sifra, s.Id asc) as BasicGoodsRowNo, // RowNumber
CONVERT(varchar(10), DENSE_RANK() OVER (ORDER BY osn.sifra, s.Id asc)) + '. ' + osn.sifra + ' ' +osn.naziv as BasicGoods, // Value that will be displayed in CrossTab Row
null as Pieces,
a.RobaSifra as GoodsCode,
a.Roba as Goods,
a.Detalj as Detail,
a.DetaljDodatak as DetailsAddon
from NP_Stavke s
left join RobaGrupe osn on osn.id = s.RobaId
left join #A a on a.S_ID = s.Id
order by BasicGoods, ID
As you can see Column BasicGoodsRowNo did not change and will still display the same values as before and I have deleted the clumns BasicGoodsCode and BasicGoods and replaced them with this
CONVERT(varchar(10), DENSE_RANK() OVER (ORDER BY osn.sifra, s.Id asc)) + '. ' + osn.sifra + ' ' +osn.naziv as BasicGoods,
The BasicGoods column will show BasicGoodsRowNo + BasicGoodsCode + BasicGoods.
Step 2:
Step 2 is the same as before.
Step 3:
Once you click on your row and on 'Group Options' go to 'Options' tab again then check the 'Customise group name field' check box again and after that instead clicking on 'Use a formula as group name' click on 'Choose from existing field' and from a combo box select the column you want to show as Row Value in your CrossTab. In my Case that is 'BasicGoods' column (Pic 7).
I used the first method since depending on what user decides I may not show CrossTab at all and I may not show BasicGoods but if you only have CrossTab in your report you can use the second, shorter and easier, method.
If you have any questions feel free to ask.
I have an interactive grid with a list of records and lets say it has a date column. Now i only want to show those records or make only those records editable whose month in that date column is equal to the current month on page load. Now i know that a dynamic action can be created with execute javascript code as the option. But what would be the actual code to do it? I tried to access the grid with this
var grid = apex.region("emp").widget().interactiveGrid("getViews", "grid");
Then i can use the grid.model._data to get the records and loop through it and check the date column values and verify if it is current month or not, but after checking i don't know as to set the css for that particular row as {display: none;}. Any help would be appreciated. Thanks.
Try this:
1 - Create a dynamic action in your interactive grid on the column that you want
disable
Event: Row Initialization [Interactive Grid]
Selection Type: Columns
Region: Your grid region
Columns: Your column to disable or enable
2 - On Client Side Condition:
Type: JavaScript expression
Javascript Expression:
//Suppose there is a function (getMonth)
//that returns the number of the month (1..12) in a date string;
//you can do this expression.
getMonth($(this.triggeringElement).val()) != ((new Date()).getMonth() + 1)
3 - True action
Disable
Selection type: Columns
Columns : The column to want disable or enable
Example: https://apex.oracle.com/pls/apex/f?p=145797:8
The column "CREDIT LIMIT" is disable when the value is 3000
i only want to show those records (...) whose month in that date column is equal to the current month on page
load
As interactive grid's source is a SELECT statement, why wouldn't you include a WHERE clause which says something like this:
where trunc(date_column, 'mm') = trunc(sysdate, 'mm')
Yes, I know - possible performance impact (index on DATE_COLUMN not being used) and stuff, but that's just the general idea. Could be further improved if it turns out to be OK.
[EDIT, after seeing the comment]
No problem in changing the WHERE clause:
where date_column >=
case when to_number(to_char(sysdate, 'dd')) <= 5 then trunc(add_months(sysdate, -1), 'mm')
else trunc(sysdate, 'mm')
end
I'm trying to cut down on rows a report has. There are 2 assets that return on this query but I want them to show up on one row.
Basically if dc.name LIKE '%CT/PT%' then I want it to be same row as the asset. The SP.SVC_PT_ID is the common field to join them.
There will be times when there is no dc.name LIKE '%CT/PT%' however I still want the DV.MFG_SERIAL_NUM to populated just with a Null to the right.
Select SP.SVC_PT_ID, SP.DEVICE_ID, DV.MFG_SERIAL_NUM, dc.name,
substr(dc.name,26)
From EIP.SVC_PT_DEVICE_REL SP,
eip.device_class dc,
EIP.DEVICE DV
Where SP.EFF_START_TIME < To_date('20170930', 'YYYYMMDD') + 1
and SP.EFF_END_TIME is null
and dc.id = DV.device_class_id
and DV.ID = SP.device_id
ORDER BY SP.SVC_PT_ID, DV.MFG_SERIAL_NUM;
I'm not sure I understand what you are saying; test case would certainly help. You said that query you posted returns two rows (only if we saw which ones ...) but you want them to be displayed as the image you attached to the message.
Generally speaking, you can do that using an aggregate function (such as MAX) on certain column(s), along with the GROUP BY clause that contains the rest of them.
Just for example:
select svc_pt_id, max(ctpt_name) ctpt_name, sum(ctpt_multipler) ctpt_multipler
from ...
group by svc_pt_id
As I said: a test case would help people who'd want to answer the question. True - someone might have understood it far better than I did and will provide assistance nevertheless.
EDIT: after you posted sample data (which, by the way, don't match screenshot you posted previously), maybe something like this might do the job: use analytic function to check whether name contains CT/PT; if so, take its data. Otherwise, display both rows.
SQL> with test as (
2 select 14 svc_pt_id, 446733 device_id, 'Generic Electric' name from dual union
3 select 14, 456517, 'Generic CT/PT, Multiplier' from dual
4 ),
5 podaci as
6 (select svc_pt_id, device_id, name,
7 rank() over (partition by svc_pt_id
8 order by case when instr(name, 'CT/PT') > 1 then 1
9 else 2
10 end) rnk
11 from test
12 )
13 select svc_pt_id, device_id, name
14 from podaci
15 where rnk = 1;
SVC_PT_ID DEVICE_ID NAME
---------- ---------- -------------------------
14 456517 Generic CT/PT, Multiplier
SQL>
My TEST table (created by WITH factoring clause) would be the result of your current query.
i'm trying to show some averages over the past 12 months but there is no data for June/July so i want the titles for the months to display but just 0's in the 3 columns
currently it's only showing August - May which is 10 rows so it's throwing off formulas and charts etc.
select to_char(Months.Period,'YYYY/MM') As Period, coalesce(avg(ec.hours_reset),0) as AvgOfHOURSReset, coalesce(AVG(ec.cycles_reset),0) as AvgofCycles_Reset, Coalesce(AVG(ec.days_reset),0) as AvgofDAYS_Reset
from (select distinct reset_date as Period from engineering_compliance
where reset_date between '01/JUN/15' and '31/MAY/16') Months
left outer join engineering_compliance ec on ec.reset_date = months.Period
WHERE EC.EO = 'AT CHECK'
group by to_char(Months.Period,'YYYY/MM')
order by to_char(Months.Period,'YYYY/MM')
;
(select distinct to_char(reset_date,'YYYY/MM') as Period from engineering_compliance
where reset_date between '01/JUN/15' and '31/MAY/16') Months;
That query is pretty good, it's not far from working.
You would need to replace the Months table part. You want exactly one row per month, regardless of whether there's any data in the ec table.
You could maybe synthesize some data without going to any actual table in your own schema.
For example:
SELECT
extract(month from add_months(sysdate,level-1)) Row_Month,
extract(year from add_months(sysdate,level-1)) Row_Year,
to_char(add_months(sysdate,level-1),'YYYY/MM') Formatted_Date,
trunc(add_months(sysdate,level-1),'mon') Join_Date
FROM dual
CONNECT BY level <= 12;
gives:
ROW_MONTH,ROW_YEAR,FORMATTED_DATE,JOIN_DATE
6,2016,'2016/06',1/06/2016
7,2016,'2016/07',1/07/2016
8,2016,'2016/08',1/08/2016
9,2016,'2016/09',1/09/2016
10,2016,'2016/10',1/10/2016
11,2016,'2016/11',1/11/2016
12,2016,'2016/12',1/12/2016
1,2017,'2017/01',1/01/2017
2,2017,'2017/02',1/02/2017
3,2017,'2017/03',1/03/2017
4,2017,'2017/04',1/04/2017
5,2017,'2017/05',1/05/2017
Option 1: Write that subselect inline into your query, replacing sysdate with the start month and the figure 12 on the last line can be altered for the number of months you want in the series.
Option 2 (can be reused more conveniently in a variety of situations and queries): Write a view with a long series of months (for example, Jan 1970 to Dec 2199) using my SQL above. You can then join to that view on join_date with whatever start and end months you want. It will give you one row per month and you can pick up the formatted date from its column.
I am running this query currently for one scenario but I have two scenarios: If SYSDATE = Monday, then run "SYSDATE - 2", otherwise run "SYSDATE - 1". I'm connecting to the database via an OLE connection from Excel so I'm not sure I can use a stored procedure. Is there a way to write the query to accomplish both scenarios? Thanks for all help.
SELECT
DISTINCT VERSION_NAME VERSION, MIN(RECONCILE_START_DT) DATES
FROM
SDE.GDBM_RECONCILE_HISTORY
WHERE
RECONCILE_RESULT = 'Conflicts'
AND
RECONCILE_START_DT > SYSDATE -1
GROUP BY VERSION_NAME
ORDER BY 2 ASC NULLS LAST
You may use a CASE statement in your WHERE condition to subtract either 2 for Mondays or 1 for the rest of the week. TO_CHAR(DATE, 'D') delivers the day of week beginning with Sundays = 1. Therefore Mondays are 2.
Try this:
SELECT
VERSION_NAME AS VERSION,
MIN(RECONCILE_START_DT) AS DATES
FROM
SDE.GDBM_RECONCILE_HISTORY
WHERE
RECONCILE_RESULT = 'Conflicts'
AND
RECONCILE_START_DT > SYSDATE -
CASE TO_CHAR(SYSDATE, 'D')
WHEN '2' THEN 2
ELSE 1 END
GROUP BY VERSION_NAME
ORDER BY 2 ASC NULLS LAST
Also you don't need the DISTINCT keyword as you're already use GROUP BY.