BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
KentaMURANAKA
Pyrite | Level 9

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 ?????????? ;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Shmuel
Garnet | Level 18

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.

View solution in original post

10 REPLIES 10
Shmuel
Garnet | Level 18

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 &check;

KentaMURANAKA
Pyrite | Level 9

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.

Shmuel
Garnet | Level 18

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.

KentaMURANAKA
Pyrite | Level 9

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!!

Kurt_Bremser
Super User

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:

  • concatenating is extremely easy in macro language, as you can see
  • by only using macro code, this macro can be placed right in the middle of a data or procedure step, without causing a step boundary
KentaMURANAKA
Pyrite | Level 9

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 !

Kurt_Bremser
Super User

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
KentaMURANAKA
Pyrite | Level 9

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!!

Kurt_Bremser
Super User

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)

 

KentaMURANAKA
Pyrite | Level 9

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!!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 10 replies
  • 914 views
  • 5 likes
  • 3 in conversation