从SAS表获取数据到SAS宏变量

时间:2017-10-25 09:57:24

标签: macros sas sas-macro

我想创建一个从SAS表中读取值并将该值存储在Global变量中的宏。

目的是在SAS DIS JOB中使用此值。

我测试了以下内容:

%GLOBAL &myMVar.;
%Macro Get_data(myDataset,myLine,myColumn,myMVar);
data _null_;
set &myDataset.;
if _N_ = &myLine. 
    then do;
        call symputx(symget('myMVar'),&myColumn.);
    end;
run;
%MEND Get_data;

*Calling a Macro program;
LIBNAME dtvault BASE "/sasdata/DataVault";
%Get_data(dtvault.codes,1,cod,myMVar);
%put &myMVar;
run;

**我没有任何结果。日志:**

*Calling a Macro program;
38         LIBNAME dtvault BASE "/sasdata/DataVault";
NOTE: Libref DTVAULT was successfully assigned as follows: 
      Engine:        BASE 
      Physical Name: /sasdata/DataVault
39         %Get_data(dtvault.codes,1,cod,myMVar);

NOTE: There were 2 observations read from the data set DTVAULT.CODES.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


40         %put &myMVar;

41         run;
42         
43         GOPTIONS NOACCESSIBLE;
44         %LET _CLIENTTASKLABEL=;
45         %LET _CLIENTPROCESSFLOWNAME=;
46         %LET _CLIENTPROJECTPATH=;
2                                                          The SAS System                          10:06 Wednesday, October 25, 2017

47         %LET _CLIENTPROJECTPATHHOST=;
48         %LET _CLIENTPROJECTNAME=;
49         %LET _SASPROGRAMFILE=;
50         %LET _SASPROGRAMFILEHOST=;
51         
52         ;*';*";*/;quit;run;
53         ODS _ALL_ CLOSE;
54         
55         
56         QUIT; RUN;
57    

谢谢

2 个答案:

答案 0 :(得分:0)

如果你想要的是一个名为myVar的全局宏变量,你初始化全局宏变量的方式。 %global语句不需要&符号。

另外,如果您要将宏变量实例化为宏定义,那么就不需要将其指定为宏定义的参数:

%GLOBAL myMVar.;
%Macro Get_data(myDataset,myLine,myColumn);
data _null_;
set &myDataset.;
if _N_ = &myLine. 
    then do;
        call symputx('myMVar',&myColumn.);
    end;
run;
%MEND Get_data;

*Calling a Macro program;
LIBNAME dtvault BASE "/sasdata/DataVault";
%Get_data(dtvault.codes,1,cod);
%put &myMVar;

请注意,symputx调用例程允许指定要在其中创建变量的符号表。然后,您可以取消%global语句:

%Macro Get_data(myDataset,myLine,myColumn);
data _null_;
set &myDataset.;
if _N_ = &myLine. 
    then do;
        call symputx('myMVar',&myColumn.,'G');
    end;
run;
%MEND Get_data;

*Calling a Macro program;
LIBNAME dtvault BASE "/sasdata/DataVault";
%Get_data(dtvault.codes,1,cod);
%put &myMVar;

编辑:在回答您的评论时,我在测试数据集中使用了上述代码:

libname dtvault (work);

data dtvault.codes;
cod='test';
run;

%Macro Get_data(myDataset,myLine,myColumn);
data _null_;
set &myDataset.;
if _N_ = &myLine. 
    then do;
        call symputx('myMVar',&myColumn.,'G');
    end;
run;
%MEND Get_data;

%Get_data(dtvault.codes,1,cod);
%put &myMVar;

日志生成此输出:

42         %Get_data(dtvault.codes,1,cod);

NOTE: There were 1 observations read from the data set DTVAULT.CODES.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
2                                                          The SAS System                          10:04 Wednesday, October 25, 2017

      cpu time            0.00 seconds


43         %put &myMVar;
test

如果您的数据上的%put语句没有产生任何内容;可能是数据集第1行cod的值是空白的吗?

答案 1 :(得分:0)

我发现两个主要错误会导致您的程序失效。

&不是宏变量名称的一部分。它是触发器,让宏处理器知道您希望它用引用的宏变量的值替换宏变量引用。因此,如果要定义名为mymvar的宏变量,则%global语句需要如下所示。

%global mymvar;

您也受到宏变量范围的影响。如果您的程序以这些行开头

%global mymvar;
%macro get_data(mydataset,myline,mycolumn,mymvar);

然后你定义了一个LOCAL宏变量mymvar,它将在宏mymvar运行时隐藏全局宏变量get_data。因此,如果将mymvar设置为某个值,则当宏完成运行时它将消失。

由于您希望宏生成一个在宏完成运行后可用的宏变量,因此您需要确保它创建的宏变量已经存在或者在GLOBAL宏空间中创建。

为了增加灵活性,您可能希望传递宏变量的名称,该宏变量希望宏用作宏的参数。然后,您可以使用%SYMEXIST()函数来决定是否需要创建全局宏变量。请注意,现在我们确实需要&语句中的%global,因为我们要创建一个名为另一个宏变量值的宏变量。

%macro get_data(dataset,line,column,mvar);
%if not %symexist(&mvar) %then %global &mvar ;
data _null_;
  set &dataset ;
  if _n_=&line then do;
    call symputx("&mvar",&column);
    stop;
  end;
run;
%mend get_data;

现在,当您调用宏时,您将传递参数所需的值。请注意,SAS宏的一个很好的特性是即使对于定义为位置参数的参数,您也可以在宏调用中使用命名参数。

%get_data(dataset=myDataset,line=1,column=myVar,mvar=myMvar)
%put &=myMvar;