<?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: dosubl - order of execution in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680501#M205676</link>
    <description>&lt;P&gt;Any code in double quotes using percent or ampersand notation will be resolved before execution begins, so DOSUBL will execute &lt;EM&gt;after&lt;/EM&gt; %LET Colname2 = Colname1 has already been resolved.&amp;nbsp; Likewise, the "colname1" in COUNT(distinct &amp;amp;colname1) will have been resolved before the DOSUBL begins execution.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As earlier replies have suggested, a single quote delays resolution of the percent and ampersand notated code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Another option is to bypass the use of DOSUBL (which is expensive in terms of CPU time) and the use of SYMGET and code the following:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%LET	Obs	=	3;

DATA	_NULL_;
	i	+	1;
	set sashelp.vcolumn(obs = &amp;amp;Obs); 
		where libname = 'SASHELP' and memname = 'CARS'; 

	call symput(CATS('colname', PUT(i, 5.)), name); 
RUN;

&amp;amp;Null	%MACRO	Get_Counts(Obs);
	%DO	i	=	1	%TO	&amp;amp;Obs;
		OPTIONS	NONOTES;
		proc sql;
			select	count(distinct &amp;amp;&amp;amp;colname&amp;amp;i)	AS	Distinct_Count
				into	:dist_count 
				from	SASHELP.CARS 
				;
		QUIT; 
		OPTIONS	NOTES;

		%PUT	&amp;amp;Nte2  ;
		%PUT	&amp;amp;Nte1  Colname&amp;amp;i=&amp;amp;&amp;amp;colname&amp;amp;i; 
		%PUT	&amp;amp;Nte2  Distinct Count=%SYSFUNC(STRIP(&amp;amp;dist_count));
	%END;
%MEND	Get_Counts;

%Get_Counts(&amp;amp;Obs);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The log from the above looks like:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;NOTE:  Colname1=Make
       Distinct Count=38
     
NOTE:  Colname2=Model
       Distinct Count=425
     
NOTE:  Colname3=Type
       Distinct Count=6&lt;/PRE&gt;
