Hello, there:
I would like to generate macro variable that includes same strings repeatedly, and that has name I want.
I have 3 ideas (for more details, please see below), and like Pattern 3, I would like to generate macro variable with name I want in same step (in MACRO setting).
But after submitting Pattern 3 code, I get WARNING. I do not know why and how to resolve this problem.
If you have any ideas, please let me know. Any ideas would be welcome.
Thank you in advance.
***** Pattern 1 ;
In this pattern, I have to define null macro variable first.
* Pattern 1: Define MACRO VARIABLEs in advance ;
***** First, you have to define MACRO VARIABLEs you want ;
%let re5=;
***** Second, specify word you want to repeat ;
%let t=WORD;
***** MACRO Setting ;
%macro re(max=);
data re(drop=i);
length re $2000.;
array ar1(*) $ re1-re&max.;
do i=1 to dim(ar1);
ar1(i)='&t';
end;
re=catx(" ", of re1-re&max.);
run;
proc sql noprint;
select re into :re&max.
from work.re
;
quit;
%mend re;
***** Finally, generate MACRO VARIABLE & check content ;
%re(max=5)
%put &re5.;
***** If you don't define MACRO VARIABLEs in advance, get WARNING ;
%re(max=100)
%put &re100.;
***** Pattern 2 ;
In this pattern, after submitting MACRO, I have to define macro variable with name I want.
* Pattern 2: After setting MACRO, Store MACRO VARIABLEs with name you want ;
***** First, specify word you want to repeat ;
%let t=WORD;
***** MACRO Setting ;
%macro re(max=);
data re(drop=i);
length re $2000.;
array ar1(*) $ re1-re&max.;
do i=1 to dim(ar1);
ar1(i)='&t';
end;
re=catx(" ", of re1-re&max.);
run;
%mend re;
***** Second, submit your MACRO ;
%re(max=10)
***** Finally, generate MACRO VARIABLE with name you want & check ;
proc sql noprint;
select re into :re10
from work.re
;
quit;
%put &re10.;
***** Pattern 3 ;
In this pattern, I think I can generate macro variable with name I want, but this code does not work.....
* Pattern 3: In same step (MACRO Setting), generate MACRO VARIABLE with name you want ;
***** NOTE: There're some problems in this method ;
***** First, specify word you want to repeat ;
%let t=WORD;
***** MACRO Setting ;
%macro re(max=);
data re(drop=i);
length re $2000.;
array ar1(*) $ re1-re&max.;
do i=1 to dim(ar1);
ar1(i)='&t';
end;
re=catx(" ", of re1-re&max.);
run;
********** At here, in MACRO Setting, I want to generate MACRO VARIABLE with name I want, but something is wrong..... ;
data _null_;
set re;
call symputx("re&max.", re);
run;
%mend re;
***** Finally, generate MACRO VARIABLE & check content ;
%re(max=15)
%put &re15.; * <----------Submit WARNING ?????????? ;
In your code:
%let txt=%str(WORD );
%macro re(max=);
data _null_;
length re $2000.;
re=repeat("&txt", &max.-1);
call symputx("re&max.", strip(re));
run;
%mend re;
%re(max=10)
%put &re10.;
the RE&max macro variable is created inside the macro code, which means it is by default local macro variable.
You need to add %global re&max; statement inside the macro.
Try next code:
%let txt=any string # ;
%let n =3;
data _NULL_;
length long_string = repeat("&txt", &n-1);
call symput('Check', strip(long_string));
run;
%put ✓
Hi, Shmuel-san:
Thank you for quick reply & your code is simple, wonderful.
I did not know REPEAT function.
Below works.
%let txt=%str(WORD );
%let max=5;
data _null_;
length re $2000.;
re=repeat("&txt", &max.-1);
call symputx("re&max.", strip(re));
run;
%put &&re&max..;
But I want to use multiple macro variables like RE5 (5 times repeated), or RE10 (10 times repeated), etc., so if possible, I want to conduct this operation in MACRO. Referring to your code, I tried to create this MACRO, but I get WARNING.
%let txt=%str(WORD );
%macro re(max=);
data _null_;
length re $2000.;
re=repeat("&txt", &max.-1);
call symputx("re&max.", strip(re));
run;
%mend re;
%re(max=10)
%put &re10.;
Do you know why and how to resolve this?
Thank you in advance.
In your code:
%let txt=%str(WORD );
%macro re(max=);
data _null_;
length re $2000.;
re=repeat("&txt", &max.-1);
call symputx("re&max.", strip(re));
run;
%mend re;
%re(max=10)
%put &re10.;
the RE&max macro variable is created inside the macro code, which means it is by default local macro variable.
You need to add %global re&max; statement inside the macro.
Hi, Shmuel-san:
Thank you, I understand!!
In summary,
KurtBremser-san's idea is.....
%macro re(var=, txt=, rep=);
%global &var.;
%let &var.=;
%do i=1 %to &rep.;
%let &var.=&&&var. &txt.;
%end;
%mend re;
%re(var=re10, txt=WORD, rep=10)
%put &re10.;
and Shmuel-san's idea is.....
%let txt=%str(WORD );
%macro re(max=);
%global re&max.;
data _null_;
length re $2000.;
re=repeat("&txt", &max.-1);
call symputx("re&max.", strip(re));
run;
%mend re;
%re(max=7)
%put &re7.;
I think both ideas are wonderful.
Thank you, Shmuel-san, KurtBremser-san!!
I usually prefer to build my macro variables in data steps, as the syntax is simpler, and I do not need %sysfunc to use data step functions.
But here there are two factors:
Hi, KurtBremser-san:
I think same as you.
I almost always create macro variables in DATA step (or SQL step),
so for me, your idea is eye-opener.
Thank you !
You can do it in the macro without using an additional data step, and it's not even complicated:
%macro repeat_text(varname,text,rep);
%global &varname.;
%let &varname.=;
%do i = 1 %to &rep.;
%let &varname=&&&varname. &text.;
%end;
%mend;
%repeat_text(re,word,3)
%put &re.;
Log:
37 %macro repeat_text(varname,text,rep); 38 %global &varname.; 39 %let &varname.=; 40 %do i = 1 %to &rep.; 41 %let &varname=&&&varname. &text.; 42 %end; 43 %mend; 44 45 %repeat_text(re,word,3) 46 47 %put &re.; word word word
Hi, KurtBremser-san:
Thank you for reply. Your code worked! Aha!
%macro re(var=, txt=, rep=);
%global &var.;
%let &var.=;
%do i=1 %to &rep.;
%let &var.=&&&var. &txt.;
%end;
%mend re;
%re(var=re10, txt=WORD, rep=10)
%put &re10.;
I think three ampersands are important (I do not understand why).
Anyway, thank you, KurtBremser-san, Shmuel-san!!
Regarding the three ampersands:
When the macro processor resolves macro triggers (& or %), it can and will do so repeatedly.
Two ampersands are converted to one on each pass, so what happens is this:
Pass 1:
&&&varname. -> & (converted from the first two ampersands) re10 (content of macro variable &varname)
so you get
&re10
(the dot is removed; if this was part of some longer string, you also need to add additional dots for each pass)
Pass 2:
&re10. --> (contents of &re10)
Hi, KurtBremser-san:
Thank you for your kind advice. I understand now!
Regarding to "%let &var.=&&&var.. &txt.",
first "&var." means variable name,
and second "&&&var.." means, not variable name, it means variable content.
Thank you!!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.