我是SAS和宏功能的新手。 我更喜欢我的代码" DRY",所以我想将有用的sql查询放入返回结果的宏函数中。
例如,我试过这个:
%macro getName;
%local nameq;
PROC SQL noprint;
SELECT b.name into :nameq from Country as b where b.ccountry = 100;
quit;
&nameq
%mend getNNSS;
%let tst = %getName;
%put &tst;
但是我收到了这个错误:
ERROR 180-322: Statement is not valid or it is used out of proper order.
你可以帮帮我吗?
感谢
答案 0 :(得分:4)
这里的问题是你实际上并没有编写宏函数(这在任何情况下都不是该语言的技术特性,但是这个术语的常见用法)。 SAS宏 - 任何类型 - 只需将文本放入输入流,就好像它已由用户键入一样。以%
开头的事情将在幕后进行,但其他任何内容都只会按原样放在输入流中。
宏函数通过常规用法定义为执行其所有计算/等的宏。以这种方式,除了单个值之外,实际上没有任何内容返回到系统 - 这样,它可以以类似的方式用于其他语言中的函数(或者实际上在SAS中)。
因此,这是一个宏功能:
%macro mymacrofunction;
5
%mend mymacrofunction;
这不是:
%macro notafunction;
data test;
x=5;
run;
%mend notafunction;
因为你不能说
%let x=%notafunction;
因为那会返回
%let x=data test; x=5; run;
这可能会出错(除非你在数据步骤中运行它,在这种情况下它根本不会按预期工作)。
对于你的宏:
%macro getName;
%local nameq;
PROC SQL noprint;
SELECT b.name into :nameq from Country as b where b.ccountry = 100;
quit;
&nameq
%mend getNNSS;
与let语句一起使用时会发生什么:
%let tst=proc sql noprint; select ... ; quit; &nameq
这不是你想要的,是吗。
您有几种方法可以解决这个问题。
PROC FCMP
PROC FCMP是SAS函数编写语言。 PROC FCMP 确实编写实际函数,或多或少 - '较少'是它们实际上并不比它们包含的代码更有效,与其他语言相反,但它们的工作方式与C-类似类型函数(它们完全在幕后操作,并在自己的局部变量上执行自己的计算,返回单个值,或者返回多个值的call routine
)。因此,您可以使用FCMP
函数替换宏函数,假设您运行的是9.3或更新版本。
DOSUBL
DOSUBL是一种要求SAS完全在幕后运行宏的方法,这将允许您做更多或更少的尝试。
RUN_MACRO
in FCMP
这几乎可以直接与您正在做的事情一起工作:您只需使用FCMP
将宏包裹在RUN_MACRO
函数中即可调用它。就简单性而言,这可能是你最好的选择。
有关宏功能的更多阅读,sascommunity.org has a page on the subject链接到很多论文;或者在搜索引擎或LexJansen.com上查找有关编写宏功能的论文。