I am quite confused with how Oracle apex_application.gfnn works and whether it only works for standard SQL reports in Oracle ApEx or only with SQL (Updateable reports, i.e. tabular forms).
Basically I am trying to achieve the following using this sample SQL, which is just a Standard SQL Report but I'm unsure if what I am trying to achieve is possible with this type or report, i.e.:
select id,
name,
telephone,
apex_item.checkbox2(10,id) as "Tick when Contacted",
apex_item.text(20,my_date) as "Date Contacted",
apex_item.textarea(30,my_comment,5,80) as "Comment"
from my_table
Based on the above SQL, assume this SQL query returns 10 rows. Now using checkbox as my driving id, I tick the checkbox of all odd records/rows, i.e. rows 1,3,5,7,9 and for each of these rows, I also enter a date value (f20) together with a comment (f30)
Keeping this in mind, I then want to created a page process that is called when the user presses the "Save" button that will iterate through these checked rows and store for each record, my date and my comment but only for the rows that I have selected.
So based on the above, I would expect to have 5 news rows in my table with the following columns:
ID MY_DATE MY_COMMENT
1 26/08/2012 Comment A
3 27/08/2012 Comment B
5 28/08/2012 Comment C
7 29/08/2012 Comment D
9 30/08/2012 Comment E
Unfortunately I am unsure how to achieve this using apex_application.G_F10.COUNT.
I want to be able to access the content of each of these array elements (f20) and f(f30) for each row that I have ticked the checkbox with.
Is this possible or have I misunderstood how apex_application.G_Fnn works? If this is not possible, how I can achieve this? Do I need a tabular report?
You're very close.
select apex_item.checkbox2(10, empno) select_me,
apex_item.text(20, empno) empno,
apex_item.text(30, ename)||apex_item.hidden(50, empno) ename
from emp
I'm concatenating the hidden item since i don't want it in its own column. Messes with the layout.
Also, the hidden item is there because of how checkboxes work. Checkboxes only submit their values for checked items. This would mean that array 10 has 3 values. The other arrays would still contain the values for all rows.
This is why i added the hidden empno again: so we can match the checked values to the other rows.
On submit process:
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
BEGIN
--f10: checkbox
--f20: empno
--f30: ename
--f50: empno again
for i in 1..apex_application.g_f10.count
loop
for j in 1..apex_application.g_f50.count loop
if apex_application.g_f10(i) = apex_application.g_f50(j)
then
-- access values for the selected rows in the other arrays
v_empno := apex_application.g_f20(j);
v_ename := apex_application.g_f30(j);
apex_debug_message.log_message('Employee: '||v_empno||' - '||v_ename);
end if;
end loop;
end loop;
END;
Run page, enable debug, select records 2, 4 and 6, submit.
Debug output:
All you now need to do is put your processing in that loop.
Related
I have a main report which has three sub-reports. I am trying to grey out one of the parameter option when a certain report is selected. The reason I want to do that is because one of the sub report does not use this parameter.
Here's the code I am using now. The parameter displaying the query result is #device.
--When user select report 2, the parameter displays the device list from table2.
IF #selectReport = 2
BEGIN
SELECT DISTINCT type
FROM table2
END
--When user select report 3, the parameter displays the device list from table3.
IF #selectReport = 3
BEGIN
SELECT DISTINCT type
FROM table3
END
--When user select report 1. I want to grey out the parameter, but I could not do it.
--So I created the table contains NULL value.
--So, when the user select the report 1, the parameter will show only null value.
IF #selectReport = 1
BEGIN
SELECT DISTINCT type
FROM nullValueTable1
END
I want it to be grey out when the report 1 is selected instead of show NULL on drop down list. Any idea???
You can't grey out the parameter. Unfortunately you can't hide the parameter either as the hidden property only takes True and False. What you are doing now might be the best you can do. However, you could try looking at cascading parameters, maybe you might be able to provide a slightly more user friendly value like "None" to the dropdown.
I have a table of items, each with an item ID(int). I want to only display items with item ID's based on a string. For example I want to display items "12, 1005, 2". This string is different every time. How would I do this?
If you are using Oracle, you can use IN:
select from item i where i.id in (12,1005,2)
is your parameter is always consist of 3 numbers or it may be different in runtime??
if it's fixed you can use substr and instr to cut
I would consider an approach documented by Justin Cave with the question, How can I select from list of values in Oracle. Tom Kyte documents a similar approach (without regexpressions) on his Ask Tom site.
Since you are in an Oracle Apps environment using Oracle Reports, I just provide an example using the items table:
with x as
( select '12, 1005, 2' str from dual
)
select *
from inv.mtl_system_items_b item
where item.organization_id =
&org_id
and item.inventory_item_id in
(select to_number(regexp_substr(str,'[^,]+',1,level)) element
from x
connect by level <= length(regexp_replace(str,'[^,]+')) + 1
)
Procedurally in Oracle reports, you could create a function as a program unit that performs this parsing of this comma separated value parameter using similar logic (again, see Justin Cave's parse list function (answer associated with the question I refer to above).
I have the following select statement that I am using as a standard report:
select id,
name,
telephone,
apex_item.checkbox2(10,id) as "Tick when Contacted",
apex_item.text(20,:P2_DATE) as "Date Contacted",
apex_item.textarea(30,:P2_COMMENT,5,80) as "Comment"
from my_table
My question is and the area that I am not sure if I am doing this correctly is that if this statement returns 10 rows and out of those 10 rows, I only select/check 5 records and then press the submit button, why is it that my PL/SQL page process that inserts the selected records into another table is not picking up :P2_DATE and :P2_COMMENT which are hidden items on the page and purely just used as placeholders and not actual columns within my_table?
Am I doing this correctly or do I need to use an apex collection?
Here is what my page process looks like; is this correct?
DECLARE
v_row BINARY_INTEGER;
BEGIN
FOR i IN 1..APEX_APPLICATION.G_F10.COUNT LOOP
v_row := APEX_APPLICATION.G_F10(i);
INSERT INTO MY_OTHER_TABLE
( DATE_CONTACTED,
COMMENTS
)
VALUES ( APEX_APPLICATION.G_F20(v_row),
APEX_APPLICATION.G_F30(v_row)
);
END LOOP;
COMMIT;
END;
Example of report with user input is as follows:
ID/CHECKBOX DATE CONTACTED COMMENTS
=====================================================
1 21/08/2012 Comment 1
2 21/08/2012 Comment 2
3 21/08/2012 Comment 3
4 21/08/2012 Comment 4
5 21/08/2012 Comment 5
Based on this report where user has manually entered these 5 comments, I expect these 5 records get inserted into MY_OTHER_TABLE, as they have been checked.
Unfortunately MY_OTHER_TABLE never gets populated for the 5 records that I have checked.
I am unsure what I have missed out on something, or if I have completely got my original select wrong with regards to using these two placeholder items?
In your comment you say
can I user apex_item.text api where the source is not coming from an underlying oracle table?
Now i read that as:
can i generate this report and have the default value for my apex_item fields set to that of my 2 page items.
Yes. You can. That is what i thought you meant originallyn and it makes sense since the items are hidden anyway. Just make sure of the below:
if you meant that the value is not put in the report items at page load:
if the region with the hidden items is BELOW the region with your report, move your region with the items or create a new region ABOVE the region with your report.
With above and below i'm talking about their position in the form structure. Switch over to tree view if you use component view to easily see this.
My guess is that the item (and its source) is processed before, and thus has a valid session state before the rendering of the report starts.
How can I fill the page with empty table rows? For example; I have 2 records in the dataset but I want to the page with empty rows (draw the table borders until the end of page)
I have;
I want;
Are you getting your report data from a database? If so you might look at returning empty rows from your database call.
If you can describe your data source and query that you are using for this report, we might be able to suggest changes to the query to return blank rows.
UPDATE:
OK, Based on how you describe the data you are getting, perhaps you can change your database call to do something like this:
select * from Subeler where Subeler.FirmaId = 10
UNION ALL
select TOP 5 ' ' from Subeler where 1 = 1
That will give you your original data, plus 5 "blank" rows to help pad your report. Of course you would have to make sure the second query has the same number and type of columns as your first, but hopefully this will point you in the right direction.
I am wondering if it's possible to use a view to get the top 5 lines from a table.
I am finding that Crystal reports doesn't seem to have anything built in to do this, or I'd do it there.
When I query the view Select * from qryTranHistory, it returns the first 5 items, but if I try to select a specific type Select * from qryTranHistory Where tID = 45 it returns nothing, since there are no tID=45 in the top 5 normally.
Is it possible to do this?
Can it be accomplished in a sub report in Crystal Reports?
It is easy to limit a report to the top 5 records. In the menu, just choose
Report --> Selection Formulas... --> Group
In the formula, enter "RecordNumber <= 5" and you are done.
You don't need to have a group field nor summary field to do the group filter. You don't need a sort order, but using top N records without a sort order doesn't usually make much sense. It might not be efficient as OMG Ponies suggested, but for small number of records it is OK.
You can reference a sproc from Crystal Reports. In the sproc, use a conditional on the parameter.
ALTER PROCEDURE dbo.Get_TOP5
(
#tID INT = NULL
)
AS
IF #tID IS NULL
BEGIN
SELECT TOP 5
FIELD1,
FIELD2
FROM qryTranHistory
END
ELSE
BEGIN
SELECT
FIELD1,
FIELD2
FROM qryTranHistory
WHERE tID =#tID
END
A simple setting can limit the records to top 5!! Here it is, if you're using .Net 1.1 (similar arrangement of options in higher frameworks too!).
Right click on the report layout > Reports > Top N/Sort Group Expert > Choose Top N in the Dropdown that asks for the type of filtering/ sorting you wish to do > Set the Value of top N (5 in your case) > Uncheck the option that includes other records.
Your report will be filtered for only the top 5 records from the Dataset.
There's another way how it could be done and that is through the Record selection formula where you limit the No. of records, as suggested by John Price in this thread.
Cheers!
Can you put the TOP in your SELECT statement instead of in the view?
SELECT TOP 5
col1,
col2,
...
FROM
qryTranHistory
WHERE
tid = 45
If your table has more then 5 rows I hope this query:
SELECT * FROM qryTranHistory
Returns more then 5 rows because you never mentioned TOP 5.
Your question doesn't make a lot of sense as I am not sure waht you are after.
You mentioned if you ran your query with WHERE tID=45, it returns nothing, what exactly do you want it to return ?
Read up on TOP in BOL:
SELECT TOP 10 Recs FROM Records WHERE...
By the way you do not want to do this in the report / a form interface, you want to do this in your db layer.
You can do Top N processing in Crystal Reports, but it's a little obscure - you have to use the group sort expert (and in order to use that, you need to have groups and summary fields inserted into the groups.)
Doing the Top N processing in the query should be more efficient, where possible.
If you have a small recordset, you can create a running total that counts the change of rows (field1), then in Section Expert in Details, tell it to supress RTotal0 (your running total variable) to > 5