<?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: Unexpected do loop behaviour in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437936#M109139</link>
    <description>&lt;P&gt;Thanks a lot &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/45151"&gt;@RW9&lt;/a&gt; and &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32246"&gt;@ChrisBrooks&lt;/a&gt; for these clear explanations and the solution to my problem.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To confirm &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/45151"&gt;@RW9&lt;/a&gt; explanation, if the put statement is moved before the set statement, it will be executed&lt;/P&gt;
&lt;P&gt;at the last iteration of the datastep :&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;68   data _NULL_;
69       put "Hi";
70       set whatever;
71       do until(eof);
72           set have end=eof;
73           put x=;
74       end;
75       put "Bye bye";
76   run;

Hi
x=foo
x=bar
x=baz
Bye bye
Hi
NOTE: There were 1 observations read from the data set WORK.WHATEVER.
NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.00 seconds
&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Fri, 16 Feb 2018 11:18:09 GMT</pubDate>
    <dc:creator>gamotte</dc:creator>
    <dc:date>2018-02-16T11:18:09Z</dc:date>
    <item>
      <title>Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437933#M109136</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have the following program :&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input x $;
cards;
foo
bar
baz
;
run;

data whatever;
y=1;
run;

data _NULL_;
    put "Hello";
    do until(eof);
        set have end=eof;
        put x=;&lt;BR /&gt;    end;
    put "Goodbye";
run;

data _NULL_;
    set whatever;
    put "Hi";
    do until(eof);
        set have end=eof;
        put x=;
    end;
    put "Bye bye";
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Which gives the following results when executed :&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;45
46
47   data _NULL_;
48       put "Hello";
49       do until(eof);
50           set have end=eof;
51           put x=;
52       end;
53       put "Goodbye";
54   run;

Hello
x=foo
x=bar
x=baz
Goodbye
Hello
NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


55
56   data _NULL_;
57       set whatever;
58       put "Hi";
59       do until(eof);
60           set have end=eof;
61           put x=;
62       end;
63       put "Bye bye";
64   run;

Hi
x=foo
x=bar
x=baz
Bye bye
NOTE: There were 1 observations read from the data set WORK.WHATEVER.
NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I dont understand why, in the first data step, "Hello" is printed a second time at the end.&lt;/P&gt;
&lt;P&gt;Is it possible to prevent this behaviour without reading an arbitrary input dataset as in&lt;/P&gt;
&lt;P&gt;the second example ?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 10:54:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437933#M109136</guid>
      <dc:creator>gamotte</dc:creator>
      <dc:date>2018-02-16T10:54:42Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437934#M109137</link>
      <description>&lt;P&gt;Is it because, and just speculating, because the set statement has moved.&amp;nbsp; In your first code, the put has to be executed on the last run to get to the point where the set statement reads the data to evaluate the EOF check, whereas in the second the EOF is evaluated earlier, so here:&lt;/P&gt;
&lt;PRE class=" language-sas"&gt;&lt;CODE class="  language-sas"&gt;&lt;SPAN class="token procnames"&gt;data&lt;/SPAN&gt; _NULL_&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
    &lt;SPAN class="token keyword"&gt;set&lt;/SPAN&gt; whatever&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Nothing to read on last, so stop, don't do put code.&lt;/P&gt;
&lt;P&gt;Here:&lt;/P&gt;
&lt;PRE class=" language-sas"&gt;&lt;CODE class="  language-sas"&gt;&lt;SPAN class="token procnames"&gt;data&lt;/SPAN&gt; _NULL_&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
    &lt;SPAN class="token keyword"&gt;put&lt;/SPAN&gt; &lt;SPAN class="token string"&gt;"Hello"&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
    do until&lt;SPAN class="token punctuation"&gt;(&lt;/SPAN&gt;eof&lt;SPAN class="token punctuation"&gt;)&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
        &lt;SPAN class="token keyword"&gt;set&lt;/SPAN&gt; have end&lt;SPAN class="token operator"&gt;=&lt;/SPAN&gt;eof&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;We have to do the put, and evaluate the do , then read the next line, which will be EOF.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 11:04:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437934#M109137</guid>
      <dc:creator>RW9</dc:creator>
      <dc:date>2018-02-16T11:04:40Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437935#M109138</link>
      <description>&lt;P&gt;The Do Loop stops executing at EOF but crucially not the data step so you get one final iteration which repeats the first Put Statement. You should put a STOP after your Do Loop like this&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _NULL_;
    put "Hello";
    
    do until(eof);
        set have end=eof;
        put x=;    end;
    put "Goodbye";
    stop;
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 16 Feb 2018 11:05:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437935#M109138</guid>
      <dc:creator>ChrisBrooks</dc:creator>
      <dc:date>2018-02-16T11:05:02Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437936#M109139</link>
      <description>&lt;P&gt;Thanks a lot &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/45151"&gt;@RW9&lt;/a&gt; and &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32246"&gt;@ChrisBrooks&lt;/a&gt; for these clear explanations and the solution to my problem.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To confirm &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/45151"&gt;@RW9&lt;/a&gt; explanation, if the put statement is moved before the set statement, it will be executed&lt;/P&gt;
