In order for this site to work correctly, and for us to improve the site, we need to store a small file (called a cookie) on your computer.
By continuing to use this website, you agree to our cookies and privacy policy.
  
Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel

IConvs / OConvs

This 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)
Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel