Using the CAN-FIND function
- Last Updated: March 30, 2020
- 4 minute read
- OpenEdge
- Version 12.2
- Documentation
Using the CAN-FIND function
Often you need to verify the existence of a record without retrieving
it for display or update. For example, your logic might need to
identify each Customer that has at least
one Order, but you might not care about retrieving
any actual Orders. To do this, you can use
an alternative to the FIND statement that is more
efficient because it only checks index entries wherever possible
to determine whether a record exists, without going to the extra
work of retrieving the record itself. This alternative is the CAN-FIND built-in
function. CAN-FIND takes a single parameter, which
can be any record selection phrase. The CAN-FIND function
returns TRUE or FALSE depending
on whether the record selection phrase identifies exactly one record
in the database.
For example, imagine that you want to identify all Customers that placed Orders as early as 1997. You don't need to retrieve or display the Orders themselves, you just need to know which Customers satisfy this selection criterion. The following simple procedure accomplishes this:
|
This procedure uses a little display trick you haven't seen before.
If the Customer has any Orders for 1997,
then the procedure displays the Customer name. Otherwise,
it displays the text phrase No 1997Orders.
If you include that literal value in the DISPLAY statement,
it displays in its own column as if it were a field or a variable.
To display it in place of the Name field,
use the at-sign symbol (@). The following figure shows the result.

The CAN-FIND function takes the argument FIRST
Order OF Customer WHERE OrderData < 1/1/98.
Why is the FIRST keyword necessary? The CAN-FIND function
returns TRUE only if exactly one record satisfies
the selection criteria. If there's more than one match, then it
returns FALSE—without error—just as it would if
there was no match at all. For example, if you remove the FIRST keyword
from the example procedure and change the literal text to be No
unique 1997 Order, and rerun it, then you see that most Customers have
more than one Order placed in 1997:
|
After you page through the results, you see just a few records that don't satisfy the criteria, as shown in the following figure.

Because you don't get an error if there's more than one match,
it's especially important to remember to define your selection criteria
so that they identify exactly one record when you want the function
to return TRUE.
The CAN-FIND function is more efficient than
the FIND statement because it does not actually
retrieve the database record. If the selection criteria can be satisfied
just by looking at values in an index, then it doesn't look at the
field values in the database at all. However, this means that the
record referenced in the CAN-FIND statement is
not available to your procedure. For example, this variation on
the example tries to display the OrderDate from
the Order record as well as the Customer fields:
|
This results in the error shown in the following figure, because
the Order record is not available following
the CAN-FIND reference to it.

If you need the Order record itself then you must use a form that returns it to you:
|
When you run this code, you see the OrderDate as well as the Customer fields except in those cases where there is no Order from 1997, as shown in the following figure.

The samples so far have shown the CAN-FIND function
in an IF-THEN statement. You can also use it anywhere
where a logical (TRUE/FALSE) expression
is valid in a WHERE clause, such as this:
|
The next section continues the discussion on building complex procedures, with details on record buffers and record scope.