【问题标题】:Get Data from SAS table to SAS Macro Variable从 SAS 表中获取数据到 SAS 宏变量
【发布时间】:2017-10-25 09:57:23
【问题描述】:

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

目的是在 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    

谢谢

【问题讨论】:

标签: macros sas sas-macro


【解决方案1】:

如果您想要的是一个名为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 的值可能是空白吗?

【讨论】:

  • 这仍然是错误的,尽管由于您在 call symputx 中指定了 g ,所以这无关紧要:%GLOBAL myMVar.; .
  • 对,我对. 不利。很好的收获。
【解决方案2】:

我发现有两个主要错误会导致您的程序无法运行。

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

%global mymvar;

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

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

那么您定义了一个本地宏变量mymvar,它将在宏get_data 运行时隐藏全局宏变量mymvar。因此,如果您将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;

【讨论】:

  • 为什么不在CALL SYMPUTX 中指定全局范围?
  • @Joe 我不想让 GLOBAL 符号表与变量混在一起。如果我在另一个宏中调用此实用程序宏,那么我可以要求它填充我已定义为该宏的 LOCAL 的宏变量。但是 CALL SYMPUTX() 上的 GLOBAL 选项很有用,因为它是您可以写入全局宏变量的唯一方法,即使存在同名的局部宏变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2014-12-02
相关资源
最近更新 更多