什么时候必须用宏替换,什么时候只用变量就可以了?

aikill 2005-10-13 05:03:38
在一些命令或函数中有时候只用变量就可以了,有时候必须用宏替换。经常因为这个而反复调试程序,郁闷中。
谁能总结一下到底什么情况下需要用什么情况下不需要用?
...全文
342 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
aikill 2005-10-17
  • 打赏
  • 举报
回复
最好是给个总结性的东西,而不是一些个别的例子
aikill 2005-10-17
  • 打赏
  • 举报
回复
函数和过程是什么样的一种情况呢?
aabiao 2005-10-15
  • 打赏
  • 举报
回复
VFP有了名称表达式,尽量不要用宏,只有少量地方必须用宏:如:SET XXX TO后面的值
●所有变量名、数组名、字段名、文件名等,以及他们的列表的,直接用名称表达式(表达式加括弧)
●表达式计算,使用EVAL()函数
十豆三 2005-10-14
  • 打赏
  • 举报
回复
这个例子就是呀:

STORE 'customer' TO gcTableName
STORE 'company' TO gcTagName
*----
USE &gcTableName ORDER &gcTagName &&要用变量gcTableName和gcTagName的值作为命令行一部分
*----
但是可以使用名称表达式代替:

USE (gcTableName) ORDER (gcTagName)
aikill 2005-10-14
  • 打赏
  • 举报
回复
apple_8180(十豆三) 兄:
哪些情况下变量的值当一个关键字使用呢?
zsjiaming 2005-10-13
  • 打赏
  • 举报
回复
(1)如果是单独的名称表达式的变量..就可以用(变量)
use (dbfname) in 0
go bottom in (dbfname)
select (dbfname)
create cursor (dbfname) ( pro_name c(20)....)
(2)如果这个变量是一个表达式中的'串'的一部分,这里要用宏
use &dbcname.!&dbfname in 0 &&为里不能用名称表达式 ()
或者
dbffullname=dbcname+'!'+dbfname
use (dbffullname) in 0

串中组合,就不能用名称表达式
for i=1 to 10
kk=alltrim(str(i))
thisform.label&kk.caption="test--"+kk
endfor






十豆三 2005-10-13
  • 打赏
  • 举报
回复
转帖:

这一章我们来学习FOXPRO的一个十分强大而又非常容易掌握的功能:宏替换。就从名字上看来这不是个容易对付的家伙,在开始讲宏替换之前,让我们先来看一看这样的一个例子:

假设我们有两个表,1997级学生成绩表(1997.DBF)和1999级学生成绩表(1999.DBF)。这时我们要求用户在浏览表之前先输入年份,以便我们来打开用户指定年度的学生成绩表。也许你会说:“这太容易了,俺会呀”然后给出下面的方案:

先用一个文本框来接收用户的输入的年份,然后调用下面的代码来打开表:

DO CASE
CASE THISFORM.TEXT1.VALUE = '1997'
USE ‘1997.DBF'
CASE THISFORM.TEXT2.VALUE = '1999'
USE '1999.DBF'
ENDCASE
BROW


不错,您的这段代码表面上是达到了要求。但是它存在着几个问题:

问题1:当学生成绩表很少时(如:上例只有1997.dbf和1999.dbf两个表),用上面的代码可以轻松摆平。但是如果表很多时,假设有十个年度的学生成绩表(1980.DBF---1990.DBF)。这下惨了,代码就会变成下面的样子:

DO CASE
CASE THISFORM.TEXT1.VALUE = '1980'
USE '1980.DBF'
CASE THISFORM.TEXT2.VALUE = '1981'
USE '1981.DBF'
CASE THISFORM.TEXT2.VALUE = '1982'
USE '1982.DBF'
CASE THISFORM.TEXT2.VALUE = '1982'
USE '1982.DBF'
……
……
*为了节省你的网费,我的纸,我就不继续打了,我想您应该明白哪些麻子……代表什么了吧……
ENDCASE


这样一来代码非常的冗长。但这还不是最糟的,更惨的在下面(天啊~~)。

问题2:当随着学生的升学,用来保存学生每年学习成绩的表也会动态的增加,这时上面的代码就完全失去了做用。用上面的代码无法预先知道到底会有多少个学生成绩表,也就不可能事先设N个CASE来判断年份了。

宏替换:“不要担心,少要害怕,俺宏替换来也”。宏替换是FOXPRO为我们提供的一项强大的功能。它的运算符是“&”,作用就是提取字符串的现值,返回值是字符串常数。

看到这里您的第一反应可能会是:“WHAT?什么乱七八糟的,你说的是什么意思?”。

别忙,接着往下看您就明白了。下面就让我们用宏替换功能来完成上面例子的功能,是又好又省事儿,包您满意。这次假设我们有20个表(1980.DBF一2000.DBF)分别存放每一年的学生成绩,放心我们绝对不会用20个CASE的:

