apex_application.g_notification - oracle-apex

I'm trying to do a notification message when doing a process on submit but is not working
DECLARE
l_sendto NUMBER := :P22_SEND_TO;
l_user_groups NUMBER := :P22_USER_GROUP;
l_media NUMBER := :P22_MEDIA;
l_usersessionid NUMBER := :APP_SESSION;
SINGLE_USER CONSTANT number :=0;
l_aux NUMBER;
e EXCEPTION;
BEGIN
--verify if user
select userid into l_aux FROM SURV_TEMP_SENDTO WHERE userid = l_user_groups and usersessionid= l_usersessionid and rownum =1;
IF l_aux > 0 THEN
RAISE e;
ELSE
IF l_sendto = SINGLE_USER THEN
--if selected all types of medias of one user
INSERT INTO SURV_TEMP_SENDTO (userid, mediatypeid, usersessionid)
(SELECT zm.userid, zm.mediatypeid, l_usersessionid
FROM z.media zm, Z.media_type zmt
WHERE zmt.mediatypeid = zm.mediatypeid
AND zm.userid = l_user_groups);
apex_application.g_print_success_message := 'Inserting OK';
END IF;
EXCEPTION
WHEN e THEN
apex_application.g_global_notification:= 'Error inserting values';
--apex_application.g_print_success_message := 'Error inserting values';
END;
In the raise EXCEPTION it doesn't show any msg but if he enters the ELSE it writes the success msg.
Anyone know why it doesn't work in EXCEPTION?

In the ELSE you are using g_print_success_message. That will work in the EXCEPTION section too. When I tried it, g_global_notification didn't work in either main body or exception section, but only appeared if an exception was raised and not handled - I don't know why though.

Related

(SOLVED) Exception from HRESULT: 0x800A01A8 Dynamic Navision 2016

