Search code examples
sas

Why is my SAS macro variable "codelist" out of scope?


 %macro useList(var,icd);

 proc sql noprint;

 select quote(trim(&var.))

 into: &var.list separated by ','

 from out.ped

 where not missing (&var.);

 quit;


if dx in: (&&&var.list) then &icd = '1';
%mend;

%useList(code);

I got this to work by making codelist a global variable but I want to understand what is happening.


Solution

  • The SELECT statement will not create the macro variable when no observations meet the WHERE condition. You should probably set the macro variable to some default value before the SELECT statement to insure that an old value is not re-used.

    %let &var.list='NO CODES FOUND';
    select .... into :&var.list ...
    

    If you need the macro variable value after the macro finishes then you might need other changes. That is because if you assign a value to a macro variable while a MACRO is executing (like your use of the INTO syntax of PROC SQL) and the macro variable does not already exist then it will be created as LOCAL to the macro. Once the macro finishes running any LOCAL macro variables it has defined no longer exist.

    If you want to be able to use the macro variable after the macro finishes running then you could either force it into the GLOBAL scope by adding at %GLOBAL statement. Make sure there is not already a macro variable with that name!

    %macro useList(var,icd);
    %if not %symexist(&var.list) %then %global &var.list ;
     ...
    

    Or just make sure the macro variable exists before you call the macro.

    %let codelist=;
    %useList(code)
    

    If you don't need the macro variable after the macro finishes then just define it as LOCAL. That will prevent you from overwriting the value of an already existing macro variable with the same name that exists in the calling environment.

    %macro useList(var,icd);
    %local &var.list;
    

    PS Your macro as written will generate invalid SAS code. You cannot have an IF statement outside of a DATA step. And you could not call the macro inside of a data step because it generates a PROC step that would immediately end the definition of the data step.