<?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 macro does not work unless I run the guts of the macro code first in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810053#M319436</link>
    <description>&lt;P&gt;SAS Studio 3.8.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The subject line sounds odd, I know. But I couldn't figure out how to better summarize the issue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have code that returns the number of observations in a dataset via the macro var 'NOBS'. I am trying to wrap this code into a macro so I can efficiently send it different datasets. But the macro only works if I run the inner code of the macro by itself first. Here's what I mean:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The dataset sashelp.baseball has 322 obs, so I should see NOBS=322 when I run the following macro:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro count_me_obs(my_ds);
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
%mend count_me_obs;

%let getnobs = %count_me_obs(Sashelp.Baseball);
%put &amp;amp;=nobs;&lt;BR /&gt;/* Should&amp;nbsp;return&amp;nbsp;NOBS=322&amp;nbsp;*/&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Instead I get "&lt;FONT color="#339966"&gt;WARNING: Apparent symbolic reference NOBS not resolved.&lt;/FONT&gt;" as seen below.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt; 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %macro count_me_obs(my_ds);
 70           %let dsid = %sysfunc(open(&amp;amp;my_ds.));
 71           %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 72           %let dsid = %sysfunc(close(&amp;amp;dsid.));
 73         %mend count_me_obs;
 74         
 75         %let getnobs = %count_me_obs(Sashelp.Baseball);
 76         %put &amp;amp;=nobs;
 WARNING: Apparent symbolic reference NOBS not resolved.
 nobs
 77&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;However, if I then run the following code (the guts of the macro):&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%let dsid = %sysfunc(open(Sashelp.Baseball));
%let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
%let dsid = %sysfunc(close(&amp;amp;dsid.));
%put &amp;amp;=nobs;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I correctly get this in my log:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt; 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %let dsid = %sysfunc(open(Sashelp.Baseball));
 70         %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 71         %let dsid = %sysfunc(close(&amp;amp;dsid.));
 72         %put &amp;amp;=nobs;
 NOBS=322
 73         
 74         
 75         OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;NOW&lt;/STRONG&gt;&lt;/EM&gt; if I run the macro again, I correctly get the NOBS=322 in my log. Before you think that it's just putting in the previous value of NOBS, I can send other datasets to the macro and those get counted correctly now too, like so:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro count_me_obs(my_ds);
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
%mend count_me_obs;

%let getnobs = %count_me_obs(Sashelp.Baseball);
%put &amp;amp;=nobs;
/* NOBS=322&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Class);
%put &amp;amp;=nobs;
/* NOBS=19&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Gas);
%put &amp;amp;=nobs;
/* NOBS=171&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Springs);
%put &amp;amp;=nobs;&lt;BR /&gt;/* NOBS=1587&amp;nbsp;*/&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;which gives me this log:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %macro count_me_obs(my_ds);
 70           %let dsid = %sysfunc(open(&amp;amp;my_ds.));
 71           %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 72           %let dsid = %sysfunc(close(&amp;amp;dsid.));
 73         %mend count_me_obs;
 74         
 75         %let getnobs = %count_me_obs(Sashelp.Baseball);
 76         %put &amp;amp;=nobs;
 NOBS=322
 77         
 78         %let getnobs = %count_me_obs(Sashelp.Class);
 79         %put &amp;amp;=nobs;
 NOBS=19
 80         
 81         %let getnobs = %count_me_obs(Sashelp.Gas);
 82         %put &amp;amp;=nobs;
 NOBS=171
 83         
 84         %let getnobs = %count_me_obs(Sashelp.Springs);
 85         %put &amp;amp;=nobs;
 NOBS=1587
 86         &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;So to recap: The macro doesn't work until I run the inner part of code by itself first. Then the&amp;nbsp; whole macro works all day long. It's almost like I have to slap NOBS around first to wake it up, then it performs properly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Of course, I need the code to work the first time it runs. Am I missing a step or something else? Thanks!&lt;/P&gt;</description>
    <pubDate>Wed, 27 Apr 2022 01:32:19 GMT</pubDate>
    <dc:creator>iggles</dc:creator>
    <dc:date>2022-04-27T01:32:19Z</dc:date>
    <item>
      <title>macro does not work unless I run the guts of the macro code first</title>
      <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810053#M319436</link>
      <description>&lt;P&gt;SAS Studio 3.8.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The subject line sounds odd, I know. But I couldn't figure out how to better summarize the issue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have code that returns the number of observations in a dataset via the macro var 'NOBS'. I am trying to wrap this code into a macro so I can efficiently send it different datasets. But the macro only works if I run the inner code of the macro by itself first. Here's what I mean:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The dataset sashelp.baseball has 322 obs, so I should see NOBS=322 when I run the following macro:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro count_me_obs(my_ds);
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
%mend count_me_obs;

%let getnobs = %count_me_obs(Sashelp.Baseball);
%put &amp;amp;=nobs;&lt;BR /&gt;/* Should&amp;nbsp;return&amp;nbsp;NOBS=322&amp;nbsp;*/&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Instead I get "&lt;FONT color="#339966"&gt;WARNING: Apparent symbolic reference NOBS not resolved.&lt;/FONT&gt;" as seen below.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt; 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %macro count_me_obs(my_ds);
 70           %let dsid = %sysfunc(open(&amp;amp;my_ds.));
 71           %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 72           %let dsid = %sysfunc(close(&amp;amp;dsid.));
 73         %mend count_me_obs;
 74         
 75         %let getnobs = %count_me_obs(Sashelp.Baseball);
 76         %put &amp;amp;=nobs;
 WARNING: Apparent symbolic reference NOBS not resolved.
 nobs
 77&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;However, if I then run the following code (the guts of the macro):&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%let dsid = %sysfunc(open(Sashelp.Baseball));