I wrote a code where user filters a source number from the table, the code get the source number and open an Excel file with the same number in a folder, write other data into the file and then save to temp folder. The program worked for some of the Excel files in the folder, but it won't work for the majority of the files. When it finishes running it'll say Exception from HRESULT: 0x800A01A8, the file gets saved into temp folder but the data is not written into it.
https://i.stack.imgur.com/kHtbC.png
I have searched all over Google but it seems like no one had encountered the same issue as I am and I have no idea what this exception means. Below is the code.
ProductionOrder - OnAfterGetRecord()
CLEAR(xlApplication);
CLEAR(xlWorkbooks);
CLEAR(xlWorksheet);
CLEAR(xlshape);
// Open excel
IF CREATE(xlApplication, FALSE, TRUE) THEN BEGIN
xlApplication.SheetsInNewWorkbook := 1;
xlApplication.ScreenUpdating(TRUE);
xlWorkbooks := xlApplication.Workbooks;
END ELSE ERROR('Could not start Excel.');
xlWorkbooks.Open('C:\PROCESS CHECKSHEET\' + ProductionOrder."Source No." + '.xlsx');
xlWorkbook := xlApplication.ActiveWorkbook;
xlSheets := xlWorkbook.Worksheets;
FOR i := 1 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(i);
xlWorksheet.Activate;
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
xlWorkbook._SaveAs('C:\temp\' + ProductionOrder."Source No.");
xlWorkbook.Close(TRUE);
xlApplication.Quit;
END;
CurrReport.QUIT;
LOCAL xlsCol(col : Integer) : Text
IF col > 26 THEN BEGIN
ColFirst := col DIV 26;
col := col MOD 26;
END
ELSE
ColFirst := 0;
Letters := 'ABCDEFGHIJKLMNOPQRSTUVYWXYZ';
IF ColFirst <> 0 THEN
EXIT (STRSUBSTNO('%1%2',Letters[ColFirst],Letters[col]))
ELSE
EXIT (STRSUBSTNO('%1',Letters[col]));
LOCAL xlsCell(col : Integer;row : Integer) : Text[15]
EXIT (STRSUBSTNO('%1%2',xlsCol(col),row));
Edit:
I have tried to debug. Debugger says error is on line "xlWorksheet := xlSheets.Item(i);". There is only one sheet in the Excel file that I am trying to access. What I don't understand is that it would work on other Excel files, just not on this file that I am currently trying to access.
I also found out that if I copy the content into a new Excel file, then the code would work on the new Excel file. Could it also be a problem of Excel version?
I solved this on my own.
Because the Excel files were given to me by my HOD at work (and these Excel files were written by other department), I did not know that there was a hidden sheet inside those Excel files, hence it output the exception error because my code was only indexing Excel file that only has one sheet. I changed my index to 2 and it worked. Note to self, next time gotta check for hidden sheets.
I don't know if there is a for each sheet equivalent for C/AL programming because I'm new to the language, so I used 2 for loops to solve the problem.
CLEAR(xlApplication);
CLEAR(xlWorkbooks);
CLEAR(xlWorksheet);
IF CREATE(xlApplication, FALSE, TRUE) THEN BEGIN
xlApplication.SheetsInNewWorkbook := 1;
xlApplication.ScreenUpdating(TRUE);
xlWorkbooks := xlApplication.Workbooks;
END ELSE ERROR('Could not start Excel.');
xlWorkbooks.Open('C:\13. PROCESS CHECKSHEET\' + ProductionOrder."Source No." + '.xlsx');
xlWorkbook := xlApplication.ActiveWorkbook;
xlSheets := xlWorkbook.Worksheets;
FOR I := 1 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(I);
xlWorksheet.Activate;
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
END;
FOR I := 2 TO xlSheets.Count DO BEGIN
xlWorksheet := xlSheets.Item(I);
xlWorksheet.Activate;
IF (FORMAT(xlWorksheet.Name) = 'PROCESS CHECKSHEET') OR (FORMAT(xlWorksheet.Name) = 'Process Checksheet') THEN BEGIN
xlRange := xlWorksheet.Range(xlsCell(14,7));
xlRange.Value := ProductionOrder."No.";
xlRange := xlWorksheet.Range(xlsCell(14,8));
xlRange.Value := FORMAT(ProductionOrder.Quantity);
END;
END;
xlWorkbook.SaveAs('C:\13. PROCESS CHECKSHEET\temp\' + ProductionOrder."Source No.");
MESSAGE('Success');
xlWorkbook.Close(TRUE);
xlApplication.Quit;
CurrReport.QUIT;

Oracle Update with the Case When Exists clause

I need a trigger to update a table DIRECTORY_NUMBER when one value of DN_NUM column matches with MSISDN column value of a different table (RNPH_REQUETS_DETAILS) under a different schema(NKADM). The trigger will run every time there's a new entry in the DIRECTORY_NUMBER table. Based upon several conditions, the values of the DN_STATUS column and a few other columns need to be updated. The updated value of the DN_STATUS column will be 'r' if the conditions are met, and 'w' if the conditions are not met. Active portion of my code is given below:
UPDATE d
SET d.DN_STATUS = CASE WHEN EXISTS (SELECT 1 from NKADM.RNPH_REQUESTS_DETAILS n where n.MSISDN = d.DN_NUM AND n.PROCESS_STATE_ID = 4 AND n.ACTION='IN' AND n.FAILED_STATUS IS NULL AND TRUNC(n.MODIFICATION_DATE) = TRUNC(SYSDATE))
THEN 'r'
ELSE 'w'
END,
d.DN_MODDATE = SYSDATE,
d.BUSINESS_UNIT_ID = 2,
d.HLCODE = 5
WHERE d.DN_ID =: NEW.DN_ID
AND d.PLCODE = 1004
AND d.DN_STATUS = 'f'
FROM DIRECTORY_NUMBER d;
I am getting the following error:
Error(48,1): PL/SQL: SQL Statement ignored
Error(60,3): PL/SQL: ORA-00933: SQL command not properly ended
The errors get resolved only if I remove the references. But that gives a different result than intended. When the code is as follows:
UPDATE DIRECTORY_NUMBER
SET DN_STATUS = CASE WHEN EXISTS (SELECT 1 from NKADM.RNPH_REQUESTS_DETAILS where MSISDN = DN_NUM AND PROCESS_STATE_ID = 4
AND ACTION='IN' AND FAILED_STATUS IS NULL AND TRUNC(MODIFICATION_DATE) = TRUNC(SYSDATE))
THEN 'r'
ELSE 'w'
END,
DN_MODDATE =SYSDATE,
BUSINESS_UNIT_ID=2,
HLCODE =5
WHERE DN_ID =:NEW.DN_ID
AND PLCODE =1004
AND DN_STATUS ='f';
COMMIT;
Even when the CASE WHEN EXISTS condition is true (returns result when run independently), the value of DN_STATUS gets updated to 'w'.
Update: I tried with the following code:
UPDATE DIRECTORY_NUMBER
SET DN_STATUS = 'r',
DN_MODDATE =SYSDATE,
BUSINESS_UNIT_ID=2,
HLCODE =5
WHERE DN_ID =:NEW.DN_ID
AND PLCODE =1004
AND DN_STATUS ='f';
AND DN_NUM in (select MSISDN from NKADM.RNPH_PROCESS_DETAILS where PROCESS_STATE_ID = 4);
This isn't working either. If I remove the last condition, the resultant row has DN_STATUS value of 'f', and the MSISDN is in NKADM.RNPH_PROCESS_DETAILS table with PROCESS_STATE_ID = 4. I don't understand why it's not working.
What am I doing wrong?
In BEFORE update/insert trigger for EACH ROW you can modify data of record which is currently processed. You don't need to call an extra UPDATE to change the data.
In other words you can do something like this
IF :NEW.PLCODE = 1004 AND :NEW.DN_STATUS = 'f' THEN
:NEW.DN_MODDATE := SYSDATE;
:NEW.BUSINESS_UNIT_ID := 2;
:NEW.HLCODE := 5;
-- this query you can wrap in a function and call this function
SELECT COUNT(1)
INTO lv_count
FROM NKADM.RNPH_REQUESTS_DETAILS n
WHERE n.MSISDN = :NEW.DN_NUM
AND n.PROCESS_STATE_ID = 4
AND n.ACTION = 'IN'
AND n.FAILED_STATUS IS NULL
AND TRUNC(n.MODIFICATION_DATE) = TRUNC(SYSDATE);
IF lv_count > 0 THEN
:NEW.DN_STATUS := 'r';
ELSE
:NEW.DN_STATUS := 'w';
END IF;
END IF;

Crystal Report converting value to number with symbol

I have an issue with a Crystal Report that I'm creating. I am using fields from a database and am pulling in the result value where the analysis field is equal to certain values.
In the condition the first check looks at the analysis field and checks if its equal to "Conf". The result for this is "<10"
The second check looks at the analysis field and checks if its equal to "Original". The result for this is "20".
I want the results to display in the order above however with the following basic logic it returns the result of 20.
if analysis = "conf" then result
else if analysis = "Original" then result
I was having this issue with multiple records however solved it by converting both results to numbers (toNumber(Result)). However this record has the less than symbol contained within the field value which causes the conf result to "be skipped" and will display the original result instead. I've tried a few things without success. Here is the code for the condition of where I'm at below. I fell this is way to complex logic but I've just added to it as I've had ideas and it shows what I've tried.
if {UNITS} = "CFU_G" then
if {ANALYSIS} = "CONF" and
{RESULT}="" or
{RESULT} = "0" then 0
else if {ANALYSIS} = "CONF"
then if isNumeric({RESULT}) then
tonumber({RESULT}) else
tonumber(Replace ({RESULT}, "<", ""))
else
if {UNITS} = "CFU_G" then
if {ANALYSIS} = "Original" and
{RESULT}="" or
{RESULT} = "0" then 0
else if {ANALYSIS} = "Original"
then if isNumeric({RESULT}) then
tonumber({RESULT}) else
tonumber(Replace ({RESULT}, "<", ""))
Thanks,
Tom
This was the solution I came up with.
Field 1
whileprintingrecords;
stringvar vResult := "";
Field 2
whileprintingrecords;
stringvar vResult;
vResult := if {RESULT.UNITS} = "CFU_G"
and {RESULT.ANALYSIS} = "CRA_LIS_ENU_CONF_MPCRAM29"
then {RESULT.FORMATTED_ENTRY}
else if {RESULT.ANALYSIS} = "CRA_LIST_ENU_MPCRAM29"
and {RESULT.UNITS} = "CFU_G"
and vResult = ""
then {RESULT.FORMATTED_ENTRY}
Field 3
whileprintingrecords;
stringvar vResult;
vResult;

Using RecordRef to Work with Multiple Tables

I have a group of tables that I need to the integer key from and I would like to be able to pass in any of them into a single and get the next value for the key.
I believe that RecordRef is the way to do this, but the code so far doesn't seem quite right.
I am trying to build a function that will take a table record and then return an integer value, that integer value will be the next record for the primary key. IE: if the last record's key is is 62825 the function will return 62826.
FunctionA
BEGIN
Id := GetNextId(SalesRecord); //Assignment not allowed
END;
FunctionB
BEGIN
Id := GetNextId(CreditMemoRecord); //Assignment not allowed
END;
GetNextId(pTableReference: RecordRef) rNextId : Integer
BEGIN
CASE pTableReference.NUMBER OF
DATABASE::SalesRecord: BEGIN
//Find last Record
pTableReference.FINDLAST;
lFieldRef := pTableReference.FIELD(1); //Set to the PK field
END;
DATABASE::CreditMemoRecord: BEGIN
//Find last Record
pTableReference.FINDLAST;
lFieldRef := pTableReference.FIELD(10); //Set to the PK field
END;
... //do more here
END; //CASE
EVALUATE(rNextId,FORMAT(lFieldRef.VALUE)); //Get the integer value from FieldRef
rNextId := rNextId + 1; //Add one for the next value
EXIT(rNextId); //return the value
END;
With this code I am getting the error "Assignment is not allowed for this variable." on the Function Call to GetNextId
Idea of the Table Structure:
Table - SalesRecord
FieldId, Fieldname, Type, Description
1 id integer PK
2 text1 text(30)
3 text2 text(30)
4 dec1 decimal
5 dec2 decmial
Table - CreditMemoRecord
FieldId, Fieldname, Type, Description
10 id integer PK
20 text1 text(30)
30 text2 text(30)
40 dec1 decmial
50 dec2 decmial
Just put function like this in both tables
GetNextId() rNextId : Integer
BEGIN
RESET;
FINDLAST;
EXIT(id+1);
END;
an then call it from record variable
FunctionA
BEGIN
Id := SalesRecord.GetNextId();
END;
FunctionB
BEGIN
Id := CreditMemoRecord.GetNextId();
END;
This is common practice I believe.
You mean "GetNextValue" get next record? I don't quite understand your use-case.
If you want to pass in a generic record, then you'll want to use the VARIANT data type. This is a wildcard type that will accept Records from any table, and allow you to return records from any table.
This is untested, but hopefully give you an idea of how they could work;
LOCAL NextRecord(VAR RecVariant : Variant)
IF RecVariant.ISRECORD THEN BEGIN
RecRef.GETTABLE(RecVariant);
// RecRef.NUMBER is useful for Database::"Customer" style comparisons
RecRef.NEXT;
RecRef.SETTABLE(RecVariant); // Might not be necessary
END;

Create a page process to hide a region

I'm having some problems creating a process to hide a region in pl/sql.
Can anyone give a example of how to do it?
Tanks.
If appropriate, you can put the PL/SQL you need directly into the Condition, using the Condition Type "PL/SQL Function Body Returning a Boolean". For example (using your code from above, which doesn't seem quite right to me - all roads lead to hidden=3!):
DECLARE
a NUMBER;
b NUMBER;
hidden NUMBER;
BEGIN
select count(1) into a from TN_HISTORY_ITEMID where itemid in (select id from TN_TREE where pid = (select id from tn_tree where pid =:P1_ID));
select count(1) into b from surv_host_data where id_client = :P1_ID;
if b <> 0 AND a = 0 then hidden := 3;
elsif a = 0 then hidden := 3;
elsif b = 0 then hidden := 3;
else hidden := 3;
end If;
return (hidden = 3);
End;
If you need to do it with a process and a page item, then you need to make sure that the item is rendered before the region, and that the process runs before the region to be hidden is rendered. Otherwise by the time the item is set it will be too late.