- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
proc sql ;
select count(distinct origin) into: count from sashelp.cars ;
select distinct(strip(origin)) into:or1-:or%left(&count) from sashelp.cars ;
quit;
%put &or1 &count ;
%macro test ;
proc sql ;
%do i=1 %to 1 ;
%global co make%left(&co) ;
select count(distinct make) into:co from sashelp.cars
where strip(origin)="&&or&i" ;
select distinct make into:make1-:make%left(&co) from sashelp.cars
where strip(origin)="&&or&i" ;
%end;
quit;
%mend ;
options mprint symbolgen ;
%test ;
%put &make1 ;
when I want to see value of make1 macro variable it is showing not resolved.
How to convert local to global macro variable?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Please paste your code into a text box (running man icon) from now on so we don't see smiley faces in your code.
If you really need &MAKE1 outside of the macro, you put a %GLOBAL statement before the macro, or inside the macro, or you change your logic so that you don't need &MAKE1 outside of the macro (which in this simple case, it is not needed outside of the macro).
Paige Miller
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
PLEASE
use the "little running man" icon for posting code. It is not rocket science, and it prevents the appearance of smileys and other funnies that make it hard to impossible to run your code.
You use the %global statement to declare a macro variable global. You have to do this for ALL variables you create, and since you use a variable series of macro variables, you have to do this declaration in the same manner.
But this all just shows the UTTER STUPIDITY of storing values in macro lists. Keep data where it belongs, in DATASETS, and use the usual SAS means to create dynamic code where necessary, but most of the time you just use lookups (join, format, hash) from the dataset anyway.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Your %DO loop is running only once since you are starting at one and stopping at one. Did you mean to use a different upper bound?
You are over complicating things. Your first step can just be:
proc sql NOPRINT;
select distinct strip(origin) into :or1- from sashelp.cars ;
%let count=&sqlobs;
quit;
Inside your macro why not just use CALL SYMPUTX() instead? It is not clear why you switched from putting the ORIGIN variable into the macro variables to putting the MAKE variable into the macro variables.
So in this example I will just show how to replicate what the SQL code above does.
%macro test ;
proc sql ;
create table origins as select distinct left(origin) as origin
from sashelp.cars;
quit;
data _null_;
if eof then call symputx('count',_n_-1,'g');
set origins end=eof;
call symputx(cats('or',_n_),origin,'g');
run;
%mend ;
UPDATE
Note that if your source dataset is already sorted there is no need for an extra step to find or count the distinct values. By group processing will do that for you.
%let or1=Asia;
%let j=1;
data _null_;
set cars end=eof;
by make ;
where origin = "&&or&J" ;
if first.make then do;
make_count + 1;
call symputx(cats('make',make_count),make,'g');
end;
if eof then call symputx('make_count',make_count,'g');
run;
%put _user_;
GLOBAL J 1 GLOBAL MAKE1 Acura GLOBAL MAKE10 Nissan GLOBAL MAKE11 Scion GLOBAL MAKE12 Subaru GLOBAL MAKE13 Suzuki GLOBAL MAKE14 Toyota GLOBAL MAKE2 Honda GLOBAL MAKE3 Hyundai GLOBAL MAKE4 Infiniti GLOBAL MAKE5 Isuzu GLOBAL MAKE6 Kia GLOBAL MAKE7 Lexus GLOBAL MAKE8 Mazda GLOBAL MAKE9 Mitsubishi GLOBAL MAKE_COUNT 14 GLOBAL OR1 Asia
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
It's not clear to me what you want to do. Why does your %DO loop only go from 1 to 1? Can you clarify what it is you need to do? I think your problem is not how to convert a local to a global macro variable. I think the issue is starting with what your 2 programs are doing versus what they need to do.
Cynthia
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Your whole issue is solved by this:
proc sort data=sashelp.cars out=lookup nodupkey;
by origin make;
run;
Now you have a dataset from which you can create lookups, where conditions, whatever. No macro stuff needed. AT ALL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@thanikondharish wrote:
We have to keep in macros not dataset
Why?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Two problems with your code:
- The CO macro variable is used in your %GLOBAL statement before it has been assigned a value
- Even if you had assigned to it before trying to declare the MAKE variables %GLOBAL, you would only be declaring the last MAKE value %GLOBAL
Other than that, what are you trying to do? Your %TEST macro tries to assign values to macro variables for a specific ORIGIN value (the first). If you want to do that, you should give your %TEST macro a parameter, so that you can specify the ORIGIN value that you want, e.g.:
%macro test(origin) ;
%local i;
proc sql ;
%global co;
select count(distinct make) into:co trimmed from sashelp.cars
where strip(origin)="&origin" ;
%do i=1 %to &co;
%global make&i ;
%end;
select distinct make into:make1-:make&co trimmed from sashelp.cars
where strip(origin)="&origin" ;
quit;
%mend ;
Then you can call the macro with the ORIGIN value that you want to get the MAKE values for. Note the use of TRIMMED in the INTO clause, that removes trailing blanks from the assigned macro variables.
But generally, I would advise against putting everything into %GLOBAL values. What exactly is it you are trying to accomplish?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
%global co make&i;