The Correct code is bellow.
%macro mymacro;
%let i=0;
%let j=0;
%do %until(&i>5);
%do %until(&j>5);
%let product=%sysevalf(&i*&j);
%put The result is &product;
%let j=%eval(&j+1);
%end;
%let i=%eval(&i+1);
%end;
%mend;
%mymacro;
The Macro compiler is called by a word processor in SAS.
When you wrote a do in side a %do, SAS assumed that the do is a part of some other sas statement which will be used after the macro processing. That you can see if you try to execute the macro. You will get the following error.
NOTE: Line generated by the invoked macro "MYMACRO".
85 do until(&j>5);
__
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
The result is 0
NOTE: Line generated by the invoked macro "MYMACRO".
85 end;
___
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: Line generated by the invoked macro "MYMACRO".
85 do until(&j>5);
__
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
The result is 1
NOTE: Line generated by the invoked macro "MYMACRO".
85 end;
___
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: Line generated by the invoked macro "MYMACRO".
85 do until(&j>5);
__
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
The result is 4
.
.
.
Macro is a very powerfull lnguage which can be mixed with BASE SAS to get results, but macro can not be mixed with BASE SAS utilities alone.