1
votes

I am trying to print a statement to the SAS Log alerting the user that certain programs did not run. To do this, I am printing to the SAS log using a put statement:

%let step1 = My program;
%let rec= cats(&step1.);

data _null_;
put "** &rec.  did not run";
run;

The put statement prints: "** cats(My program) did not run". Does anyone know why the cats function is not executing? I am guessing it has something to do with macro code being executed before SAS statements, but I am not sure how to make this work.

EDIT

Thanks Reeza and Tom. Now I understand why this wasn't working - I have to use %sysfunc to use a function outside of a data step, and I can't use functions inside a put statement.

Tom - you asked for a more complete example:

I am trying to print a statement to the SAS log so that the user can easily see which programs ran and which were skipped. I am trying to accomplish that doing the following:

data _null_;
array steps(*) $ step1-step7;
do i=1 to dim(steps);
    if symget(cats('run',i)) = 'N' then
    put "** The program "symget(cats('run',i)" did not run";
end;
run;

I thought if I could figure out how to make a function execute inside the put statement, this code would work. However, that is impossible. I should be able to get the variable to change with "i", though.

For example, when i is 1, the put statement should be, "The program file1.sas did not run".

When i is 2, the put statement should be, "The program file2.sas did not run", and so on.

I tried using:

put "** The program &&step&i did not run";

but SAS is not able to recognize my variables.

Hopefully this provides a little more context!

2
Why do you even have that step? - Reeza
You cannot include functions in the middle of a PUT statement. Your PUT statement is not even trying to call a function since it is just putting a character literal. Your second %LET statement is not making any attempt to call the cats() function since you did not use the %sysfunc() macro function. Do you have a more meaningful example of what you are trying to do? - Tom
What is the ARRAY steps doing other than setting the upperbound on your DO loop? - Tom
Sounds like you have 14 macro variables, RUN1 to RUN7 and STEP1 to STEP7 and you want to treat them as 7 pairs and print the STEPx macro variable when the RUNx macro variable has a particular value. - Tom

2 Answers

2
votes

You can add %SYSFUNC() to use functions outside a data step, but in this case, the CATS doesn't add any value to your process.

%let step1 = My program;
%let rec= %sysfunc(cats(&step1.));

data _null_;
put "** &rec.  did not run";
put "** &step1.  did not run";
run;

Output:

293
294
295  %let step1 = My program;
296  %let rec= %sysfunc(cats(&step1.));
297
298  data _null_;
299  put "** &rec.  did not run";
300  put "** &step1.  did not run";
301  run;

** My program  did not run
** My program  did not run
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
1
votes

If you are running a macro then just use a %DO loop.

%do i=1 %to 7 ;
  %if (N=&&run&i) %then %put NOTE: The program &&step&i did not run;
%end;

Otherwise just use a data step variable and print that.

data _null_;
  do i=1 to 7 ;
    if symget(cats('run',i)) = 'N' then do;
      length program $100 ;
      program=symget(cats('step',i));
      put 'NOTE: The program ' program 'did not run';
    end;
  end;
run;