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

Hi Folks,

 

I need to execute a macro inside data step. I made a simple example but the following error appears:

 

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
       valor_2 
ERROR: %EVAL function has no expression to evaluate, or %IF statement has no condition.
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro VALOR will stop executing.

Our example is:

 

%global valor_final;

%macro valor (var_1, var_2);
%let valor_final=;
%do i=1 %to %eval(&var_2);
  %if &i=1 %then %let valor_final = &var_2. ;  
  %else %let valor_final = &valor_final., &var_1. ; 
%end;
%mend valor;


data test;
   valor_1=90; 
   valor_2 = 5;
   %valor(valor_1, valor_2);
   var_final = SUM(&valor_final.);
run;

In this case, our objective is parameter "VALOR_FINAL" will be replace by: "90, 90, 90, 90, 90". So the program will be:

 

data test;
   valor_1=90; 
   valor_2 = 5;
   %valor(valor_1, valor_2);
   var_final = SUM(90, 90, 90, 90, 90);
run;

Regards,

1 ACCEPTED SOLUTION

Accepted Solutions
Oligolas
Barite | Level 11

Hi,

as it has been said you do not Need a macro to perform this Kind of Operation.

For Demonstration purpose there are 2 ways to run a macro inside a data step: dosubl and call execute.

 

dosubl:

%macro valor (var_1, var_2);
   %do i=1 %to %eval(&var_2);
     %if &i=1 %then %let valor_final = &var_1. ;  
     %else %let valor_final = &valor_final., &var_1. ; 
   %end;
   %put &=valor_final;
   %let valor_final = %sysfunc(sum(&valor_final.)); 
   %put &=valor_final;
%mend valor;

data test;
   set sashelp.class;
   valor_1=weight; 
   valor_2 = age;

   rc = dosubl('%global valor_final; %valor('||put(valor_1,best.)||','||put(valor_2,best.)||')');
   var_final=symget('valor_final');
   rc = dosubl('%symdel valor_final');
   keep va: rc:;
run;
proc print;run;

call execute:

%macro valor (var_1, var_2);
   %local valor_final;
   %do i=1 %to %eval(&var_2);
     %if &i=1 %then %let valor_final = &var_1. ;  
     %else %let valor_final = &valor_final., &var_1. ; 
   %end;
   %put &=valor_final;
   %let valor_final = %sysfunc(sum(&valor_final.)); 
   %put &=valor_final;
   &valor_final.
%mend valor;

data test1;
   set sashelp.class end=last;
   valor_1=weight; 
   valor_2 = age;

   if _N_ eq 1 then call execute('data test2;');
   call execute('var_final=%nrstr(%valor('||put(valor_1,best.)||','||put(valor_2,best.)||'));output;');
   if last then call execute('run;');
run;
proc print;run;

Give them a try and have fun with it 🙂

________________________

- Cheers -

View solution in original post

7 REPLIES 7
smantha
Lapis Lazuli | Level 10

Macro resolution is compile time only and not execution time inside a datastep. %let does not work. 

The options you have are sum(of valor_1 -- valor_n) if you have a repeating pattern in your variable names such as valor_: as suggested previously.

Use combination of arrays and sum function.

array x{*} var1 dummy2 someotherthing;

sum(of x:)

 

MariaD
Barite | Level 11

Hi @smantha ,

 

The main objective is not to use with SUM function, was only a sample. Our problem is we have a value 90, por example in a variable and 5 in other variable. We need to create of list of 90 value, separated by ",", 5 times. So, we expected a result of 90, 90, 90, 90, 90 to use in other process. 

 

I know exists REPEAT function, but the if we use REPEAT(90, 5) the result is 9090909090 (without a separated value). 

 

Regards,

smantha
Lapis Lazuli | Level 10

The value of  valor_2 is not resolved at compile time and is symbolically passed as a character string valor_2

MariaD
Barite | Level 11

Yes, @smantha. The macro takes valor_2 as text not the value of the variable called valor_2.

 

Regards, 

ed_sas_member
Meteorite | Level 14

Hi @MariaD 

 

An approach to avoid this:

data test;
   valor_1=2; 
   valor_2 = 5;
   call symputx ("valor_final", prxchange('s/\s+/,/',-1,strip(repeat(valor_1,valor_2-1))));
run;

data want;
	set test;
	var_final = sum(&valor_final.);
run;
LeonidBatkhan
Lapis Lazuli | Level 10

Hi MariaD,

 

If your objective is to replace VALOR_FINAL by: "90, 90, 90, 90, 90", why do you need SUM function and the macro?

 

data test;
   valor_1=90; 
   valor_2 = 5;
   %valor(valor_1, valor_2);
   var_final = SUM(&valor_final.);
run;

Why not just replace your above code with:

data test;
   valor_1=90; 
   valor_2 = 5;
   var_final = valor_1 * valor_2;
run;

?

 

 

Oligolas
Barite | Level 11

Hi,

as it has been said you do not Need a macro to perform this Kind of Operation.

For Demonstration purpose there are 2 ways to run a macro inside a data step: dosubl and call execute.

 

dosubl:

%macro valor (var_1, var_2);
   %do i=1 %to %eval(&var_2);
     %if &i=1 %then %let valor_final = &var_1. ;  
     %else %let valor_final = &valor_final., &var_1. ; 
   %end;
   %put &=valor_final;
   %let valor_final = %sysfunc(sum(&valor_final.)); 
   %put &=valor_final;
%mend valor;

data test;
   set sashelp.class;
   valor_1=weight; 
   valor_2 = age;

   rc = dosubl('%global valor_final; %valor('||put(valor_1,best.)||','||put(valor_2,best.)||')');
   var_final=symget('valor_final');
   rc = dosubl('%symdel valor_final');
   keep va: rc:;
run;
proc print;run;

call execute:

%macro valor (var_1, var_2);
   %local valor_final;
   %do i=1 %to %eval(&var_2);
     %if &i=1 %then %let valor_final = &var_1. ;  
     %else %let valor_final = &valor_final., &var_1. ; 
   %end;
   %put &=valor_final;
   %let valor_final = %sysfunc(sum(&valor_final.)); 
   %put &=valor_final;
   &valor_final.
%mend valor;

data test1;
   set sashelp.class end=last;
   valor_1=weight; 
   valor_2 = age;

   if _N_ eq 1 then call execute('data test2;');
   call execute('var_final=%nrstr(%valor('||put(valor_1,best.)||','||put(valor_2,best.)||'));output;');
   if last then call execute('run;');
run;
proc print;run;

Give them a try and have fun with it 🙂

________________________

- Cheers -

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 1226 views
  • 0 likes
  • 5 in conversation