## Sum Values Stored in Macro Variables

Solved
Regular Contributor
Posts: 247

# Sum Values Stored in Macro Variables

I have a macro variable that I split up into X number of macro variables, each macro variable storing a number.  I want to sum up those number.  I cannot get the code below to work properly.  Can anyone help me figure out how to use the SUM() function with macro variables?

%macro enrollment(rampdata=);

%let rampmo=%sysfunc(countw(&rampdata.,'|'));

%put &rampmo.;

%do i=1 %to &rampmo.;

%let ramp&i.=%scan(&rampdata.,&i.,'|');

%let ramp&i.=%sysfunc(compress(&&ramp&i.));

%put &&ramp&i.;

%end;

%let rampsum=%eval(sum(OF ramp1-ramp&rampmo.));     /* I know this is wrong, and I tried different way here.  Can't figure it out. */

%mend enrollment;

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|10|10);

Accepted Solutions
Solution
‎04-26-2012 05:03 PM
Super User
Posts: 6,782

## Re: Sum Values Stored in Macro Variables

The SUM function doesn't exist in macro language.  In general, to use DATA step functions in macro language, you have to apply %SYSFUNC:

%let rampsum = %eval(%sysfunc(sum(of ramp1 - ramp&rampmo.)));

Even this is not a working statement, as the word OF causes trouble for macro language.

Better yet, skip most of the code and shift to:

%let rampsum = %eval(%sysfunc(translate(&rampdata, +, |)));

This will convert all the "|" to "+", then perform the math.

Good luck.

All Replies
Solution
‎04-26-2012 05:03 PM
Super User
Posts: 6,782

## Re: Sum Values Stored in Macro Variables

The SUM function doesn't exist in macro language.  In general, to use DATA step functions in macro language, you have to apply %SYSFUNC:

%let rampsum = %eval(%sysfunc(sum(of ramp1 - ramp&rampmo.)));

Even this is not a working statement, as the word OF causes trouble for macro language.

Better yet, skip most of the code and shift to:

%let rampsum = %eval(%sysfunc(translate(&rampdata, +, |)));

This will convert all the "|" to "+", then perform the math.

Good luck.

Posts: 4,736

## Re: Sum Values Stored in Macro Variables

2 more alternatives:

/* alternative 1 */
%macro enrollment(rampdata=);
%let rampmo=%sysfunc(countw(&rampdata.,'|'));
%put &rampmo.;
%let rampsum=;
%do i=1 %to &rampmo.;
%let rampsum=%sysevalf(&rampsum + %scan(&rampdata.,&i.,'|'));
%end;
%put rampsum= &rampsum.;
%mend enrollment;

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|9.5|10.5);

/* alternative 2 */
%let rampdata=0|1|2|2|4|4|5|6|8|8|13|9.5|10.5;
%let rampsum2=%sysfunc(sum(%sysfunc(translate(&rampdata,+,|))));
%put rampsum2= &rampsum2;

Posts: 3,852

## Re: Sum Values Stored in Macro Variables

Looks like you are on the road to ruin with a macro like that.  It just seems wrong to me on many levels.  What are you trying to do?

Having said that Patrick almost has it but instead of + is should be comma to accommodate missing values.

39 %macro enrollment(rampdata=);

40 %let sum = %sysfunc(sum(%sysfunc(translate(%superQ(rampdata),%str(,),|))));

41 %put NOTE: SUM=&sum;

42 %mend;

43 %enrollment(rampdata=0|1|2|2|4|4|.|5|6|8|8|13|10|10);

NOTE: SUM=73

Super User
Posts: 8,116

## Re: Sum Values Stored in Macro Variables

I prefer to use spaces as delimiters in strings.  They are easy to type, read and pass as parameters to macros.

Using a space also makes it easy to handle empty strings by adding a default value inside of the call to translate() to prevent syntax errors when the list in the macro variable is empty.

%let list= 1 2 3;

%let sum=%sysfunc(sum(%sysfunc(translate(. &list,%str(,),%str( )))));

%put sum(&list)=&sum;

sum(1 2 3)=6

%let list= ;

%let sum=%sysfunc(sum(%sysfunc(translate(. &list,%str(,),%str( )))));

%put sum(&list)=&sum;

sum()=.

Super User
Posts: 10,784

## Re: Sum Values Stored in Macro Variables

The following is inherited from your code. If you like, but I recommend to use Astounding's code.

```%macro enrollment(rampdata=);
%let rampmo=%sysfunc(countw(&rampdata.,|));
%put &rampmo.;
%do i=1 %to &rampmo.;
%let ramp&i.=%scan(&rampdata.,&i.,|);
%let ramp&i.=%sysfunc(compress(&&ramp&i.));
%if &i=1 %then %let list=&ramp1 ;
%else %let list= &list , &&ramp&i   ;
%put &&ramp&i.;
%end;
%put &list ;
%let rampsum=%sysfunc(sum( &list ));     /* I know this is wrong, and I tried different way here.  Can't figure it out. */
%put &rampsum ;
%mend enrollment;

%enrollment(rampdata=0|1|2|2|4|4|5|6|8|8|13|10|10);

0
1
2
2
4
4
5
6
8
8
13
10
10
0 , 1 , 2 , 2 , 4 , 4 , 5 , 6 , 8 , 8 , 13 , 10 , 10

```

Ksharp

🔒 This topic is solved and locked.