0
votes

My loop is only making 1 iteration. I am supposed to create three macro variables: var1 = Month1, var2 = Month2, and var3 = Month3 if qtr = qtr1. My loop is only creating var1 = Month1 and I = 1 when I checked it with a Put statement. It is only making one iteration, so I'm not sure what I am doing wrong.

%Let qtr = qtr1;

%Macro Firstqtr(qtr);

%Let I = 1;

%If &qtr = qtr1 %then %do %until (&I > 3);

%Let var&I = Month&I;

%let I = %eval(&I + 1);

%end;

%Mend Firstqtr;

%Firstqtr(qtr);
3
Your posted program will never run the %DO loop because the condition in the %IF statement will be FALSE.Tom

3 Answers

0
votes

Your %DO loop will never run given the input you made for the QTR parameter to your macro. You can turn on MLOGIC to see this.

1228  options mlogic;
1229  %Firstqtr(qtr);
MLOGIC(FIRSTQTR):  Beginning execution.
MLOGIC(FIRSTQTR):  Parameter QTR has value qtr
MLOGIC(FIRSTQTR):  %LET (variable name is I)
MLOGIC(FIRSTQTR):  %IF condition &qtr = qtr1 is FALSE
MLOGIC(FIRSTQTR):  Ending execution.

If you want to pass in qtr1 as the value either hard code it in the macro call.

%Firstqtr(qtr1);

Or you could make your call pass in the macro variable you defined earlier.

%let qtr=qtr1;
%Firstqtr(&qtr);

It might make this distinction between the parameter's value and the value of an external macro variable with the same name clearer if you call the macro using named parameters. Note: you can use parameter names in the macro call even for parameters that were defined as positional in the macro definition.

%Firstqtr(qtr=&qtr);
0
votes
option mprint;
%global qtr;
%Let qtr = qtr1;

%Macro Firstqtr(qtr);

%Let I = 1;

%If &qtr = &qtr  %then %do %until (&I > 3);

%Let var&I = Month&I;

%let I = %eval(&I + 1);

%end;
%put &var1 &var2 &var3;

%Mend Firstqtr;

%Firstqtr(qtr);

You have to declare qtr as Global variable then only the if condition will be pass.

0
votes

The issue is one of macro variable scope. qtr is defined both globally (line1) and locally (as a macro parameter) so the local (empty) one is used instead.

Try passing it through in your parameter as follows:

%Let qtr = qtr1;

%Macro Firstqtr(qtr);
  %Let I = 1;
  %If &qtr = qtr1 %then %do %until (&I > 3);
    %global var&i;
    %Let var&I = Month&I;
    %put var&i=&&var&i;
    %let I = %eval(&I + 1);
  %end;
%mend Firstqtr;

%Firstqtr(&qtr);

Be aware that the variables you are creating would have local scope - to make them global, you declare them as such (%global statement).