<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: do until loop not working as I thought it would in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824641#M325677</link>
    <description>&lt;P&gt;Thank you for taking the time to respond. In my actual task, I am reading from multiple input datasets, i.e. always the most recent 5 years, so I am trying to make the program dynamic. The challenge is that in the current year the rule for identifying the records to keep has changed and there are fields on the 2022 dataset that are not on the 2018-2021 datasets. That is why I am using the subsetting IF statement and not a WHERE dataset option.&lt;/P&gt;</description>
    <pubDate>Thu, 21 Jul 2022 13:38:38 GMT</pubDate>
    <dc:creator>GeorgeBonanza</dc:creator>
    <dc:date>2022-07-21T13:38:38Z</dc:date>
    <item>
      <title>do until loop not working as I thought it would</title>
      <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824607#M325661</link>
      <description>&lt;P&gt;Below is a simple example of a more complex task I am trying to accomplish.&amp;nbsp; What I want to do is read through all the data and accumulate AMT grouped by product using a hash object and output the hash object as a dataset once the end of the input is reached.&amp;nbsp; I want to only include products A and B and need to do this with a subsetting IF statement.&amp;nbsp; The two input datasets, HAVE1 and HAVE2 are identical except for the order of the records.&amp;nbsp; I get the output I want when I use HAVE1 but not with HAVE2 and I think it is because the last record in HAVE2 doesn't satisfy the&amp;nbsp;subsetting IF statement.&amp;nbsp; I am sure there is a simple solution, I am just not seeing it.&amp;nbsp; Any insight is appreciated.&amp;nbsp; Thanks in advance.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;data work.HAVE1;
	input PRODUCT $ AMT;
	datalines;
A 100
A 200
B 500
C 1000
B 800
;
run;

data work.HAVE2;
	input PRODUCT $ AMT;
	datalines;
A 100
A 200
B 500
B 800
C 1000
;
run;

data _null_;
	if _n_ = 1 then do;
		declare hash tot();
		tot.definekey ("PRODUCT");
		tot.definedata ("PRODUCT", "TOTAL");
		tot.definedone();
	end;
	do until (EOF);
		set work.HAVE1 end= EOF;

		if PRODUCT in ("A","B");

		if tot.find() ne 0 then call MISSING(TOTAL);
		TOTAL + AMT;
		tot.replace();
	end;
	tot.output(dataset: "work.WANT");
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 21 Jul 2022 11:50:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824607#M325661</guid>
      <dc:creator>GeorgeBonanza</dc:creator>
      <dc:date>2022-07-21T11:50:21Z</dc:date>
    </item>
    <item>
      <title>Re: do until loop not working as I thought it would</title>
      <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824610#M325663</link>
      <description>&lt;P&gt;You have correctly diagnosed the problem.&amp;nbsp; When the subsetting IF deletes the final observation, the program never gets to the test for the END= variable.&amp;nbsp; A simple solution would be to replace these statements:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;		set work.HAVE1 end= EOF;
		if PRODUCT in ("A","B");&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Instead, switch from IF to WHERE:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;		set work.HAVE1 (where=(PRODUCT in ("A", "B"))) end= EOF;&lt;/CODE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 21 Jul 2022 12:17:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824610#M325663</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2022-07-21T12:17:08Z</dc:date>
    </item>
    <item>
      <title>Re: do until loop not working as I thought it would</title>
      <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824639#M325676</link>
      <description>&lt;P&gt;This is good example of a program that violates a top down structure.&amp;nbsp; You have a DO loop where the process flow does not always enter from the top and exit from the bottom.&amp;nbsp; Instead because of the subsetting IF statement sometimes the process jumps out of the DO loop and starts another iteration of the data step.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you wan to keep the subsetting IF move the hash output to BEFORE the DO loop.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if eof then tot.output(dataset: "work.WANT");
do until( eof );
  ...&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;In this case there is no need for a subsetting if.&amp;nbsp; You could convert to a WHERE statement instead.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;where PRODUCT in ("A","B");&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;or an IF/THEN block.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if PRODUCT in ("A","B") then do;
  if tot.find() ne 0 then call MISSING(TOTAL);
  TOTAL + AMT;
  tot.replace();
end;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Once you eliminate jumping out of the DO loop you can simplify the program.&amp;nbsp; You no longer need the IF _N_=1 test since there can only be on iteration.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  declare hash tot();
  tot.definekey ("PRODUCT");
  tot.definedata ("PRODUCT", "TOTAL");
  tot.definedone();
  do until (EOF);
    set work.HAVE1 end= EOF;
    where PRODUCT in ("A","B");
    if tot.find() ne 0 then call MISSING(TOTAL);
    TOTAL + AMT;
    tot.replace();
  end;
  tot.output(dataset: "work.WANT");
  stop;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 21 Jul 2022 13:27:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824639#M325676</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-07-21T13:27:59Z</dc:date>
    </item>
    <item>
      <title>Re: do until loop not working as I thought it would</title>
      <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824641#M325677</link>
      <description>&lt;P&gt;Thank you for taking the time to respond. In my actual task, I am reading from multiple input datasets, i.e. always the most recent 5 years, so I am trying to make the program dynamic. The challenge is that in the current year the rule for identifying the records to keep has changed and there are fields on the 2022 dataset that are not on the 2018-2021 datasets. That is why I am using the subsetting IF statement and not a WHERE dataset option.&lt;/P&gt;</description>
      <pubDate>Thu, 21 Jul 2022 13:38:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824641#M325677</guid>
      <dc:creator>GeorgeBonanza</dc:creator>
      <dc:date>2022-07-21T13:38:38Z</dc:date>
    </item>
    <item>
      <title>Re: do until loop not working as I thought it would</title>
      <link>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824659#M325681</link>
      <description>Thank you Tom. Your responses are always detailed and usually contain multiple ways to solve the problem. I always learn something from your solutions. I appreciate you taking the time to respond.</description>
      <pubDate>Thu, 21 Jul 2022 14:06:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/do-until-loop-not-working-as-I-thought-it-would/m-p/824659#M325681</guid>
      <dc:creator>GeorgeBonanza</dc:creator>
      <dc:date>2022-07-21T14:06:39Z</dc:date>
    </item>
  </channel>
</rss>

