Oracle EBS R12 - Form Personalization - Disable a particular field - oracleforms

User should not update the Ordered Quantity Fields in the tabs ie (Pricing ,Shipping,Addresses,Returns,Service,Others) if it satisfies a certain condition.
If someone tries to update - just pop-up an error message
"Update not allowed here !!"
I think we can achieve this using Form Personalization.
But I am not sure actually (Trigger Event,Trigger Object,Condition) - how to disable particular field
Kindly Help.
Let me know if you need any more inputs

It depends on your condition, if it depends on record data, if it can change when user changes data, etc.
If the condition is constant during forms session, use WHEN-NEW-FORM-INSTANCE trigger like this
if _condition_ then
set_item_property('your_block.item1', UPDATE_ALLOWED, PROPERTY_FALSE);
set_item_property('your_block.item2', UPDATE_ALLOWED, PROPERTY_FALSE);
...
end if;
if your condition depends on record data, use POST-QUERY trigger in similar way
if _condition_ then
set_item_instance_property('your_block.item1', :SYSTEM.TRIGGER_RECORD, UPDATE_ALLOWED, PROPERTY_FALSE);
set_item_instance_property('your_block.item2', :SYSTEM.TRIGGER_RECORD, UPDATE_ALLOWED, PROPERTY_FALSE);
...
else
set_item_instance_property('your_block.item1', :SYSTEM.TRIGGER_RECORD, UPDATE_ALLOWED, PROPERTY_TRUE);
set_item_instance_property('your_block.item2', :SYSTEM.TRIGGER_RECORD, UPDATE_ALLOWED, PROPERTY_TRUE);
...
end if;
if your condition depends on record data, which can user modify use additional WHEN-VALIDATE-RECORD trigger whith the same code as the POST-QUERY-TRIGGER

Related

MSACCESS, how to edit a record after insert using the "after insert" trigger

MS Office 365 ProPlus, Access 2007 - 2016
I'm trying/failing to change the value of a field in a table after it is inserted using the "after insert" trigger. Something like this...
EditRecord
SetField
Name orig_id
Value = [mytable].[id]
End EditRecord
This doesn't seem to work.
USysApplicationLog gives...
SourceObject = mytable.AfterInsert
DataMacro InstanceID = {489D5697-5247-44A8-AE3C-3773A25F72E5}
Error Number = -20335
Category = Execution
Object Type = Macro
Description = EditRecord failed because the default alias represents a record which is read only.
The field is not read only. After the fact I can edit it just fine. I don't know what the "default alias" is nor what that even means.
If the trigger can't do this, can you think of another way to accomplish the same thing ?
You don't want to use the AfterInsert, since then the record is already saved, and tucked away nicely, and everything you need to change in that record is assumed to have been done. In fact, the default context will cause the record in question to be read only. You CAN get around this by pulling the record again, (looking up a record), but if you modify it again then all of the triggers for that record will fire again.
So I ONLY suggest you use this event to sum() or add/edit OTHER tables, but not the record that was just edited and saved.
If you need/want to update this current record, then move your "edit" or "modify" code to the "BeforeChange". This event not only lets you edit/modify right before the save (and thus preventing endless loops in which the update triggers fire again and again), but the CURRENT record is in full context, and you don't even need any "edit record" command, since you have the fresh un-saved record right in context. You thus can use SetField without the need for EditRecord.
So, the AfterInsert is really too late here, and if you could modify the record in that event, you will cause the AfteUpdate event to fire again if you do use a workaround.
Now, if you use BeforeChange, it will fire for both insert and edits (change). So, if your code really only needs to run when inserting, you can check this status by using
If [isinsert] = True then
Edit
Also, it looks like your code is attempting to save (capture) the previous value, and if it is, then you can use:
[old].[id]
Of course this does not make too much sense for "id", since that is usually an autonumber PK column, but for grabbing other values during an update in the BeforeChange event, you can certainly test + inspect the previous (old) values.

Oracle Forms Execute_query giving FRM-40737 error