C_YEAR = THISFORM.TEXT1.VALUE &&用变量C_YEAR来接收用户输入的年份。
USE &C_YEAR
*上面这一句利用宏替换来根据C_YEAR的值来找打开对应的表,等价于
*Use ‘1999.dbf’,只不过引号的表名是随C_YEAR的值而变罢了
BROW


搞定,收工。嘿。。。。。。。。怎么样,是不是又省时又省力呀?

再看下面的例子:

a='b'
b='庄稼'

?a &&显示的结果是“b”
?&a &&显示的结果是“庄稼”

也就是说宏替换将当前变量的值作为真正需要的变量,并返回这个变量的值。

VFP 的很多命令的某些地方不能使用变量,比如上面的 use 命令,你不能写成:

a='1997.dbf'
use a

这样就成了打开 a 这个表,这时就必须用宏替换,

use &a

类似的还有当 locate for 后面跟的条件不是固定的,你的程序可以允许操作者选择不同的字段来查询,可能是:

姓名=...

也可能是:

电话=...

你不能直接把 for 后面的内容整个作为一个变量,这时宏替换也可以起作用,你可以把条件整个放入一个变量,比如字段名放在一个变量中 zdm,要查的内容放在 nr:

tj=zdm+"'"+nr+"'"
locate for &tj

如果这时 zdm='姓名',nr='庄稼',这就相当于:

locate for 姓名='庄稼'

那么只要 tj 的内容是个正确的逻辑表达示,不论是什么内容都可以运行,这将给编程带来很大方便。

多学一招
你甚至可以把整条语句放入一个变量:

tj="locate for "+zdm+"'"+nr+"'"
&tj

酷吧!


 

注意
值得注意的是,宏替换&不能递归的引用自已。比如下面的用法就是错误的:

STORE “&ZL” TO ZL
?&ZL


赋值语句与宏替换巧妙地组合,能实行灵活的查询和程序控制,提高程序通用性,使程序更加简练,运行效率更高,龙其在处理一些不确定对象时,宏替换将扮演非常重要角色。

最后补充一点,虽然宏替换功能强大,但是也不要太频繁使用,正是由于宏替换灵活性,使得它执行时要进行一些转换,如果太多的使用宏替换 可能会影响程序的性能。

所以在一些不是必须的场合下,尽量避免使用宏替换 ,就象好吃的东西吃得多了也会起腻一样,宏替换用的太多也会使你的程序不舒服的。
十豆三 2005-10-13
  • 打赏
  • 举报
回复
转帖:

这一章我们来学习FOXPRO的一个十分强大而又非常容易掌握的功能:宏替换。就从名字上看来这不是个容易对付的家伙,在开始讲宏替换之前,让我们先来看一看这样的一个例子:

假设我们有两个表,1997级学生成绩表(1997.DBF)和1999级学生成绩表(1999.DBF)。这时我们要求用户在浏览表之前先输入年份,以便我们来打开用户指定年度的学生成绩表。也许你会说:“这太容易了,俺会呀”然后给出下面的方案:

先用一个文本框来接收用户的输入的年份,然后调用下面的代码来打开表:

DO CASE
CASE THISFORM.TEXT1.VALUE = '1997'
USE ‘1997.DBF'
CASE THISFORM.TEXT2.VALUE = '1999'
USE '1999.DBF'
ENDCASE
BROW


不错,您的这段代码表面上是达到了要求。但是它存在着几个问题:

问题1:当学生成绩表很少时(如:上例只有1997.dbf和1999.dbf两个表),用上面的代码可以轻松摆平。但是如果表很多时,假设有十个年度的学生成绩表(1980.DBF---1990.DBF)。这下惨了,代码就会变成下面的样子:

DO CASE
CASE THISFORM.TEXT1.VALUE = '1980'
USE '1980.DBF'
CASE THISFORM.TEXT2.VALUE = '1981'
USE '1981.DBF'
CASE THISFORM.TEXT2.VALUE = '1982'
USE '1982.DBF'
CASE THISFORM.TEXT2.VALUE = '1982'
USE '1982.DBF'
……
……
*为了节省你的网费,我的纸,我就不继续打了,我想您应该明白哪些麻子……代表什么了吧……
ENDCASE


这样一来代码非常的冗长。但这还不是最糟的,更惨的在下面(天啊~~)。

问题2:当随着学生的升学,用来保存学生每年学习成绩的表也会动态的增加,这时上面的代码就完全失去了做用。用上面的代码无法预先知道到底会有多少个学生成绩表,也就不可能事先设N个CASE来判断年份了。

宏替换:“不要担心,少要害怕,俺宏替换来也”。宏替换是FOXPRO为我们提供的一项强大的功能。它的运算符是“&”,作用就是提取字符串的现值,返回值是字符串常数。

看到这里您的第一反应可能会是:“WHAT?什么乱七八糟的,你说的是什么意思?”。

