Find

You will normally use the Find message to find a record and all of its parents. A typical find operation can be described as follows:

  1. Prepare your File Buffer with properly seeded Field values. Note that you prepare the File Buffer and not DDO-Field values (see Understanding File Buffers and DDO Field Buffers).

  2. Send the Find message to the DDO, passing the find mode and find index as parameters.

  3. Check status of the find and react accordingly.

 

A Find actually sends the Request_Find message passing the mode, file-number and index. Request_Find does the actual find performing the following steps:

 

Note that all DEO objects attached to the DDO performing a find will immediately display the results of a find.

When DEOs perform finds they use the Request_Find message. When performing finds in your code you will usually the Find message. The examples shown here show how to use the Find messages for manually coded operations.

The following example shows a typical find operation:

Function FindUser String sCustNo Returns Boolean

    Boolean bFound

    Handle hoDD

    Move oCustomer_DD to hoDD

 

    // Step 1: Prepare the File Buffers for a find

    Send Clear of hoDD

    Move sCustNo to Customer.Customer_Number

 

    // Step 2: Perform the find Operation

    Send Find of hoDD EQ 1

  

    // Step 3: Process the information after the find.

    Move (Found) to bFound

 

    Function_Return bFound

End_Function // SearchUser

The Found indicator is always set after a find. Because this indicator is global and easily changed you should always move the status of this indicator to some other variable.

You can also test if a find succeeded by checking the DDO’s HasRecord function if the DDO buffer did not contain a record prior to the find operation (otherwise, check the Found indicator).

It can also be used to determine if a save will result in a new record save (if HasRecord is false) or an edit of an existing record (if HasRecord is true).

    Send Find      of hoDD EQ 1

    Get  HasRecord of hoDD to bFound

In some cases, you may wish to return the value of the record’s RowId.

Function FindUser String sCustNo Returns RowId

    Rowid  riRecId

    Handle hoDD

    Move oCustomer_DD to hoDD

    // Step 1: Prepare the File Buffers for a find

    Send Clear of hoDD

    Move sCustNo to Customer.Customer_Number

    // Step 2: Perform the find Operation

    Send Find of hoDD EQ 1

    // Step 3: Process the information after the find.

    Get CurrentRowId of hoDD to riRecId

    Function_Return riRecId

End_Function // SearchUser

 

Preparing the File Buffer for the Find

The first step in performing a find is to prepare file buffer for the find. This usually consists of clearing the DDO (send Clear) and then seeding the file-buffer with the information needed to find the record.

Very Important: When you are seeding field values for a find, you must seed the file-buffer and not DDO-field buffer. Do not use the set File_Field_Current_Value message to seed data for a find – it will not work. In this example we cleared the customer DDO and moved a unique Customer identifier into the Customer_Number field. For more about using File-Buffers and DDO-Field Buffers see Understanding File Buffers and DDO Field Buffers.

Send the Find Message

Once the file buffers are prepared, you find the record using the Find message. This message requires that you pass a find mode (LT, LE, EQ, GE, GT, NEXT_RECORD, FIRST_RECORD, or LAST_RECORD) and a find index number. In the above example we are performing a "find equal" using Index 1, which presumably is an index of Customer_Number (if it is not, this find will not work).

After the find, all DEO objects that are attached to any of DDOs involved in the find will be refreshed. The DDOs do this by sending the message Refresh to all DEOs. This is an automatic process of DDOs and makes it very simple for your DEOs to stay synchronized. This also means that your DEOs will change as you find records. If you do not want this behavior see Finding without Updating the DDO.

Check the Status of the Find

If the find succeeds, the data will be loaded into the DDO, CurrentRowId will contain the record’s ID, HasRecord will be true, and the Found indicator will be set to true. If the find failed, the DDO will not be changed and the found indicator will be set to False.

Finding Loops

If you use the Find message to find multiple records, you will usually use a slightly different method of preparing your file buffers. Normally, you will prepare your file buffer for the first find, and perform a find using the "Find greater than or equal to" mode (GE). Successive finds will perform a "Find Greater than" (GT), using the state of the file buffer from the previous find.

Procedure ListUsers

    Handle hoDD

    Move oUser_DD to hoDD

    Send Clear of hoDD

    Send Find of hoDD GE 1

    While (Found)

        Send ProcessThisUser

        Send Find of hoDD GT 1

    Loop

End_Procedure

You can also use FIRST_RECORD and NEXT_RECORD.

Note that Find mode Next_Record will use the same find direction as the prior Find operation. Using find mode Next_Record <B>must</B> be preceded by a find using one of the other modes, or it will result in an error.

Procedure ListUsers

    Handle hoDD

    Move oUser_DD to hoDD

    Send Find of hoDD FIRST_RECORD 1

    While (Found)

        Send ProcessThisUser

        Send Find of hoDD NEXT_RECORD 1

    Loop

End_Procedure

Instead of clearing the DDO and using GE, you can also use FIRST_RECORD (or LAST_RECORD with LT, if you wished to find in reverse order).

Procedure ListUsers

    Handle hoDD

    Move oUser_DD to hoDD

    Send Find of hoDD FIRST_RECORD 1

    While (Found)

        Send ProcessThisUser

        Send Find of hoDD GT 1

    Loop

End_Procedure

A word or caution when using the Found indicator. This indicator is global and is easily changed. If you are using this, you should only use it immediately after a find operation. If you have additional commands or messages between the find and the test of the Found indicator, you may be testing on a Found value that was changed by some other process. The following code may not work as expected:

// this demonstrates improper technique

Procedure ListUsers

    Handle hoDD

    Move oUser_DD to hoDD

    Send Find of hoDD FIRST_RECORD 1

    While (Found)

        Send ProcessThisUser

        Send Find of hoDD GT 1

        Send LogLineChange // THIS COULD CHANGE FOUND!!!

    Loop

End_Procedure

In the situation where Found may be altered by other processes, you should immediately move this value to another variable as follows:

// this demonstrates a proper technique

Procedure ListUsers

    Handle hoDD

    Boolean bOK

    Move oUser_DD to hoDD

    Send Find of hoDD FIRST_RECORD 1

    Move (Found) to bOK

    While (bOK)

        Send ProcessThisUser

        Send Find of hoDD GT 1

        Move (Found) to bOK

        Send LogLineChange

    Loop

End_Procedure

It is considered good programming practice to always move the Found indicator to a local variable.

You will primarily use finding loops like this in non-DEO batch processes. If you use this with DDOs that have DEOs, the DEOs will get refreshed with every find – probably not something you want.

See Also

Find and Clear Operations in DDOs