2015-01-08 42 views
1

我有一个SAS项目(EGv7.1),允许用户在第一行指定一个值。然后,根据指定的值调用其他进程。其中之一就是分配了一些其他宏变量。下面是我所拥有的,而且似乎没有工作。我真的需要let语句是序列中的第一个,但除此之外,我愿意改变。有什么建议么?SAS宏功能条件宏变量的值

%let number=8; 

%macro my_function(); 
    %if &number=8 %then 
     %do; 
      %let number_text=eight; 
      %let number_text_2=equal to eight; 
     %end; 
    %if &number>8 %then 
      %do; 
      %let number_text=not eight; 
      %let number_text_2=greater then eight; 
     %end; 
    %if &number<8 %then 
      %do; 
      %let number_text=not eight; 
      %let number_text_2=less than eight; 
     %end; 
%mend my_function; 
%my_function(); 

%put =================&number==================; 
%put ===========The number is &number_text.=============; 
%put =======Furthermore, the number is &number_text_2.========; 
+2

虽然你的程序可能比上述更复杂,如果你使用的提示(如您应该如果您在EG是!),你可以通过提示界面做一些这方面,而不是与宏困扰。 – Joe

+0

是的,我同意提示将是更好的方式去这里。我一直在测试提示管理器功能,但需要一个短期解决方案。还是)感谢你的建议。 – pyll

回答

3

当您使用宏内部%let语句,变量默认为本地范围。也就是说,它们只存在于宏内部。要解决该问题,请在宏内添加%global声明。

%let number = 8; 

%macro my_function(); 
    %global number_text number_text_2; 

    %if %sysevalf(&number = 8) %then 
     %do; 
      %let number_text = eight; 
      %let number_text_2 = equal to eight; 
     %end; 
    %else %if %sysevalf(&number > 8) %then 
     %do; 
      %let number_text = not eight; 
      %let number_text_2 = greater than eight; 
     %end; 
    %else %if %sysevalf(&number < 8) %then 
     %do; 
      %let number_text = not eight; 
      %let number_text_2 = less than eight; 
     %end; 

%mend my_function; 
%my_function(); 

这告诉SAS的宏变量number_textnumber_text_2应该是宏,它应该解决您的问题之外访问。

我还建议将%else添加到您的%if s。这确保了每个条件仅在前面的条件为假时才被评估。没有%else,每次评估每个条件。

正如@DomPazz提到的,在评估数值条件时使用%sysevalf()是个好主意。

+2

这是正确的。宏变量的范围比这里描述的要复杂一些。我强烈建议阅读它的文档:http://support.sas.com/documentation/cdl/en/mcrolref/68140/HTML/default/viewer.htm#n10i4tmalsyhgxn1hj4ud13ff074.htm – DomPazz

+0

@DomPazz:同意,范围更复杂比我描述的。更准确的说,添加'%global''意味着它可以在程序的所有地方(几乎)访问,除非明确删除,否则在会话期间它将被访问,包括开放代码和任何嵌套宏。 –

+1

由于效率的原因,我不会使用'%else if' - 这会在几微秒内运行一次。我会使用'%else if',因为它更清楚地表明它只会通过三条路径中的一条,而不会超过一条。 – Joe

1

如果你没有传递任何值,为什么要使用宏?这是一种使用数据null步骤的方法。

%let number=3; 

data _null_; 
if &number=8 then do; 
call symputx('number_text_3', "eight", g); 
call symputx('number_text_4', "equal to eight", g); 
end; 
else if &number>8 then do; 
call symputx('number_text_3', "not eight", g); 
call symputx('number_text_4', "greater than eight", g); 
end; 
else if &number<8 then do; 
call symputx('number_text_3', "not eight", g); 
call symputx('number_text_4', "less than eight", g); 
end; 

run; 

%put &number_text_3; 
%put &number_text_4;