« Back to University of Vienna - OMILAB

oldval with the Event AfterEditAttributeValue

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Dear ADOxx.org Team,

I would like to be aware of the attribute value _before_ it has been _changed_ but only if the change has been performed _by the modeler_.
So actually, I would need the "oldval" which is present in the "SetAttributeValue" event within the "AfterEditAttributeValue" event as i am only interested in the attribute values that have been changed by the modeler.
I tried to store the oldval in a global variable every time the "SetAttributeValue" event occurs, unfortunately, the event is not fired whenever the user changes e.g. the name of an object. By contrast, changing the position attribute value triggers the "SetAttributeValue" event.

Any help would be highly appreciated!
Thansk in advance!

RE: oldval with the Event AfterEditAttributeValue
Answer
8/13/14 9:54 AM as a reply to Anonymous.
Dear UNIVIE Team,

summing up the information in our online help documentation (see here for further information: http://www.adoxx.org/AdoScriptDoc/index.html), the two events have the following specification:

SetAttributeValue:
This is the generic event, that is triggered in case of a change of an attribute, independent of the origin.

AfterEditAttributeValue:
This is the event triggered by changes of a modeller/user of the toolkit. The difference to the above is, that attribute value changes which are not initiated by the user, e.g.
by import, trigger a “SetAttributeValue” event, but not an “AfterEditAttributeValue” event.

Event Timing:

An “AfterEditAttributeValue” event is always triggered later than the corresponding “SetAttributeValue” event.

Certain restriction are related to the AfterEditAttributeValue and SetAttributeValue events, due to internal logic related to uniqueness conditions of elements.
+ The "Name" attribute triggers the AfterEditAttributeValue, but no SetAttributeValue
+ For "SetAttributeValue", the original value (as string) is returned. This is the core internal value (not UI value). For attributes of type RECORD this is always an empty string. If the new value is needed, this can be be determined via the "Core" MessagePort.

As a small showcase of the above, please find enclosed an implementation of a change history tracking mechanism - in the event of a change of attribute, the old value and additional information on the change are stored in an attribute of type "LONGSTRING" - this update is triggered by the script and does not result in a recursive call. The "Name" attribute issue is mitigated by the implementation. The implementation uses the debugging facility as introduced here http://www.adoxx.org/live/faq/-/message_boards/message/18583. The code snipplet needs to be added to the library attribute "External coupling" of the dynamic library.

The sample implementation is also available in the SVN at https://www.adoxx.org/svn/all-repo/5_ADOxx_SupportLibraries_ADOxx13UL1/AfterEditAttributeValueEvent_ADOxx13UL1/ as ABL and ALL.


 1ON_EVENT "AppInitialized" {
 2  # create the dockable window for the output stream
 3  CC "AdoScript" CREATE_OUTPUT_WIN winid:"EVENTLOG" title:"Event Logging"
 4
 5  # establish a global procedure as a helper implementation for timestamped logging
 6  PROCEDURE global EVENT_LOG msgType:string message:string {
 7    CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"
 8    SET currentDateTime: ((date) + " " + (time))
 9    CC "AdoScript" OUT winid:"EVENTLOG" text: ("[" + (msgType) + "@" + currentDateTime + "]: " + (message) + "\n")
10  }
11  # Initial event log message for the "AppInitialized" event
12  EVENT_LOG msgType:"EVENT_LOG" message: ("AppInitialized")
13  # Perform other things for the event
14}
15
16ON_EVENT "AfterEditAttributeValue" {
17  # log to console
18  EVENT_LOG msgType:"EVENT_LOG" message: ("AfterEditAttributeValue with parameters instid: "  + STR instid + " attrid: " + STR attrid + " modelid: " + STR modelid + " attrtypeid: " + STR attrtypeid)
19  # attrtypeid:
20  # 0 INTEGER, 1 DOUBLE, 2 STRING, 3 DISTRIBUTION, 4 TIME, 5 ENUMERATION, 6 ENUMERATIONLIST, 7 LONGSTRING, 8 PROGRAMCALL, 9 INTERREF, 10 EXPRESSION, 11 RECORD, 12 ATTRPROFREF, 13 DATE, 14 DATETIME, 15 CLOB
21  # update change history
22  CC "Core" GET_ATTR_VAL objid: (instid) attrname:"Change history"
23  SET sChangeHistory: (val)
24  # get changing user
25  CC "Application" GET_USER
26  SET sUser: (user)
27  # get attribute name
28  CC "Core" GET_ATTR_NAME attrid: (attrid)
29  SET sAttrName: (attrname)
30  # get change date
31  CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"
32  SET sCurrentDateTime: ((date) + " " + (time))
33  # update change history
34  # add a line break if change history is not empty
35  SET sNewChangeHistory:""
36  IF (LEN sChangeHistory > 0) {
37    SET sNewChangeHistory: (sChangeHistory + "\n")
38  }
39  # the "Name" attribute needs different treatment, since it is the uniqueness identifier. No "SetAttributeValue" is triggered, therefore no oldval is available
40  IF (sAttrName = "Name") {
41    SET sNewChangeHistory: (sNewChangeHistory + "The name has been changed by user:\"" + sUser + "\"")
42  }
43  ELSE {
44    SET sNewChangeHistory: (sNewChangeHistory + "Value of attribute \""+sAttrName+"\" until: " + sCurrentDateTime + ": " + sAttrOldValue + ", changed by user:\"" + sUser + "\"")
45  }
46  CC "Core" SET_ATTR_VAL objid: (instid) attrname:"Change history" val: (sNewChangeHistory)
47  # Perform other things for the event
48  # ....
49}
50
51ON_EVENT "SetAttributeValue" {
52  # log to console
53  EVENT_LOG msgType:"EVENT_LOG" message: ("SetAttributeValue with parameters instid: "  + STR instid + " attrid: " + STR attrid + " modelid: " + STR modelid + " attrtypeid: " + STR attrtypeid + " oldval: " + oldval)
54  # attrtypeid:
55  # 0 INTEGER, 1 DOUBLE, 2 STRING, 3 DISTRIBUTION, 4 TIME, 5 ENUMERATION, 6 ENUMERATIONLIST, 7 LONGSTRING, 8 PROGRAMCALL, 9 INTERREF, 10 EXPRESSION, 11 RECORD, 12 ATTRPROFREF, 13 DATE, 14 DATETIME, 15 CLOB
56  # remember the OLD value as a global variable
57  SETG sAttrOldValue: (oldval)
58
59  # Perform other things for the event
60  # ....
61}

RE: oldval with the Event AfterEditAttributeValue
Answer
8/14/14 4:47 AM as a reply to Wilfrid Utz.
Thank you!