Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/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中多次运行宏,如下所示: %mymac(a,b); %mymac(a,c); . %mymac(a,a) %mymac(a,w); . 我的程序/宏类似于: /* begin program here */ data original_data; set mylib.mydata; run; %macro mymac(x,y); data mydata1; set original_data; where school_district="&x"; run; proc

我在SAS中多次运行宏,如下所示:

%mymac(a,b);
%mymac(a,c);
.
%mymac(a,a)
%mymac(a,w);
.
我的程序/宏类似于:

/* begin program here */

data original_data;
set mylib.mydata;
run;

%macro mymac(x,y);

data mydata1;
set original_data;
where school_district="&x";
run;

proc means data=mydata1;
var income;
run;

%mend mymac;
我意识到我忘记了一个分号(如(a,a)中的分号),SAS似乎并不介意。它毫无问题地运行了所有宏调用。当我在中添加分号时,我比较了输出,我看不出有什么不同


SAS不给出缺少分号的错误是正常的吗?

通常可以。了解SAS宏的主要内容是它是一种代码生成工具,而不是一种真正的编程语言。而
%my_mac(x,y)
看起来像是C语言中的传统函数调用,在这里,您希望用
结束每个语句,这里是一个终止
没有实际意义。相反,它是在
%my_mac(x,y)
内部生成的SAS代码。在您的情况下,该代码符合语法要求,可以使用。如果您在心里用它生成的代码替换
%my_-mac(x,y)
调用(即
data mydata…..run;
),您会发现即使在
%my_-mac(x,y)
结尾处使用
,它也是合乎语法的。如果你写了
%my_mac(x,y)数据mydate…..run
,这很好,但是
是多余的

事实上,跳过分号也是对宏返回值的攻击。例如:

%MACRO x_plus_n (x = , y= );
    %SYSEVALF (&x + &y)
%MEND;

%LET x = 3 ;
%LET y = 4 ;
%LET z = %x_plus_n (x = &x , y= &y) is the result;
%PUT ------------- &z;

注意缺少的
在%SYSEVALF行上。这允许宏在行首
%LET z=..
的末尾终止,其中有一个
。由
x\u plus\n
创建的输出成为宏的一种返回值。

宏只是文本替换。它们本身通常不是可执行语句(尽管它们有时可以使用
%SYSFUNC
执行语句)。因此,在宏调用之后不需要分号,除非在宏中包含的文本之后需要分号(实际上并不包含在宏本身中)

即:

必须按规定执行

%test;
因为
运行
没有终端分号。如果在宏中的
run
后面加上分号,则可以将其作为
%test
运行,而不使用分号


记住上面的第一句话:宏只是文本替换。宏生成的任何文本都会被塞进SAS程序,并像您键入它一样执行(可能您使用了
%do i=1%到100;
-因此它会将循环中所有内容的100个副本放入循环中-但就好像您自己键入了所有100个)。因此需要一个
取决于您是否需要键入它。

宏调用不需要分号

通常,分号包括在内,因为人们习惯于将分号视为“终止语句”或结束行的一种方式。我个人更喜欢在可能的情况下包含它们,因为我相信这会使我的代码更具可读性

请记住,宏只需对自身进行求值,并返回它们解析的任何内容,这些内容可能是看起来像数字、字符串或其他任何内容的代码块

以不使用分号的示例为例:

%macro field_list();
    name, 
    age, 
    sex, 
    height
%mend;

proc sql;
  select %field_list()
  from sashelp.class
  ;
quit;
尝试在自己的机器上使用
选项mprint运行它已启用。运行宏的结果只是返回其中的代码块。这将导致执行以下代码:

proc sql;
  select  name, age, sex, height
  from sashelp.class
  ;
quit;
如果在调用宏之后有一个分号,那么SAS将尝试运行的代码将包括分号,这将是无效的语法,如下所示(请注意高度后的分号):

这是因为调用宏时不需要分号,所以它只会被留下并包含在步骤的执行中

当您像在上面给出的示例中那样调用宏时,可以使用分号,因为宏是一个完全自包含的步骤。在开放代码中,使用这样的分号没有什么害处:

%macro example2(inDS=, outDs=);
  data &outDs;
    set &inDs;
  run;
%mend;

%example2(inDS=sashelp.class, outDs=tmp_class);
这基本上评估为:

data tmp_class;
  set sashelp.class;
run;;
注意我们通话结束时剩下的分号吗?我们可以拥有我们想要的数量,代码仍然可以正常运行,即:

%example2(inDS=sashelp.class, outDs=tmp_class);;;;;;
决心:

data tmp_class;
  set sashelp.class;
run;;;;;;;

它仍然可以正常运行,因为它是有效的语法。

基本上,每次调用mydata1数据集时,我的宏都会创建mydata1数据集。我不是最擅长使用宏的,也不确定我是否完全理解您的示例。@sparc_spread-我通过在宏调用和分号之间添加文本使示例更有意义。如果没有额外的文本,您试图表达的观点就不那么明显了。如果没有编辑,这基本上与问题的要求相反(宏中缺少了有用的
,而不是原始问题所做的,在宏之外跳过)。“这样的编辑是恰当的。”乔同意了。我编辑了一段新的开头段落,更直接地解决了这个问题,“返回值黑客”现在是一个有用的事后思考。因此,如果我完全正确地理解了这一点,我不需要在上述宏的末尾使用分号,因为最后一条语句中有一个分号,所以在%mymac(a,a)中添加一个分号基本上与输入run相同;;在资产负债表的末尾?是的,这是完全正确的。
%example2(inDS=sashelp.class, outDs=tmp_class);;;;;;
data tmp_class;
  set sashelp.class;
run;;;;;;;