Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SAS宏函数以宏变量的值为条件_Sas_Sas Macro - Fatal编程技术网

SAS宏函数以宏变量的值为条件

SAS宏函数以宏变量的值为条件,sas,sas-macro,Sas,Sas Macro,我有一个SAS项目EGv7.1,它允许用户在第一行指定一个值。然后,根据指定的值调用其他进程。其中之一是分配了一些其他宏变量。下面是我所拥有的,它似乎不起作用。我真的需要let语句成为序列中的第一个语句,但除此之外,我对更改持开放态度。有什么建议吗 %let number=8; %macro my_function(); %if &number=8 %then %do; %let number_text=eight;

我有一个SAS项目EGv7.1,它允许用户在第一行指定一个值。然后,根据指定的值调用其他进程。其中之一是分配了一些其他宏变量。下面是我所拥有的,它似乎不起作用。我真的需要let语句成为序列中的第一个语句,但除此之外,我对更改持开放态度。有什么建议吗

%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.========;
在宏中使用%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_text和number_text_2应该可以在宏外部访问,这将解决您的问题

我还建议将%else添加到您的%ifs中。这确保了每个条件仅在其前面的条件为false时才进行计算。如果没有%else,则每次都会计算每个条件


正如@DomPazz所提到的,在计算数值条件时使用%sysevalf是一个好主意。

如果不传入任何值,为什么要使用宏?这里有一种使用数据空步骤的方法


这是正确的。宏变量的作用域比这里描述的要复杂一些。我强烈建议阅读关于它的文档:@DomPazz:同意,范围界定比我描述的更复杂。更准确的说法是,添加%global意味着在会话期间,它几乎可以在程序中的所有位置访问,包括打开的代码和任何嵌套的宏,除非显式删除。出于效率考虑,我不会使用%else-这将在几微秒内运行一次。我会使用%else if,因为它更清楚地表明它将只通过三条路径中的一条,并且可能不会超过一条。用%sysevalf括起逻辑测试,即如果%sysevalf&number<8…,则为%。。。。编写的测试将通过字符串比较而不是数字进行。这会,而且经常会,引起心痛@多姆帕兹:请随意编辑我的答案。我对它进行了编辑,以包含您对%sysevalf的建议。虽然您的程序可能比上述程序更复杂,但如果您使用的是提示,如果您在EG!您可以通过提示界面来完成一些操作,而不用费心处理宏。是的,我同意提示是更好的方式。我一直在测试prompt manager功能,但需要一个短期解决方案。不过,谢谢你的建议。
%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;