I suppose that the most likely reason to use subsets in a Do loop rather than just mapping (/@) a function is to conserve memory. Therefore I would like to point out that the third argument of Subsets specifies which subset(s) within the sequence to return. If one were attempting to find all subsets that sum to a certain value without first storing all subsets in memory one might use it like this:
SeedRandom[1]
set = RandomInteger[123, 50];
n = 3;
Do[
If[Total@# == 37, Print@#] & @@ Subsets[set, {n}, {i}],
{i, Binomial[Length@set, n]}
]
{14,0,23} {0,4,33} {3,24,10} {3,4,30} {3,1,33} {23,4,10} {15,4,18}
{1,26,10}
(This is a brute force approach to that particular problem and there are better ways, but it serves as an illustration.)
In practice this is painfully slow. To make it practical you would process the subsets in blocks. Here in blocks of 10,000 subsets each:
SeedRandom[1]
set = RandomInteger[2000, 250];
n = 3;
Do[
If[Total@# == 137, Print@#] & /@ Quiet@Subsets[set, {n}, {i, i + 10000}],
{i, 1, Binomial[Length@set, n], 10000}
]
{28,16,93}
{28,106,3}