Indeed, you can use a macro fonction to do it easily like this :
1) Set an empty data set:
data result;
run;
2) Create a macro fonction to process your dataset.
The VAR macro-variable will be the number of dataset from your list B1,B2,B3,B4.
%macro processDatasets(var);
proc iml ;
use B&var;
read all var _ALL_ into B&var;
close B&var;
g= B&var.[1,1];
ExG = B&var.[3,1];
Res = B&var.[5,1];
E =2;
R =3;
You here store the value with a call symputx("g", B&var.[1,1], 'G');.
And then add the global macro variable into the dataset to_store.
call symputx("g", B&var.[1,1], 'G');.
....
test = g/(g+(ExG/E)+(Res/(R*E)));
print g ExG res test [format = 10.6];
create try var {g ExG res test};
append;
close try;
run; quit;
Here is the way how to store the macro variable into the current dataset.
data to_store;
g=call symget("g");
ExG=call symget("ExG");
...
run;
3) Here is the tips to concatenate multiple dataset into a result one.
data result;
set result to_store;
run;
%mend processDataset;
4) You can do several call to the function :
%processDataset(1);
%processDataset(2);
%processDataset(3);
...
5) Or you can loop through a list of number :
%macro processVarList;
%let var_list=1|2|3|4;
%let k=1;
%do %while (%qscan(&var_list, &k,|) ne );
%let VAR = %scan(&var_list, &k,|);
%processDataset(&var);
%let k = %eval(&k + 1);
%end;
%mend processVarList;
%processVarList;
6) You can adapt this code following what you want to store in the result dataset.
I didn't test the code but the idea is there.
I guess you have to store all your variable G, ExG, Res, E, R into a dataset to be merge into the final result dataset.
At the end you get all your value into the result dataset.