&lt;P&gt;at the last iteration of the datastep :&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;68   data _NULL_;
69       put "Hi";
70       set whatever;
71       do until(eof);
72           set have end=eof;
73           put x=;
74       end;
75       put "Bye bye";
76   run;

Hi
x=foo
x=bar
x=baz
Bye bye
Hi
NOTE: There were 1 observations read from the data set WORK.WHATEVER.
NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.00 seconds
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 16 Feb 2018 11:18:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437936#M109139</guid>
      <dc:creator>gamotte</dc:creator>
      <dc:date>2018-02-16T11:18:09Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437937#M109140</link>
      <description>&lt;P&gt;Hi,&amp;nbsp;an other way is to control your put statements with:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _NULL_;
   set have end=eof;
   if _N_ eq 1 then put "Hello";
   put x=; 
   if eof then put "Goodbye";
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 16 Feb 2018 11:19:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437937#M109140</guid>
      <dc:creator>Oligolas</dc:creator>
      <dc:date>2018-02-16T11:19:23Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437939#M109142</link>
      <description>&lt;P&gt;Thanks for the advice. This is what i wanted to avoid though, since the "Hello" and "Goodbye" parts are in&lt;/P&gt;
&lt;P&gt;fact big chunks of code so i try to avoid unnecessary identations.&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 11:25:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437939#M109142</guid>
      <dc:creator>gamotte</dc:creator>
      <dc:date>2018-02-16T11:25:25Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437946#M109146</link>
      <description>&lt;P&gt;ah ok, sounds interesting...&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 12:00:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437946#M109146</guid>
      <dc:creator>Oligolas</dc:creator>
      <dc:date>2018-02-16T12:00:34Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437948#M109148</link>
      <description>&lt;P&gt;&lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://communities.sas.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt; Not really. Mostly put statements that generate a web page.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 12:09:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437948#M109148</guid>
      <dc:creator>gamotte</dc:creator>
      <dc:date>2018-02-16T12:09:18Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437952#M109150</link>
      <description>In that case you should check out Proc Stream - it’s designed for exactly that sort of thing</description>
      <pubDate>Fri, 16 Feb 2018 12:25:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437952#M109150</guid>
      <dc:creator>ChrisBrooks</dc:creator>
      <dc:date>2018-02-16T12:25:53Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437960#M109152</link>
      <description>&lt;P&gt;The application i work on was developped under SAS 9.1.3 which did not include proc stream. Switching to proc stream would be too big of a change to handle. Thanks anyway for the tip.&lt;/P&gt;</description>
      <pubDate>Fri, 16 Feb 2018 13:26:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/437960#M109152</guid>
      <dc:creator>gamotte</dc:creator>
      <dc:date>2018-02-16T13:26:40Z</dc:date>
    </item>
    <item>
      <title>Re: Unexpected do loop behaviour</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/438081#M109196</link>
      <description>&lt;P&gt;So later in the thread you clarify that this is a process that is generating a text file from a data set.&lt;/P&gt;
&lt;P&gt;The key thing to remember is that most SAS data steps do not stop on the last statement. Instead they stop when SAS reads past the end of the input in either an INPUT or SET/MERGE/UPDATE statement.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So when you are using data to generate output and you want to smoothly handle empty files setup your data step like this:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  file output ;
  if _n_=1 then put
 '&amp;lt;html&amp;gt;'
/'&amp;lt;body&amp;gt;'
  ;
  if eof then put
 '&amp;lt;/body&amp;gt;'
/'&amp;lt;/html&amp;gt;'
  ;
  set have end=eof ;
  put .... ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So the first pass writes the header. The last pass writes the footer. And then for each record read from the input something is written that will be in the middle.&amp;nbsp; &amp;nbsp;Note that&amp;nbsp;f the input dataset is empty then both of the first 2 IF statements are true and the beginning and ending are written and then the data step stops when it can't read any data.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This will work even if you add a WHERE statement after the SET statement (or use a WHERE= dataset option).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can extend it to use BY group processing also.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  file output ;
  if _n_=1 then put
 '&amp;lt;html&amp;gt;'
/'&amp;lt;body&amp;gt;'
  ;
  if eof then put
 '&amp;lt;/body&amp;gt;'
/'&amp;lt;/html&amp;gt;'
  ;
  set have end=eof ;
  by tablename ;
  if first.tablename then put 
 '&amp;lt;table&amp;gt;'
/'&amp;lt;th&amp;gt;' ...... '&amp;lt;/th&amp;gt;'
  ;
  put .... ;
  if last.tablename then put
  '&amp;lt;/table&amp;gt;'
  ;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 16 Feb 2018 21:46:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Unexpected-do-loop-behaviour/m-p/438081#M109196</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2018-02-16T21:46:50Z</dc:date>
    </item>
  </channel>
</rss>

