2015-01-08 64 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;