0

I am trying to conditionally call a macro based on identifiers in an array, and have the macro variable change based on the value of the array. Here is my code:

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;

As an example:

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

I would expect that my code would create arrays for the file and prog variables that are defined earlier in my code. Then, it would begin cycling through the array. The first iteration would conditionally execute the macro statement, because the prog1 variable is Y. Then, the macro would execute using the value of file1 ("C:\file.doc") as the macro variable.

The conditional logic appears to be working. However, the macro executes on "name(file(I)))" instead of on "C:\file.doc".

Does anyone see my mistake?

3
  • What do the %LET statements have to do with the code you posted? Commented Nov 3, 2017 at 19:27
  • I was just trying to show an example of the variables that I am using for the array since I did not show how they are defined here. Commented Nov 3, 2017 at 19:43
  • Macro variables are not variables. They have nothing to do with arrays. Commented Nov 3, 2017 at 20:38

2 Answers 2

4

You passed a string literal to CALL EXECUTE() instead of using the value of your variable. But you also never set your variables to any values.

So if you have list of PROG/FILE combinations in a dataset. Like this:

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

Then you can use them to generate calls to your macro like this:

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

So you should see this line in the SAS LOG to show what command you pushed onto the stack to execute after the DATA _NULL_ step.

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

If you have a series of macro variables then use symget() function to retrieve the values. You can use CATS() to generate the macro variable name to pass to the symget() function.

%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;
Sign up to request clarification or add additional context in comments.

3 Comments

Notice the use of ' not " also - those prevent resolution of the macro before you actually want it resolved.
Thanks! This logic works, but I need to use macro variables so that other people can define the variable values in the program. I am trying my same code with your call execute statement. I am able to finish processing without getting an illegal array call error, but I am not able to see the results in the log. Does using arrays hide the results of each specific variable? For example, instead of saying that prog(1) resolved to "Y", so the call execute was processed using file(1), which resolved to "C:\file.doc", it says "DATA statement used". Is there a way to get a more specific record?
What do macro variables have to do with ARRAYs?
1

You may be confusing things here.

If you have a set of macro variables, which might casually be called a macro variable array (but be aware, this is not a formal type in SAS nor is it technically accurate), like so:

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

And you want to call the macro %findit(&file1.), you might do the following:

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

%call_findit();

That uses macro language syntax to call %findit when you need to. The && is needed for the conversion from &&file&i to contents of &file1; the macro parser passes twice, once turning && to & and &i to 1, and thus leaving &file1, which then in the second pass is turned to c:\temp\file1.txt.

Again, this is not technically using 'arrays' in any fashion, but it's using SAS macro variables in a way that is roughly similar to how arrays work, and sometimes is called "SAS Macro Variable Arrays", such as in this paper by Ron Fehd and this paper by Ted Clay, both of which have written extensively on the subject.

In my opinion this isn't a great way to write things like this, in general. You're better off using Tom's suggested methodology via a data step, and having the person who makes these changes do so via a text file input to the data step, as that's better than modifying the code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.