Las macrosustituciones deben ser evitadas porque son muy lerdas, siempre que sea posible.
Ejemplo:
lcString = "1236.41"
? VAL(m.lcstring) && función específica
lnNumeric = VAL(m.lcstring)
? VARTYPE(lnNumeric) && "N"
lnNUmeric = EVALUATE(m.lcstring)
? VARTYPE(lnNumeric) && "N"
? lnNUmeric
Evaluate() es una función muy poderosa, aunque debe utilizarse allí donde corresponda.
Fijate en este ejemplo:
LOCAL a,b,h
a = 30
b = 0.35
h = 120
lcString_Form = "a * b + h"
lnResult = EVALUATE(m.lcstring_form)
? lnREsult
Entonces puede que tenga la fórmula de lcSTring_form en una tabla, y que en el proceso, previamente le asigne valor a las variables y con EVALUATE() se determina el valor. Este método es utilizado en escenarios donde el cálculo puede variar de acuerdo a términos comerciales, disposiciones legales o convencionales, etc. (Ejemplo, cálculo de sueldos, cálculo de tarifas de transporte, etc.)
También con EVALUATE se puede revelar el valor de un cursor cuyo nombre se desconoce, o de un campo cuyo nombre puede variar.
lcCursor = "CursorEnUso"
lcCampo = "MiCampo"
lxValor = EVALUATE(m.lcCursor + "." + m.lcCampo)
Para el caso, como conocemos el nombre, podría ser
lxValor = EVALUATE(m.lcCursor + ".MiCampo")
Y por qué ignoramos el nombre de un cursor?. Bueno, en un procedure que determina algún cálculo, el nombre del cursor puede venir como parámetro para independizarse del origen de datos.
lcNombreCliente = Ret_NombreCliente(Alias() , 3 )
PROCEDURE Ret_NombreCliente
LPARAMETERS tcCursor , tnField
* Ejemplo
* tcCursor = "CLIENTES"
* tnField = 3
RETURN EVALUATE(m.lccursor + "."+FIELD(m.lnfield,m.lccursor))
En cambio, la macrosustitución se debe utilizar en un caso como este
loREsp._Items = m.lnItems
lcString = LEFT(m.lcString,LEN(m.lcString)-1)
TEXT TO lcSelect TEXTMERGE NOSHOW PRETEXT 15
SELECT <<lcString>> FROM <<tcCursor>> WHERE <<tcIncluye>> INTO ARRAY laSum
ENDTEXT
&lcSelect
lnTally = _tally
A muchos le parece más elengante la función EXECSCRIPT(), pero tiene la penalización del tiempo: Esta poderosa función escribe un archivo prg y crea la versión objeto (fxp) que es la que entiende Visual Fox. Por eso en este caso será más rápida la macrosustitución.
EXECSCRIPT() debe reservarse para el caso en que se necesiten ejecutar varias líneas de código, separadas por CHR(13), cuando este código deba generarse dentro del programa, o pueda ser generado por un usuario experto en alguna tabla. Puede recibir parámetros y devolver un valor, cosa que no puede esperarse de la macrosustitución.
Acá va una muestra sencilla de lo que puede hacer Execscript()