There are only 4 character operators, in their order of precedence:
Operator | Description |
---|---|
() | Parentheses for grouping. Note: VFP documentation, that I have, misses this one. Without this, - operator is almost always useless. |
+ | Concatenates (joins) strings side by side. |
- | Concatenates strings by moving the trailing spaces from left string to the right string's end. |
$ | Checks if first string is contained in second. |
+ is the simpliest and also used to concatenate strings in many other languages.
local firstName, lastName
firstName = "John"
lastName = "Smith"
? m.firstName + " " + m.lastName
Outputs: John Smith
- is a little tricky, and not widely known. It takes trailing spaces from the left string, appends those spaces to the string on the right. Suppose you have a table with first and last names and each of them is 20 characters. We want to concatenate first and last names to create a full name, and we also want the resulting size be fixed (in this case 20 + 20 + 1 space = 41). Let's make it you also have a middle name column and we want the full name look like "lastName, firstName middleName_______". It is easiest to do this using - operator but you should note the trick of using parentheses here for grouping so we get exactly what we want to:
* Create a cursor for our sample and fill in a few names
Create Cursor Names (firstName c(20), midName c(20), lastName c(20))
Insert Into Names (firstName, midName, lastName) Values ('Cetin','', 'Basoz')
Insert Into Names (firstName, midName, lastName) Values ('John', 'M', 'Smith')
Insert Into Names (firstName, midName, lastName) Values ('John', 'F', 'Kennedy')
Insert Into Names (firstName, midName, lastName) Values ('Tom', '', 'Hanks')
* Select with tricky - operator
Select *, ;
lastName - (', '+firstName-(' '+midName)) As FullName ;
from Names ;
INTO Cursor crsNames ;
nofilter
Browse
And the ouput is like this:
firstName | midName | lastName | fullName |
---|---|---|---|
Cetin | Basoz | Basoz, Cetin | |
John | M | Smith | Smith, John M |
John | F | Kennedy | Kennedy, John F |
Tom | Hanks | Hanks, Tom |
In fullName column all the trailing spaces are pushed to the end nicely. If you check the structure fullName column is 63 characters wide (3 * 20 + 3 characters that we added).
Note the importance of grouping parentheses (try removing parentheses or arranging in a different way).
Although - operator might be tempting to use in such cases, there is other side of the coin. This operator is VFP specific and thus the SQL is not portable. You could achieve the same result by this ANSI compatible SQL instead:
Select *, ;
CAST(RTRIM(lastName) +', '+ RTRIM(firstName) +' '+ midName as char(63)) As FullName ;
from Names ;
INTO Cursor crsNames ;
nofilter
Last operator is $. It simply checks if left string is part of right string.
local upcased, digits, hexDigits
upcased = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digits = '0123456789'
hexDigits = m.digits + 'ABCDEF'
? 'A' $ m.upcased && .T.
? 'a' $ m.upcased && .F.
? '1' $ m.digits && .T.
? 'F' $ m.digits && .F.
? 'F' $ m.hexDigits && .T.
Important: In VFP, although you can write your code in any case (upper, lower or mixed), strings are always case sensitive. For example: "Smith" and "smith" are two distinct values. Or in your table if there is a country column, you wouldn't find 'USA' if you search it with 'usa'. Same goes with $ operator, "GE" $ "Germany" is false.
Personal note: Although you might like $ for its simplicity and you may find it often used in Microsoft source codes, IMHO it is of very little value. Thinking about many many thousands of lines I have written in my carrier, I think I would find very few occurences of it in my own code. Almost always there is a better alternative (especially when left operand is not a single character and\or case sensitivity matters).