Macro operator example
The first example stores the value of a setting at the beginning of a function, and restores it at the end.
function findMatch( xArg )
local lRet
private cExact // Can't be local for macro substitution
cExact = set( "EXACT" ) // Store "ON" or "OFF" to character variable
set exact on
lRet = seek( xArg ) // Does exact match exist?
set exact &cExact // Either "set exact ON" or "set exact OFF"
return lRet
The second example converts the value of a control in a form into a literal value to be used in a filter. The filter cannot refer to the control directly, because the value of the form reference varies depending on what form has focus at any given moment.
function setFilter_onClick( )
private cFltr
cFltr = form.cityCombobox.value // Store string in private variable
set filter to CITY == "&cFltr"
Note the use of macro substitution inside a quoted string. For example, if the value of the combobox is "Dover", then the variable is assigned the value "Dover". The result of the macro substitution would then be the statement:
set filter to CITY == "Dover"
The third example uses macro substitution to refer to a control by name through a variable.
local f
private c, g
f = new Form( )
g = f // g and f both point to same form
f.button1 = new PushButton(f)
c = "1"
? g.button&c..className // Displays "PUSHBUTTON"
? f.button&c..className // Error: Variable undefined: F
This creates a form with a single button. Two variables refer to this form, one private variable, and one local variable. In the first macro substitution statement, the value of the variable c is substituted. There are two periods following the variable. The first is to terminate the macro, and the second is the actual dot operator. This results in:
? g.button1.className
The second macro substitution works the same, but the statement fails because the local variable f is not in scope when the statement is executed. However, this approach is actually unnecessary because you can refer to controls by name with a variable through the form’s elements array:
? f.elements[ "button" + c ].className
Without macro substitution, you avoid potential problems with local variables.
Finally, continuing the previous example, compare these statements that attempt to assign to a property using macro substitution:
local cText
cText = "OK"
g.button&c..text := cText // Has both & and . to left of assignment; won't compile
private cVar
cVar = "g.button" + c + ".text"
&cVar := cText // Compiles, but fails at runtime; local variable out-of-scope
private cStmt
cStmt = cVar + " := cText" // Try macro substituting entire statement
&cStmt // Fails; local variable out-of-scope
cStmt = cVar + [ := "] + cText + ["] // Build entire statement with no locals
&cStmt // This works
g.elements[ "button" + c ].text = cText // But this is still easier to use