I am getting an error
FRM - 40737 - illegal restricted procedure GO_BLOCK in
WHEN-VALIDATE-RECORD trigger.
My Code is
IF event_name = 'WHEN-VALIDATE-RECORD'
THEN
IF (form_name = 'OEXOEORD' AND block_name = 'ORDER')
THEN
-- call procedure to validate and cascade the ship method code.
cascade_ship_method;
execute_query;
END IF;
What am I doing wrong here ?
This is because Oracle Forms has two types of built-in procedures - restricted and unrestricted. Some triggers enable restricted procedures, some not (see Oracle Forms help, every trigger has information which procedures it enables).
Trigger WHEN-VALIDATE-ITEM fires for example when user moves cursor from one record to the other (this is called navigation). In this case it leaves one record and enters other. There is fired following chain of triggers
WHEN-VALIDATE-ITEM
WHEN-VALIDATE-RECORD
POST-ITEM
POST-RECORD
PRE-RECORD
PRE-ITEM
If any of this trigger fails, navigation is canceled and cursor returns to the original item. If you call any procedure, which starts new navigation (like GO_BLOCK), Oracle Forms would not be able to manage first navigation.
This is, why some procedures are restricted.
It might be relevant with content of cascade_ship_method. When I got this error, I had missed an apostrophe in the SET_BLOCK_PROPERTY statement. When I fixed, it worked. This is the correct structure in my code block:
SET_BLOCK_PROPERTY (
'TABLE_A',
default_where,
'column_a= '
|| ''''
|| variable
|| '''');

Save or update record when two dirty forms are based on same recordsource

There are two forms based on a single table named project. Form f_project shows the main project data and form f_phases shows the phase dates.
When a user updates information I need to update the fields edited_by and edit_date.
Form f_project has its Before Update event:
Me!edit_date = Now
Me!edited_by = TempVars!email
Form f_phases has the same. Note that the referenced fields are the exact same table fields.
The problem arises when one form is dirty and the other form tries to run its Before Update event.
You cannot use:
If Forms!f_project.Dirty Then Forms!f_project.Dirty = False
within the Before Update event of the form f_phases (and vice versa). I assume this is because they both have the same recordsource.
Attempting to change f_project's fields from f_phases results in a write conflict because you are also changing the same record within f_phases.
So, what I am trying to do in the end is detect whether the form f_project is dirty and save it prior to the record update made by form f_phases.
Any elegant solutions or workarounds?
The (inelegant) way that I handled this issue is:
Made form f_phases modal so I only have to worry about whether form f_project is dirty.
Added the following code to form f_phases' Before Update event.
If Application.SysCmd(acSysCmdGetObjectState, acForm, "f_project") = acObjStateOpen Then
If Forms!f_project.Dirty = False Then
Me!edit_date = Now
Me!edited_by = TempVars!email
End If
Else
Me!edit_date = Now
Me!edited_by = TempVars!email
End If
Basically what it does is if form f_project is either not open or is not dirty it will update the last edit information. If f_project is dirty it simply does nothing. It allows f_project to handle the last edit update.

MS Access: Auto update fields in same table

Sorry but I'm not very experienced when it comes to things like this.
I have a table called "Measure Table" with the fields "ID", "Proxy" and "ProxyID".
I created a form based on this table. ID is a label pre-populated from the table. Proxy is a drop down menu with the options "For" or "From". ProxyID contains a drop down with the same numbers as ID.
I would like a user to go to a specific record in the form (say for ID:I800), select "For" from the Proxy drop down and then select ProxyID (lets say L800). For the record for L800, I want it to automatically change the proxy to "From" and the ProxyID to I800.
Is this possible in Access?
Thanks so much for any help provided
Here is a visual of what i wnat to happen:
I want the table to look like this before the update(when the user selects "For" and "L800"):
Record# ID Proxy ProxyID
1 I800 For L800
2 L800
Then the table is automaticaly updated to:
Record# ID Proxy ProxyID
1 I800 For L800
2 L800 From I800
Okay, here is the gist of what you need to do to solve your immediate problem (updating the corresponding row in the other table.
Simply add an event handler to the AfterUpdate event of the form to perform the update to the other row. The code should look very similar to this...
Private Sub Form_AfterUpdate()
Dim RelatedID As String
Dim Proxy As String
If (UCase(Me.Form!Proxy) = "FOR") Then
RelatedID = Me.Form!ProxyID
CurrentID = Me.Form!ID
DoCmd.RunSQL ("UPDATE [Measure Table] SET ProxyID='" & CurrentID & "', Proxy='From' WHERE ID='" & RelatedID & "'")
End If
End Sub
Caveats:
As I mentioned in the comments, this data structure is a very bad idea and will create a lot of extra work for you to maintain the data integrity according to the implicit rules you are specifying as a matter of course with this design. I realize you have an existing DB to deal with, but frankly it would probably be less work to fix the DB design than maintain this one in the long run.
Some additional considerations you didn't ask about, but are going to need to deal with:
What happens if someone updates
either of the entries in a pair
directly in the table instead of
using your form? There really isn't a
good way to apply the above logic to run when
except in the context of using the form.
What happens in this code if the related row doesn't exist for some reason?
What happens if the related row "The FROM" row is updated in the form?
What happens if either row is deleted from the table?

MySQL triggers: move to trash

I want to create a trigger in MySQL that will do two things: if forum's topic is located in trash or it is hidden, delete it, elsewhere move the topic to trash. The question is how to stop the delete action in 'before delete' trigger?
I don't know if there's a way to prevent the delete once it has already been called without raising an exception of some sort.
I think a better solution might be instead of calling delete on the record you want to trash/delete you should update a field such as "IsTrashed" to TRUE. And then in the update trigger, see if it was already TRUE and being set to TRUE again (e.g. IF(OLD.IsTrashed && NEW.IsTrashed)). If so, delete it, otherwise move it to the trash.
The only problem that will arise from this method is if you update a different field (e.g. PostDate) of a trashed item, NEW.IsTrashed and OLD.IsTrashed will both be TRUE so it might look like you are trying to delete it, but you are only updating the PostDate. You can either check that this is the only field that was modified (e.g. by checking OLD.SomeField <> NEW.SomeField for every other field) or use a field that will always reset it's value to NULL after an UPDATE statement. Something like "TrashNow". That way if TrashNow ever has a TRUE value, you know that you did intentionally want to trash the field.
However, that "reseting field" is just wasted space, I think the best solution for this problem is a stored procedure... something like:
CREATE PROCEDURE DeletePost (IN APostID INT)
BEGIN
IF ((SELECT InTrash FROM posts WHERE PostID = APostID LIMIT 1))
DELETE FROM posts WHERE PostID = APostID;
ELSE IF
UPDATE posts SET InTrash = TRUE WHERE PostID = APostID;
END IF;
END;
Assuming you have the table posts with the fields PostID (INT) and InTrash (any integer type).
You would call this like so to delete post with PostID 123:
CALL DeletePost(123);