在数组中使用变量 - SAS

Use a variable within an array - SAS

我正在尝试根据数组中的标识符有条件地调用宏,并根据数组的值更改宏变量。这是我的代码:

data;
array file(*) $ file1-file7;
array prog(*) $ prog1-prog7;
do i=1 to dim(prog);
    if prog(i) = "Y" then
    call execute("%findit(name(file(i)))");
end;
run;

例如:

%let file1 = C:\file.doc
%let prog1 = Y

我希望我的代码会为我的代码中前面定义的文件和 prog 变量创建数组。然后,它将开始循环遍历阵列。第一次迭代将有条件地执行宏语句,因为 prog1 变量是 Y。然后,宏将使用 file1 ("C:\file.doc") 的值作为宏变量来执行。

条件逻辑似乎有效。但是,宏在 "name(file(I)))" 而不是 "C:\file.doc" 上执行。

有人看到我的错误吗?

您将字符串文字传递给 CALL EXECUTE() 而不是使用变量的值。但是您也永远不会将变量设置为任何值。

因此,如果您在数据集中有 PROG/FILE 组合列表。像这样:

data have ;
  infile cards truncover ;
  input prog . file 0. ;
cards;
YC:\file.doc
NC:\file2.doc
;

然后您可以像这样使用它们来生成对您的宏的调用:

data _null_;
  set have ;
  if prog = "Y" then call execute(cats('%nrstr(%findit)(',file,')'));
run;

所以您应该在 SAS LOG 中看到这一行,以显示在 DATA _NULL_ 步骤之后您将什么命令压入堆栈以执行。

1   + %findit(C:\file.doc)

如果您有一系列宏变量,则使用 symget() 函数检索值。您可以使用 CATS() 生成宏变量名以传递给 symget() 函数。

%let prog1=Y;
%let file1=C:\file.doc;
%let n=1;

data _null_;
  do n=1 to &n ;
    if symget(cats('prog',n))='Y' then 
      call execute(cats('%nrstr(%findit)(&file',n,')'))
    ;
  end;
run;

你可能在这里混淆了东西。

如果你有一组宏变量,可以随便称为宏变量数组(但要注意,这不是SAS中的正式类型,技术上也不准确),像这样:

%let file1= c:\temp\file1.txt;
%let file2= c:\temp\file2.txt;
%let prog1= Y;
%let prog2= N;

并且您想调用宏 %findit(&file1.),您可以执行以下操作:

%macro call_findit();
  %do i = 1 %to 2;
    %if &&prog&i. = Y %then %do;
      %findit(&&file&i.)
    %end;
  %end;
%mend call_findit;

%call_findit();

在需要时使用宏语言语法调用%findit。从&&file&i&file1的内容转换需要&&;宏解析器通过两次,一次将 && 转为 & 并将 &i 转为 1,从而留下 &file1,然后在第二遍转为c:\temp\file1.txt

同样,这在技术上并没有以任何方式使用 'arrays',但它以与数组工作方式大致相似的方式使用 SAS 宏变量,有时称为 "SAS Macro Variable Arrays",例如如 this paper by Ron Fehd and this paper by Ted Clay,两者都在该主题上写了很多文章。

在我看来,一般来说,这不是编写此类内容的好方法。您最好通过数据步骤使用 Tom 建议的方法,并让进行这些更改的人通过将文本文件输入到数据步骤来执行此操作,因为这比修改代码更好。