%let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
%let dsid = %sysfunc(close(&amp;amp;dsid.));
%put &amp;amp;=nobs;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I correctly get this in my log:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt; 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %let dsid = %sysfunc(open(Sashelp.Baseball));
 70         %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 71         %let dsid = %sysfunc(close(&amp;amp;dsid.));
 72         %put &amp;amp;=nobs;
 NOBS=322
 73         
 74         
 75         OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;NOW&lt;/STRONG&gt;&lt;/EM&gt; if I run the macro again, I correctly get the NOBS=322 in my log. Before you think that it's just putting in the previous value of NOBS, I can send other datasets to the macro and those get counted correctly now too, like so:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%macro count_me_obs(my_ds);
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
%mend count_me_obs;

%let getnobs = %count_me_obs(Sashelp.Baseball);
%put &amp;amp;=nobs;
/* NOBS=322&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Class);
%put &amp;amp;=nobs;
/* NOBS=19&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Gas);
%put &amp;amp;=nobs;
/* NOBS=171&amp;nbsp;*/&lt;BR /&gt;
%let getnobs = %count_me_obs(Sashelp.Springs);
%put &amp;amp;=nobs;&lt;BR /&gt;/* NOBS=1587&amp;nbsp;*/&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;which gives me this log:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 68         
 69         %macro count_me_obs(my_ds);
 70           %let dsid = %sysfunc(open(&amp;amp;my_ds.));
 71           %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
 72           %let dsid = %sysfunc(close(&amp;amp;dsid.));
 73         %mend count_me_obs;
 74         
 75         %let getnobs = %count_me_obs(Sashelp.Baseball);
 76         %put &amp;amp;=nobs;
 NOBS=322
 77         
 78         %let getnobs = %count_me_obs(Sashelp.Class);
 79         %put &amp;amp;=nobs;
 NOBS=19
 80         
 81         %let getnobs = %count_me_obs(Sashelp.Gas);
 82         %put &amp;amp;=nobs;
 NOBS=171
 83         
 84         %let getnobs = %count_me_obs(Sashelp.Springs);
 85         %put &amp;amp;=nobs;
 NOBS=1587
 86         &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;So to recap: The macro doesn't work until I run the inner part of code by itself first. Then the&amp;nbsp; whole macro works all day long. It's almost like I have to slap NOBS around first to wake it up, then it performs properly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Of course, I need the code to work the first time it runs. Am I missing a step or something else? Thanks!&lt;/P&gt;</description>
      <pubDate>Wed, 27 Apr 2022 01:32:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810053#M319436</guid>
      <dc:creator>iggles</dc:creator>
      <dc:date>2022-04-27T01:32:19Z</dc:date>
    </item>
    <item>
      <title>Re: macro does not work unless I run the guts of the macro code first</title>
      <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810054#M319437</link>
      <description>&lt;P&gt;That's because the macro variable NOBS is first defined within your macro&amp;nbsp;count_me_obs so is only local to that macro. Add a %GLOBAL statement to ensure NOBS is available outside your macro:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro count_me_obs(my_ds);
  %global nobs;
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
%mend count_me_obs;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 27 Apr 2022 01:39:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810054#M319437</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-04-27T01:39:21Z</dc:date>
    </item>
    <item>
      <title>Re: macro does not work unless I run the guts of the macro code first</title>
      <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810057#M319438</link>
      <description>&lt;P&gt;Thank you! That was indeed my issue. Solution worked like a charm and I'm a little more knowledgeable now for it &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 27 Apr 2022 01:56:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810057#M319438</guid>
      <dc:creator>iggles</dc:creator>
      <dc:date>2022-04-27T01:56:24Z</dc:date>
    </item>
    <item>
      <title>Re: macro does not work unless I run the guts of the macro code first</title>
      <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810061#M319441</link>
      <description>&lt;P&gt;Keeping track of scope is very important when doing macro coding. Macro variables that should "result" from the macro&amp;nbsp;&lt;U&gt;must&lt;/U&gt; be defined as global (or you won't see them outside the macro), while variables used only for the functioning of the macro itself&amp;nbsp;&lt;U&gt;must&lt;/U&gt; be defined as local to avoid unwanted side effects.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Macro definitions, OTOH, exist side-by-side in the global scope (that's why defining a macro inside another makes no sense and only reduces code readability).&lt;/P&gt;</description>
      <pubDate>Wed, 27 Apr 2022 04:50:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810061#M319441</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-04-27T04:50:17Z</dc:date>
    </item>
    <item>
      <title>Re: macro does not work unless I run the guts of the macro code first</title>
      <link>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810107#M319465</link>
      <description>&lt;P&gt;Another solution is to have the macro create text as its output, using the variable &amp;amp;NOBS, so that the assignment statement %LET GETNOBS is assigned a value:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro count_me_obs(my_ds);
  %let dsid = %sysfunc(open(&amp;amp;my_ds.));
  %let nobs = %sysfunc(attrn(&amp;amp;dsid.,nlobs));
  %let dsid = %sysfunc(close(&amp;amp;dsid.));
  &amp;amp;nobs
%mend count_me_obs;

%let getnobs = %count_me_obs(sashelp.baseball);
%put &amp;amp;=getnobs;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 27 Apr 2022 10:59:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/macro-does-not-work-unless-I-run-the-guts-of-the-macro-code/m-p/810107#M319465</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2022-04-27T10:59:14Z</dc:date>
    </item>
  </channel>
</rss>

