The only way I can do this without declaring each macro as global ahead of time, and then make the% let statement, use a macro instead of the% let statement.
% mylet, , . % let , .
.
%global myvar;
%let myvar=2;
...
%mylet(myvar,2);
%macro mylet(var,value);
%global &var;
%let &var.= &value ;
%mend;
%macro test;
%mylet(myvar,2);
%mylet(myvar2,12);
%mylet(myvar3,'string');
title "Macro scope inside test macro";
proc sql;
select *
from dictionary.macros
where name in('MYVAR','MYVAR2','MYVAR3');
quit;
%mend;
%test;
title "Macro scope outside test macro";
proc sql;
select *
from dictionary.macros
where name in('MYVAR','MYVAR2','MYVAR3');
quit;