|
|||||||
IConvs / OConvsThis article is to deal with the problems encountered when mixing application specific logic (such as fuzzy searches) with User Defined ICONVs, but before this subject can be dealt with, it is necessary first to consider how R/LIST processes fields with OCONVs. When R/LIST is asked to evaluate an = clause (WITH DATE = "14/05/87") it knows (assuming that DATE has an OCONV of D2/E) that as an exact match has been requested, the value on file will not be 14/05/87, it will be the internal representation of 14/05/87, 7074. Subsequently it will ICONV 14/5/87 using D2/E and use the value returned to compare against the value on file (or on index). If however, R/LIST is asked to evaluate a ] clause (WITH DATE STARTS "14/05") or another partial clause ([] or [) (again assuming that DATE has an OCONV of D2/E) it will not be able to ICONV this data to compare against file. 14/5 does not ICONV correctly, consequently it will have to read each record from disk and OCONV each date to compare the beginning to the entered value. When, instead of a standard system conversion, a User Defined Conversion (UDC) is used on a dictionary item the author had always naively assumed that as R/LIST ICONVed the data to compare with an = clause, it used the ICONV routine nominated on the edit pattern of the dictionary item. This misses the point of User Defined Conversions. They are designed to cope with both ICONVs and OCONVs. R/LIST in fact calls the UDC contained on the OCONV of the dictionary item, passing it a type ICONV. With the introduction of UDCs came the capability to define "edit patterns" (ICONVs) that not only checked that the data was valid but also assisted the user in finding a match for entered invalid data. The most classic cases involve ICONVs which if unable to find an exact match on a code file perform a BTREE.EXTRACT on the description. This is not the forum for a discussion of whether data (represented here by the ICONV) ought to be mixed with the application logic (represented here by the BTREE.EXTRACT logic). The fact remains that many developers have created these type of ICONVs and subsequently encounter problems. Imagine a scenario where the ICONV takes an entered value and if not found on the codes file, looks at the name of the current prompt (in WC_SI%<2> of WINDOW_COMMON%) to derive the popup to use for validation. It then displays a popup and prompts the user to choose the closest match. The user does so and the correctly ICONVed data is returned to the calling program. This works perfectly well in a window environment but can create very real problems when using R/LIST. If the user opts to LIST file WITH UDF.FIELD = "FRED" where FRED is not a valid option, the logic described above will be called into play. The ICONV logic will be called, an attempt will be made to access the WINDOW_COMMON% area to get hold of WC_SI%, and an "Attempt to access Undefined Common" message will be displayed as the system enters the debugger. Using the knowledge derived above, this problem can be easily circumvented. Simply pass the UDC a flag in the optional branch, telling it that it is being called from an OCONV, e.g. Oconv = [UDF,OCONV]. This branch will be passed regardless of whether an OCONV or an ICONV is called. It can thus be tested for explicitly by the ICONV logic in determining whether to use WINDOW_COMMON% (or any form of user prompting) or not. e.g. 0001 * rest of logic assumed to be above 0002 ICONV: 0003 RETURNED = XLATE("CODES",PASSED,1,"X") 0004 IF RETURNED = "" THEN 0005 IF SUBR.LABEL = "OCONV" THEN 0006 * Not in window, don't lookup 0007 RETURNED = PASSED 0008 STATUS() = 1 0009 END ELSE 0010 * LOOKUP sets STATUS() 0011 CALL LOOKUP(PASSED,RETURNED) 0012 END 0013 END (Volume 2, Issue 5, Pages 6,7) |
|||||||
| |||||||