2
votes

I have a SAS project (EGv7.1) that allows the user to specify a value on the first line. Then, other processes are invoked based on the value specified. One of these is that some other macro variables are assigned. Below is what I have, and it does not seem to be working. I really need the let statement to be first in the sequence, but besides that I am open to changes. Any suggestions?

%let number=8;

%macro my_function();
    %if &number=8 %then 
        %do;
            %let number_text=eight;
            %let number_text_2=equal to eight;
        %end;
    %if &number>8 %then
            %do;
            %let number_text=not eight;
            %let number_text_2=greater then eight;
        %end;
    %if &number<8 %then
            %do;
            %let number_text=not eight;
            %let number_text_2=less than eight;
        %end;
%mend my_function;
%my_function();

%put =================&number==================;
%put ===========The number is &number_text.=============;
%put =======Furthermore, the number is &number_text_2.========;
2
Although your program is probably more complex than the above, if you're using prompts (as you should if you're in EG!) you can do some of this via the prompt interface rather than bothering with macros.Joe
Yes, I agree that prompts would be the better way to go here. I've been testing the prompt manager functionality, but need a short term solution. Thanks for the suggestion, though.pyll

2 Answers

3
votes

When you use %let statements inside of a macro, the variables default to local scope. That is, they only exist inside the macro. To remedy that add a %global statement inside the macro.

%let number = 8;

%macro my_function();
    %global number_text number_text_2;

    %if %sysevalf(&number = 8) %then 
        %do;
            %let number_text = eight;
            %let number_text_2 = equal to eight;
        %end;
    %else %if %sysevalf(&number > 8) %then
        %do;
            %let number_text = not eight;
            %let number_text_2 = greater than eight;
        %end;
    %else %if %sysevalf(&number < 8) %then
        %do;
            %let number_text = not eight;
            %let number_text_2 = less than eight;
        %end;

%mend my_function;
%my_function();

This tells SAS that the macro variables number_text and number_text_2 should be accessible outside of the macro, which should fix your problem.

I also recommend adding %else to your %ifs. This ensures that each condition is only evaluated if the one preceding it is false. Without %else, each condition is evaluated every time.

As @DomPazz mentioned, it's a good idea to use %sysevalf() when evaluating numeric conditions.

1
votes

If you're not passing in any values why use a macro at all? Here's a way to do it using a data null step.

%let number=3;

data _null_;
if &number=8 then do;
call symputx('number_text_3', "eight", g);
call symputx('number_text_4', "equal to eight", g);
end;
else if &number>8 then do;
call symputx('number_text_3', "not eight", g);
call symputx('number_text_4', "greater than eight", g);
end;
else if &number<8 then do;
call symputx('number_text_3', "not eight", g);
call symputx('number_text_4', "less than eight", g);
end;

run;

%put &number_text_3;
%put &number_text_4;