This particular time the client had an issue with a multi page form. Under most circumstances the data displayed correctly but under - as yet undetermined circumstances - the data display would become corrupt. Data would appear in edit fields that belonged in other edit fields and existing data would be overwritten by seemingly unrelated data.
Approaching the issue logically, we installed break points to ensure that what was read from disk was correct and sure enough @Record and the ATRECORD and RECORD properties all contained what they should. It was only when a certain field was filled in that the data became corrupt. Through much testing we were able to determine which field had to be filled in to cause the corruption but it still made no sense. To illustrate using the AVERY_LABELS table (the client's data is commercially sensitive so we can't use screenshots from their system). In the example below the Cross Reference column references another row in the AVERY_LABELS table and extracts the product description.
LIST 100 AVERY_LABELS PRODUCT_DESC XREF_DESC SEQUENCE and were rewarded with something like
which was NOT what we would have expected to see. So we decided that the XREF_DESC formula must have been to blame in some way. Looking at it, it SEEMED to be straightforward enough :-
Until we looked REALLY closely... the column is called PRODUCT_DESC not PRODUCT_DESCS$. When we changed the spelling to the correct one - AVERY_LABELS$PRODUCT_DESC$ everything was right with the world again - the screen displayed correctly and the LIST statement produced
A major change in OI over AREV is that when the system WRITEs the current screen contents to disk, it does not simply write the contents of @Record onto disk as in AREV, rather it takes the current row from disk and updates ONLY those columns that feature in the current Window. THEN it writes the row back. This allows the user to have multiple windows open updating separate sections of the same current row.
To do this the Window processor has to maintain its own pseudo @Record, just containing the contents of the current screen. To illustrate using the pseudo code for a READ and populate operation
pseudoRecord = ""
for loopPtr = 1 to controlCount
control = controlList< loopPtr >
dictColumn = get_Property( control , "COLUMN")
pseudoRecord := xlate( dataTable, @Id, dictColumn, "X") : @Fm
next
pseudoRecord[-1, 1] = ""
for loopPtr = 1 to controlCount
control = controlList< loopPtr >
call set_Property( control, "DEPFROP", pseudoRecord< loopPtr >)
next
for loopPtr = 1 to controlCount
control = controlList< loopPtr >
dictColumn = get_Property( control , "COLUMN")
pseudoRecord := xlate( dataTable, @Id, dictColumn, "X") : @Fm
next
pseudoRecord[-1, 1] = ""
for loopPtr = 1 to controlCount
control = controlList< loopPtr >
call set_Property( control, "DEPFROP", pseudoRecord< loopPtr >)
next
In the original dictionary item the XLATE destination column was incorrectly spelt, so at compile time in the Table Builder the equate would NOT have been replaced with a column number, but with a blank. The Table Builder compiler before OI 10 does not include the error checking that the System Editor has. So the XREF_DESC formula was resolving to
@Ans = Xlate("AVERY_LABELS", {CROSSREF}, "", "X")
which returns the entire row, not just an individual column. So instead of pseudoRecord containing
1 : @FM : 8 : @FM : 3 : @FM : Xlated 8 : @FM : 2 : @FM : 17 : @FM : 10 : @FM : 16
it contained
1 : @FM : 8 : @FM : 3 : @FM : Xlated 1 - 43 : @FM : 2 : @FM : 17 : @FM : 10 : @FM : 16
thereby pushing the subsequent SET_PROPERTY DEFPROP out of kilter.
Obvious with hindsight but not the easiest bug in the world to track down on a system written by someone else!
No comments:
Post a Comment