在尝试解决与宏变量范围相关的问题时,我发现这个非常有用的 SO 页面。 为什么 %let 不创建局部宏变量?
因此,总结一下,编写%let x = [];
或%do x = [] %to [];
在宏中将:
- 如果全局符号表中已经没有“x”,则创建一个局部范围的宏变量 x,或者
- 如果“x”在全局符号表中,则更新全局范围宏变量“x”
这让我觉得非常不直观。由于这种设计选择,我愿意打赌 SAS 荒野中存在大量错误。我很少在宏中看到 %local 语句,即使是在使用常见变量名(如“i”或“counter”)的循环语句之上。例如,我刚刚从 SUGI 和 SAS 全球论坛论文 http://www.lexjansen.com/cgi-bin/xsl_transform.php?x=sgf2015&c =杉
事实上,我在我打开的第一篇 SAS 会议论文中发现了这段代码:
%macro flag;
data CLAIMS;
set CLAIMS;
%do j= 1 %to 3;
if icd9px&j in (&codelist)
then _prostate=1;
%end;
run;
%mend;
%flag;
http://support.sas.com/resources/papers/proceedings15/1340-2015.pdf
任何调用 %flag 并且也有自己的 &j 变量的人都有祸了。他们很容易以没有日志错误但错误的结果结束,因为在他们调用 %flag 之后,他们的 &j 到处都是 4,这将是(根据经验)一个没有乐趣追踪的错误。或者更糟糕的是,他们可能永远不会意识到他们的结果是虚假的。
所以我的问题是,为什么不默认所有宏变量都是本地范围的决定?SAS 宏变量范围的工作方式是否有充分的理由?