Putting the finishing touches to an order entry system this week, we
were frustrated by the apparent unwillingness of one symbolic to update,
whilst those around it had no such qualms.
Looking
at the dictionary items nothing stood out; they were all multivalued,
they all derived their values based upon the code entry. So we decided
to go for the sledgehammer to crack a nut approach and added a
quickevent to the POSCHANGED event. Column 4 doesn't want to update -
we'll tell it to update every single time the user moves cells.
This was sort of successful - but not entirely. Sometimes it worked, sometimes the price column was the only one updated.
In
the Sprezz world, "Sort of" doesn't cut it. So just as we were about to
start coding a POSCHANGED in the commuter routine to update ALL of the
columns we reviewed our options. As is often the way when discussing
problems rather than thinking about problems the solution becamse
obvious. RTI have optimised the semantic logic layer in such a way that
the only symbolics recalculated by default are those that rely on the
column that has just changed.
How do they do that?
We
can't know the exact mechanism but it's safe to guess that they look at
the formula for the symbolic in some way and see if it references the
changed column. They doubtless do this once at Window compilation time
then cache the results. And what was the formula of the non-updating
column?
Because
the calculation was reused elsewhere, we'd moved it off into a function
- which worked well BUT confused the semantic logic layer as now, as
far as it was concerned, the formula was NOT dependent on the code
column.
The initial solution - as inelegant as it seems, was simply to ensure
that the formula contained a reference to the code column so -
et voila now all the symbolics update without any further user intervention.
But
that still didn't really satisfy us
ΜΆΜΆ why should we have to pollute our
dictionary items just to make dependencies within the window work?
Especially as we have an increasing tendency on new systems to move all
symbolic calculations into a control commuter for the table. So we
decided to work out how OI was dealing with these dependencies and
manipulate them ourselves on the form CREATE event.
The
first place to look when trying to establish this sort of information
is always the additional features documentation provided by Revelation -
or the SYSPROG Inserts as they're more commonly known - OIWIN_EQUATES
in this case. Opening this, the area that we're specifically interested
in is the equates for the Control Semantics which are associated with
the Control Map. Scanning this we come to the rubric "* list of controls
to send recalcs to on change" next to column position 14 - CS_RECALC$.
Given
that we're dealing with an edit table here, the information is going to
be somewhat nested! We could have several data columns which in turn
are depended upon by several other symbolics. Describing the structure
in English first - column X of controlSemantics@ contains the
controlSemantic information for the control we have located at X in the
controlMap@.
Value14 of controlSemantics@
contains a subvalued list of information - each subvalue corresponding
to the equivalent data column in the edit table. So if the data control
that was depended upon was in column 3 of the data table, the
corresponding information would be in controlSemantics@.
Now there could be multiple columns dependent on this data column so
their details would be text mark delimited. So the details of the first
dependent column would be in controlSemantics@ the
second in controlSemantics@ etc. Finally the
identification of the data that is dependent consists on the control
name value, and in the case of an edit table the column value. In the
case of an edit control that is not multivalued this is always 1. The
two values are in turn delimited by sub text marks. So if the control in
question were dependent on the 3rd column of the editable and it was
the EDT_PRODUCTS control column 4 then the structure would be
controlSemantics@< X, 14, 3, 4, 1> = "ENQUIRIES.EDT_PRODUCTS"
controlSemantics@< X, 14, 3, 4, 2> = "4"
So finally a code sample showing how we achieved the result we wanted without having to change our dictionary columns.
/*
ensure controlSemantics@ is updated to adjust the selling price
when the product code changes. The product code is tn column 2 of
the edit table and the selling price is In column 4
*/
Equ editTable$ To atWindow : ".EDT_PRODUCTS"
Equ sellingPrice$ To editTable$ : @Stm : 4
Equ codeColumn$ To 2
Locate editTable$ In controlMap@ using @Fm setting controlPos Then
dependsInfo = controlSemantics@< controlPos, CS_RECALC$ >
colInfo = dependsInfo<0, 0, codeColumn$>
Locate sellingPrice$ In colInfo using @Tm setting thereAlready Else
colInfo := @Tm : sellingPrice$
dependsInfo<0, 0, codeColumn$> = colInfo
controlSemantics@< controlPos, CS_RECALC$ > = dependsInfo
End
End
This worked perfectly and lent itself to encapsulation in a function to tweak recalculation dependencies as we saw fit.
2 Comments:
Nice article. We ran into the very same issue because we manage our calculated column logic in the same way as well. It always looked funny to us to introduce a throw away variable just to satisfy the column dependency logic. ;-) Like you we have our own encapsulation processes but we have not yet resolved whether this should be hard-coded, soft-coded, or handled differently. Trying to manage dependencies away from the calculated column itself requires discipline. How are you tackling this?
By Don Bakke, At 15 February 2013 at 00:31
As tempting as it was to ask our framework author to work it out for himself at create time by a combination of naming conventions and tab order it seemed more elegant for the programmer to set a custom property on the CREATE event of the window which in turn is interrogated by the POSTCREATE promoted event to set the actual labelled common. This is pretty similar to what we do with our OPTIONCOLS property which we set on the CREATE event to tell the framework which edittable columns should be hyperlinked.
By Sprezz, At 15 February 2013 at 00:38
Post a Comment
Subscribe to Post Comments [Atom]
<< Home