Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

If

This is the original branching command. It lets you choose between two paths of action based on a condition. If the condition is true, you follow the first path. If it’s not true, you take the second path. IF can only be used in programmatic code. To have conditional code in an expression, use IIF().

Usage

IF lCondition [ THEN ]
     Commands
[ ELSE
     Commands ]
ENDIF

If lCondition is true, the commands on the lines immediately after the IF are executed. There are two possibilities for what happens if the condition isn’t true. If an ELSE clause appears, the commands following ELSE are executed. If there’s no ELSE, no commands are executed and we continue after the ENDIF.

Visual FoxPro introduced a new wrinkle in IF. Conditions can no longer be divided into true or false—they might be null. If lCondition is null, the ELSE branch is taken.

The optional THEN keyword was added in VFP 5 … sort of. Until VFP 5, FoxPro read IF lines until it found something that didn’t seem to be valid code. At that point, it assumed the rest of the line was a comment, even without a comment indicator. (See NOTE for more on this topic.) When VFP 5 limited that ability to lines containing only keywords, people who’d always included THEN after an IF were left out in the cold. Microsoft took pity on them and made the THEN keyword legal at the end of the IF line.

Example

* move forward, but don't end up at EOF
SKIP
IF EOF()
   GO BOTTOM
ENDIF

* print one message for kids - another for adults
IF YEAR(DATE()) - YEAR(dBirthdate) < 21
   ? "Come see our incredibly cool new gizmos"
ELSE
   ? "Come in now for amazing bargains"
ENDIF

FoxPro uses a “short circuit” way of evaluating lCondition. As soon as it’s clear what the final result will be, FoxPro stops evaluating. This can be a handy shortcut, but it’s a double-edged sword. You’ll run into trouble if you depend on anything after the first portion of an IF to be evaluated. Here’s an example of the good side of this behavior:

SELECT Transactions
IF NOT EOF() AND Transactions.lPrint
   * Print out this record
ENDIF

In this example, we count on the NOT EOF() test being passed before we check the field lPrint. Now the down side:

IF lCondition AND MyUDF()
   * do something
ENDIF

In this example, we have to keep in mind that MyUDF() is called only when lCondition is true, so we shouldn’t be counting on something to happen in MyUDF() every time we execute the IF. Similarly, when testing your code, make sure you test all combinations of conditions. If you’ve tested your code when the first few conditions always cause a branch, you may not detect problems at the end of your test:

IF MyUDF() OR HerUDF() OR TheirUDF() OR Syntax Error
   * do something
ENDIF

The code above will work fine until the first three functions each return .F.

IFs can be nested one inside another. If you find yourself nesting a whole series of Ifs, though, take a look at DO CASE—it may be more appropriate for the situation.

See Also

Do Case, IIf()