别忙,接着往下看您就明白了。下面就让我们用宏替换功能来完成上面例子的功能,是又好又省事儿,包您满意。这次假设我们有20个表(1980.DBF一2000.DBF)分别存放每一年的学生成绩,放心我们绝对不会用20个CASE的:

C_YEAR = THISFORM.TEXT1.VALUE &&用变量C_YEAR来接收用户输入的年份。
USE &C_YEAR
*上面这一句利用宏替换来根据C_YEAR的值来找打开对应的表,等价于
*Use ‘1999.dbf’,只不过引号的表名是随C_YEAR的值而变罢了
BROW


搞定,收工。嘿。。。。。。。。怎么样,是不是又省时又省力呀?

再看下面的例子:

a='b'
b='庄稼'

?a &&显示的结果是“b”
?&a &&显示的结果是“庄稼”

也就是说宏替换将当前变量的值作为真正需要的变量,并返回这个变量的值。

VFP 的很多命令的某些地方不能使用变量,比如上面的 use 命令,你不能写成:

a='1997.dbf'
use a

这样就成了打开 a 这个表,这时就必须用宏替换,

use &a

类似的还有当 locate for 后面跟的条件不是固定的,你的程序可以允许操作者选择不同的字段来查询,可能是:

姓名=...

也可能是:

电话=...

你不能直接把 for 后面的内容整个作为一个变量,这时宏替换也可以起作用,你可以把条件整个放入一个变量,比如字段名放在一个变量中 zdm,要查的内容放在 nr:

tj=zdm+"'"+nr+"'"
locate for &tj

如果这时 zdm='姓名',nr='庄稼',这就相当于:

locate for 姓名='庄稼'

那么只要 tj 的内容是个正确的逻辑表达示,不论是什么内容都可以运行,这将给编程带来很大方便。

多学一招
你甚至可以把整条语句放入一个变量:

tj="locate for "+zdm+"'"+nr+"'"
&tj

酷吧!


 

注意
值得注意的是,宏替换&不能递归的引用自已。比如下面的用法就是错误的:

STORE “&ZL” TO ZL
?&ZL


赋值语句与宏替换巧妙地组合,能实行灵活的查询和程序控制,提高程序通用性,使程序更加简练,运行效率更高,龙其在处理一些不确定对象时,宏替换将扮演非常重要角色。

最后补充一点,虽然宏替换功能强大,但是也不要太频繁使用,正是由于宏替换灵活性,使得它执行时要进行一些转换,如果太多的使用宏替换 可能会影响程序的性能。

所以在一些不是必须的场合下,尽量避免使用宏替换 ,就象好吃的东西吃得多了也会起腻一样,宏替换用的太多也会使你的程序不舒服的。
十豆三 2005-10-13
  • 打赏
  • 举报
回复
简单一点就是要用变量的值当一个关键字时。

还是参考一下详解吧:
执行宏替换。

& VarName[.cExpression]
参数
& VarName
指定宏替换中引用的内存变量名或数组元素名。请不要加上用于区分内存变量与字段的前缀 M.,否则将产生语法错误。宏的长度不要超过 Visual FoxPro 中允许的最大语句长度。
在宏替换中,变量不能递归引用其自身。例如,下列语句将产生错误信息:

STORE '&gcX' TO gcX
? &gcX
出现在 DO WHILE、FOR 和 SCAN 中的宏替换语句只在循环开始时计算值,在后续的循环中则不再计算值。因此在循环内改变内存变量和数组元素的值对宏替换都无效。

.cExpression
句点分隔符 (.) 和 cExpression 选项可用来在宏后面追加额外的字符。使用 .cExpression 附加在宏后面的 cExpression 也可以是一个宏。如果 cExpression 是一个属性名, 包括一个额外的点号 (cExpression..PropertyName)。
备注
宏替换把内存变量和数组元素中的内容当作原义字符串。当连字符 (&) 位于字符型内存变量或数组元素前面时,内存变量和数组元素的内容将替代宏引用。宏替代可用在任何接受原义字符串的命令和函数中。

提示 请尽可能使用名称表达式来取代宏替换。名称表达式与宏替换作用相似,但是,名称表达式限于传递作为名称的字符串。当命令或函数接受名称(文件名、窗口名、菜单名等)时,使用名称表达式的处理速度要明显快得多。有关名称表达式的详细内容,请参阅语言概述。
下列代码可以正确执行:

STORE 'customer' TO gcTableName
STORE 'company' TO gcTagName
USE &gcTableName ORDER &gcTagName
但是可以使用名称表达式代替:

USE (gcTableName) ORDER (gcTagName)
宏替换对于替换命令中的关键字是很有用的。在下面的示例中,把 TALK 设置保存在内存变量中,以便后面的程序能够恢复它。TALK 的原始设置使用宏替换恢复。

示例
STORE SET('TALK') TO gcSaveTalk
SET TALK OFF
*
* 额外的程序代码
*
SET TALK &gcSaveTalk && 恢复原始的 TALK 设置

2,723

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