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;