SAS V9.1.3 - 组合 %INC 和 CALL EXECUTE 时出错

发布于 2024-08-23 10:26:18 字数 1630 浏览 9 评论 0原文

我遇到一些 SAS v9.1.3 代码的解析错误。

这是我想存储在 .txt 文件(称为 Problem2.txt)中的一些代码,并用 %INC 将其带入 SAS

%macro email020;                  
   %if &email = 1 %then %do;       
     %put THIS RESOLVED AT 1;      
   %end;                           
   %else %if &email = 2 %then %do; 
     %put THIS RESOVLED AT 2;      
   %end;                           
   %put _user_;                    
%mend email020;                   

%email020; 

然后这是主要代码:

filename problem2 'C:\Documents and Settings\Mark\My Documents\problem2.txt';

%macro report1;                            
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2 (inc);                            
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

data test;                                 
  run = 'YES';                             
run;                                       

data _null_;                               
  set test; 
  call execute("%report1");  
  call execute("%report2");  
run;

日志显示:

NOTE: CALL EXECUTE generated line.
1   +  %inc problem2;
MLOGIC(EMAIL020):  Beginning execution.

WARNING: Apparent symbolic reference EMAIL not resolved.

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &email = 1

ERROR: The macro EMAIL020 will stop executing.

MLOGIC(EMAIL020):  Ending execution.

所以问题是为什么 CALL EXECUTE 生成 %inc Problem2而不是 %report1,导致 SAS 错过分配,我该怎么办?

I am getting a resolution error with some SAS v9.1.3 code.

Here is some code I want to store in a .txt file (called problem2.txt) and bring into SAS with a %INC

%macro email020;                  
   %if &email = 1 %then %do;       
     %put THIS RESOLVED AT 1;      
   %end;                           
   %else %if &email = 2 %then %do; 
     %put THIS RESOVLED AT 2;      
   %end;                           
   %put _user_;                    
%mend email020;                   

%email020; 

Then this is the main code:

filename problem2 'C:\Documents and Settings\Mark\My Documents\problem2.txt';

%macro report1;                            
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2 (inc);                            
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

data test;                                 
  run = 'YES';                             
run;                                       

data _null_;                               
  set test; 
  call execute("%report1");  
  call execute("%report2");  
run;

The log shows:

NOTE: CALL EXECUTE generated line.
1   +  %inc problem2;
MLOGIC(EMAIL020):  Beginning execution.

WARNING: Apparent symbolic reference EMAIL not resolved.

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &email = 1

ERROR: The macro EMAIL020 will stop executing.

MLOGIC(EMAIL020):  Ending execution.

So the question is why does CALL EXECUTE generate %inc problem2 rather than %report1, causing SAS to miss the assignment and what can I do about it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

打小就很酷 2024-08-30 10:26:18

这似乎是一个宏变量范围问题。尝试:

%macro report1;   
  %global email; 
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2;            
%global email; 
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

但是,我认为将 email 作为参数传递给 %email020 而不是使用全局宏变量会更好。另外,我会避免使用嵌套的宏定义。

要获取有关宏变量范围的更多数据,您可以在宏执行期间查询dictionary.macros视图。您可以使用以下命令获取dictionary.macros的描述

proc sql;
    describe table dictionary.macros;
quit;

It seems to be a macro varible scope issue. Try:

%macro report1;   
  %global email; 
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2;            
%global email; 
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

However, I think it would be better to pass email as a parameter to %email020 rather than using global macro variables. Also, I'd avoid using nested macro definitions.

To get more data on macro variable scope, you could query the dictionary.macros view during macro execution. You can get the description of dictionary.macros with

proc sql;
    describe table dictionary.macros;
quit;
酒与心事 2024-08-30 10:26:18

%include 不是宏调用,而是一种编译器指令,用于包含来自外部文件的代码。当宏%report1编译时,没有宏变量email(因为该宏之前从未运行过),因此引用保持原样,&电子邮件。然后隐式 %eval() 看到 &email = 1 并抱怨,因为它看起来像是您正在比较文本(&email)针对数字 (1)。

如果可能的话,应避免引入%global。我会完全取消 %include 。简单得多,下面是。 :-)

%macro doSomething(email=);                  
  %if &email = [email protected] %then %do;       
    %put THIS RESOLVED AT 1;      
  %end; %else %if &email = [email protected] %then %do; 
    %put THIS RESOVLED AT 2;      
  %end;                           
  %put _user_;                    
%mend doSomething;                   


data emails;
  email="[email protected]"; output;
  email="[email protected]"; output;
run;

data _null_;
  set emails;
  call execute(catx(email, '%doSomething(email=', ')'));
run;

/* on log
THIS RESOLVED AT 1
DOSOMETHING EMAIL [email protected]
THIS RESOVLED AT 2
DOSOMETHING EMAIL [email protected]
*/

%include is not a macro call but sort of a compiler directive to include code from an outside file. When the macro %report1 is compiled, there is no macro variable email (because the macro never ran before), thus the reference remains as it is, &email. Then the implicit %eval() sees &email = 1 and complains because it looks like you are comparing a text(&email) against a number (1).

Introducing the %global is to be avoided if possible. I would do away with %include completely. much simpler, below is. :-)

%macro doSomething(email=);                  
  %if &email = [email protected] %then %do;       
    %put THIS RESOLVED AT 1;      
  %end; %else %if &email = [email protected] %then %do; 
    %put THIS RESOVLED AT 2;      
  %end;                           
  %put _user_;                    
%mend doSomething;                   


data emails;
  email="[email protected]"; output;
  email="[email protected]"; output;
run;

data _null_;
  set emails;
  call execute(catx(email, '%doSomething(email=', ')'));
run;

/* on log
THIS RESOLVED AT 1
DOSOMETHING EMAIL [email protected]
THIS RESOVLED AT 2
DOSOMETHING EMAIL [email protected]
*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文