&lt;P&gt;The data step creates a little macro array, and then an SQL step is driven by the macro array.&amp;nbsp; To me, this is easier to follow the logic of, but each to their own.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Jim&lt;/P&gt;</description>
    <pubDate>Mon, 31 Aug 2020 18:01:54 GMT</pubDate>
    <dc:creator>jimbarbour</dc:creator>
    <dc:date>2020-08-31T18:01:54Z</dc:date>
    <item>
      <title>dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680391#M205616</link>
      <description>&lt;P&gt;I struggle to understand the behavior of the following code (SAS 9.3).&amp;nbsp;&lt;/P&gt;&lt;P&gt;(Although the objective is to count distinct values for the columns in "Sashelp.Cars", i am primarily interested in help with understanding why it is not working as expected.)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data testing (keep = libname memname name dist_count colname1 colname2); 

  set sashelp.vcolumn(obs = 3); 
  where libname = 'SASHELP' and memname = 'CARS'; 

  call symput('colname1', name); 
  rc = dosubl("
    %let colname2 = &amp;amp;colname1;
    proc sql noprint;
      select 
        count(distinct &amp;amp;colname1) into :dist_count 
      from 
        SASHELP.CARS quit; 
    ");
 
  dist_count = symget('dist_count');
  colname1 = symget('colname1');
  colname2 = symget('colname2'); 
run;

%put &amp;amp;colname1; 
%put &amp;amp;colname2;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;The first time the code is submitted it gives the following warning:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;WARNING: Apparent symbolic reference COLNAME1 not resolved.&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;The last two lines both outputs "Type" which is what I expected.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In the resulting dataset, the column "dist_count" and "colnam1" is as expected. "colname2" on the other hand takes the value "&amp;amp;colname1".&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="testing_1_run.PNG" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/48815i7F7430DFCF7ABD0C/image-size/large?v=v2&amp;amp;px=999" role="button" title="testing_1_run.PNG" alt="testing_1_run.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;When the code is submited one more time, no warnings are generated but in the dataset the column "dist_count" are no longer as expected. Also all values in "colname2" are now "Type".&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="testing_2_run.PNG" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/48816i76B3CA56636B1163/image-size/large?v=v2&amp;amp;px=999" role="button" title="testing_2_run.PNG" alt="testing_2_run.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Again, the last two lines generates "Type".&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The most obvious problem is that "dist_count" no longer is assigned the right values the second time the code is submited.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Im interessted in knowing why is this is, and how is it is to be avoided in other scenarios?&lt;/P&gt;</description>
      <pubDate>Mon, 31 Aug 2020 08:33:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680391#M205616</guid>
      <dc:creator>steinarv</dc:creator>
      <dc:date>2020-08-31T08:33:38Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680397#M205618</link>
      <description>&lt;P&gt;Seems to be a timing-issue: because you are using double-quotes in dosubl, the macro-statements are resolved before call symputx is executed. Switching to single-quotes seems to solve the problem.&lt;/P&gt;</description>
      <pubDate>Mon, 31 Aug 2020 09:53:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680397#M205618</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2020-08-31T09:53:40Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680433#M205638</link>
      <description>&lt;P&gt;Agree with Andreas's solution to change to single quotes to avoid the macro variables attempting to resolve before the CALL SYMPUTX has executed.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Part of your confusion in not being able to replicate the results of your first run is the common problem related to global macro variables.&amp;nbsp; On the second submission, the macro variables exist from the first submission.&amp;nbsp; It's one of the reasons that global macro variables often prove problematic.&amp;nbsp; For this sort of playing around, if you are going to create global macro variables in the code, I would start the code by deleting them:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%symdel colname1 colname2 dist_count / nowarn;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another side point is that you don't need to create macro variables colname1 or colname2 in order to pass values to the DOSUBL side session.&amp;nbsp; Since you already have the value in the PDV variable NAME, you can use that variable to build the string passed to DOSUBL, e.g.:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%symdel dist_count / nowarn;

data testing (keep = libname memname name dist_count); 

  set sashelp.vcolumn(obs = 3); 
  where libname = 'SASHELP' and memname = 'CARS'; 

  rc = dosubl('
    proc sql noprint;
      select 
        count(distinct ' || name || ') into :dist_count 
      from 
        SASHELP.CARS quit; 
    ');
 
  dist_count = symget('dist_count');

  put (_ALL_)(=) ; 
run;

%symdel dist_count ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 31 Aug 2020 13:45:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680433#M205638</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2020-08-31T13:45:26Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680501#M205676</link>
      <description>&lt;P&gt;Any code in double quotes using percent or ampersand notation will be resolved before execution begins, so DOSUBL will execute &lt;EM&gt;after&lt;/EM&gt; %LET Colname2 = Colname1 has already been resolved.&amp;nbsp; Likewise, the "colname1" in COUNT(distinct &amp;amp;colname1) will have been resolved before the DOSUBL begins execution.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As earlier replies have suggested, a single quote delays resolution of the percent and ampersand notated code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Another option is to bypass the use of DOSUBL (which is expensive in terms of CPU time) and the use of SYMGET and code the following:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%LET	Obs	=	3;

DATA	_NULL_;
	i	+	1;
	set sashelp.vcolumn(obs = &amp;amp;Obs); 
		where libname = 'SASHELP' and memname = 'CARS'; 

	call symput(CATS('colname', PUT(i, 5.)), name); 
RUN;

&amp;amp;Null	%MACRO	Get_Counts(Obs);
	%DO	i	=	1	%TO	&amp;amp;Obs;
		OPTIONS	NONOTES;
		proc sql;
			select	count(distinct &amp;amp;&amp;amp;colname&amp;amp;i)	AS	Distinct_Count
				into	:dist_count 
				from	SASHELP.CARS 
				;
		QUIT; 
		OPTIONS	NOTES;

		%PUT	&amp;amp;Nte2  ;
		%PUT	&amp;amp;Nte1  Colname&amp;amp;i=&amp;amp;&amp;amp;colname&amp;amp;i; 
		%PUT	&amp;amp;Nte2  Distinct Count=%SYSFUNC(STRIP(&amp;amp;dist_count));
	%END;
%MEND	Get_Counts;

%Get_Counts(&amp;amp;Obs);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The log from the above looks like:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;NOTE:  Colname1=Make
       Distinct Count=38
     
NOTE:  Colname2=Model
       Distinct Count=425
     
NOTE:  Colname3=Type
       Distinct Count=6&lt;/PRE&gt;
&lt;P&gt;The data step creates a little macro array, and then an SQL step is driven by the macro array.&amp;nbsp; To me, this is easier to follow the logic of, but each to their own.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Jim&lt;/P&gt;</description>
      <pubDate>Mon, 31 Aug 2020 18:01:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680501#M205676</guid>
      <dc:creator>jimbarbour</dc:creator>
      <dc:date>2020-08-31T18:01:54Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680514#M205680</link>
      <description>&lt;P&gt;Another possible DOSUBL approach would be to write a function-style macro that calculates the cardinality of a variable, e.g.:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro cardinality(data=,var=);
  %local rc emit; 

  %let rc=%sysfunc(dosubl(%nrstr(
     proc sql noprint;
       select 
         count(distinct &amp;amp;var) into :emit
       from 
         &amp;amp;data
     quit; 

  )));

  &amp;amp;emit 
%mend ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then you can read the driver data and use the RESOLVE function to build macro calls, it ends up looking like CALL EXECUTE:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data testing (keep = libname memname name dist_count); 

  set sashelp.vcolumn; 
  where libname = 'SASHELP' and memname = 'CARS'; 

  dist_count=resolve('%cardinality('
                                || ' data= ' || cats(libname,'.',memname)
                                || ',var= '  || name
                                || ')'
                      ) ;
  put (libname memname name dist_count)(=) ; 
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;There are more efficient ways to calculate cardinality (see e.g.&amp;nbsp;&lt;A href="https://blogs.sas.com/content/sasdummy/2013/10/16/about-cardinality/" target="_blank"&gt;https://blogs.sas.com/content/sasdummy/2013/10/16/about-cardinality/&lt;/A&gt;&amp;nbsp;and the papers mentioned in the comment section), but if you're playing around with DOSUBL, the ability to write function-style macros is handy.&lt;/P&gt;</description>
      <pubDate>Mon, 31 Aug 2020 19:07:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680514#M205680</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2020-08-31T19:07:35Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680636#M205741</link>
      <description>&lt;P&gt;Thank you for the explanation. Since you write "&lt;EM&gt;the macro variables attempting to resolve before the CALL SYMPUTX has executed", &lt;/EM&gt;I assume this does not happen the first time I submit the code. And this is why it is working as expected the first time..&lt;/P&gt;</description>
      <pubDate>Tue, 01 Sep 2020 07:51:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680636#M205741</guid>
      <dc:creator>steinarv</dc:creator>
      <dc:date>2020-09-01T07:51:49Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680640#M205744</link>
      <description>Thank you for your explanation and suggestion. The order of execution of dosubl was my main concern, rather than cardinality. It is still very useful and instructive to see alternative approaches to these kinds of problems.&lt;BR /&gt;&lt;BR /&gt;When I try to run your code I get some warnings about NULL and $nte: “Apparent symbolic reference not resolved”.&lt;BR /&gt;</description>
      <pubDate>Tue, 01 Sep 2020 08:06:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680640#M205744</guid>
      <dc:creator>steinarv</dc:creator>
      <dc:date>2020-09-01T08:06:27Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680695#M205769</link>
      <description>&lt;P&gt;&amp;amp;Null is just a trick to preserve coloration in the SAS editor.&amp;nbsp; The definition is:&lt;/P&gt;
&lt;P&gt;%let Null = ;&lt;/P&gt;
&lt;P&gt;&amp;amp;Null therefore resolves to, well, nothing.&amp;nbsp; By putting &amp;amp;Null before the %MACRO, the colorization of the DATA step and other non-macro code is preserved.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;amp;Nte1 resolves to NOTE:&lt;/P&gt;
&lt;P&gt;&amp;amp;Nte2 resolves to NOTE-&lt;/P&gt;
&lt;P&gt;I also use:&lt;/P&gt;
&lt;P&gt;&amp;amp;Warn1 which resolves to WARNING:&lt;/P&gt;
&lt;P&gt;&amp;amp;Warn2 which resolves to WARNING-&lt;/P&gt;
&lt;P&gt;&amp;amp;Err1 which resolves to ERROR:&lt;/P&gt;
&lt;P&gt;&amp;amp;Err2 which resolves to ERROR-&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I use these to make text searches in the SAS log easier.&amp;nbsp; If I search on, for example, "Error: " I only find places where an actual error is issued by SAS, not occurances in the source code which may or may not have actually executed.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Jim&lt;/P&gt;</description>
      <pubDate>Tue, 01 Sep 2020 13:25:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680695#M205769</guid>
      <dc:creator>jimbarbour</dc:creator>
      <dc:date>2020-09-01T13:25:57Z</dc:date>
    </item>
    <item>
      <title>Re: dosubl - order of execution</title>
      <link>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680697#M205771</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/343687"&gt;@steinarv&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Thank you for the explanation. Since you write "&lt;EM&gt;the macro variables attempting to resolve before the CALL SYMPUTX has executed", &lt;/EM&gt;I assume this does not happen the first time I submit the code. And this is why it is working as expected the first time..&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Not quite.&amp;nbsp; It happens every time you submit the code.&amp;nbsp; Here's a simpler example without DOSUBL.&amp;nbsp; Because for your original question, the key point is that macro references inside of double quotes are resolved when the step compiles (before it executes):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you code (in a fresh SAS session):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data testing; 

  set sashelp.vcolumn(obs = 3); 
  where libname = 'SASHELP' and memname = 'CARS'; 

  call symput('colname1', name); 

  str="The value of colname1 is: &amp;amp;colname1" ;
  put str= ;
 
  colname1 = symget('colname1');
  put colname1= ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;When the step compiles, the compiler gets to the assignment statement for STR, and attempts to resolve a macro variable named colname1.&amp;nbsp; There is no existing macro variable named colname1, so it throws the cannot resolve warning, and the failed macro resolution attempt returns &amp;amp;colname1.&amp;nbsp; The PUT str= statement will print the same line three times.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note that the SYMGET() function succeeds, because it does its work while the step is executing (not compiling).&amp;nbsp; When SYMGET executes, there is a macro variable named colname1, and it has a different value every time symget executes.&amp;nbsp; The log is:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;1    data testing;
2
3      set sashelp.vcolumn(obs = 3);
4      where libname = 'SASHELP' and memname = 'CARS';
5
6      call symput('colname1', name);
7
8      str="The value of colname1 is: &amp;amp;colname1" ;
WARNING: Apparent symbolic reference COLNAME1 not resolved.
9      put str= ;
10
11     colname1 = symget('colname1');
12     put colname1= ;
13   run;

str=The value of colname1 is: &amp;amp;colname1
colname1=Make
str=The value of colname1 is: &amp;amp;colname1
colname1=Model
str=The value of colname1 is: &amp;amp;colname1
colname1=Type
NOTE: There were 3 observations read from the data set SASHELP.VCOLUMN.
      WHERE (libname='SASHELP') and (memname='CARS');
NOTE: The data set WORK.TESTING has 3 observations and 20 variables.
&lt;/PRE&gt;
&lt;P&gt;Now run the same code a second time, and the results are different:&lt;/P&gt;
&lt;PRE&gt;14   data testing;
15
16     set sashelp.vcolumn(obs = 3);
17     where libname = 'SASHELP' and memname = 'CARS';
18
19     call symput('colname1', name);
20
21     str="The value of colname1 is: &amp;amp;colname1" ;
22     put str= ;
23
24     colname1 = symget('colname1');
25     put colname1= ;
26   run;

str=The value of colname1 is: Type
colname1=Make
str=The value of colname1 is: Type
colname1=Model
str=The value of colname1 is: Type
colname1=Type
NOTE: There were 3 observations read from the data set SASHELP.VCOLUMN.
      WHERE (libname='SASHELP') and (memname='CARS');
NOTE: The data set WORK.TESTING has 3 observations and 20 variables.
&lt;/PRE&gt;
&lt;P&gt;In the first submission, you created a global macro variable colname1 and ultimately assigned it the value Type.&amp;nbsp; During the second submission, when the step compiles, it can resolve the reference to &amp;amp;colname1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It's the same issue with your original code.&amp;nbsp; The first time the reference cannot resolve, after that, it does resolve (to a "legacy" value which happened to be sitting in the global symbol table).&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If your first submission gave you the desired result (despite the resolution warnings), it's likely a side effect of the fact that even though the reference to &amp;amp;colname1 could not be resolved during data step compilation, when the code is executed in the DOSUBL environment it will be able to resolve.&amp;nbsp; Because by the time the DOSUBL() function executes, the CALL SYMPUT has already executed.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And just to add, your instinct to focus on timing is absolutely correct.&amp;nbsp; Thinking through the timing of DATA step compilation vs execution is critical to understanding SAS.&amp;nbsp; And the timing issues only become more complex (and more critical) when you introduce automated code generation, whether it's done via the macro language, DOSUBL, CALL EXECUTE, or even PUT statements and %INCLUDEs.&lt;/P&gt;</description>
      <pubDate>Tue, 01 Sep 2020 13:52:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/dosubl-order-of-execution/m-p/680697#M205771</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2020-09-01T13:52:57Z</dc:date>
    </item>
  </channel>
</rss>

