<?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: Macro help: Reuse lines in multiple programs in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633043#M187767</link>
    <description>&lt;P&gt;Yes, you can put code into a macro variable.&amp;nbsp; Just make sure you understand how to get it in and how to evaluate it in a way that it generates the code you want.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One obvious problem is trying to get the semi-colons into the macro variable.&amp;nbsp; Adding the quotes like you did will allow that. But then you have to remember to remove them so they don't become part of the program you are tying to generate.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%sysfunc(dequote(&amp;amp;programlines))&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another issue the timing of when you are changing the value of the EVENT_DATE macro variable.&amp;nbsp; If you use the %LET statement you posted:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let programlines = 
"Length owner $100; 
if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D)
 or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D)
 or (ID='789')) then owner = 'JOHN';
"; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then &amp;amp;EVENT_DATE will be evaluated when the macro variable is created and your later attempt to change its value will not have any impact.&amp;nbsp; You could use single quotes on the outside instead to prevent the macro processor from trying to process the text.&amp;nbsp; Make sure to also either change the single quotes on the inside to double quotes, or just double them up.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let programlines = 
'Length owner $100; 
if ((ID="123" and &amp;amp;EVENT_DATE &amp;gt; "01APR2011"D)
 or (ID="456" and &amp;amp;EVENT_DATE &amp;gt; "05JUN2015"D)
 or (ID="789")) then owner = "JOHN";
'; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then when SAS sees the unquoted value of the macro the macro processor will see the &amp;amp; and evaluate it to the current value of EVENT_DATE.&lt;/P&gt;</description>
    <pubDate>Wed, 18 Mar 2020 18:14:08 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2020-03-18T18:14:08Z</dc:date>
    <item>
      <title>Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631960#M187294</link>
      <description>&lt;P&gt;Hi, we'd like to store frequently used lines of programs in macro. For example:&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro ownerrange;&amp;nbsp;
Length owner $100.;
if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D) or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D) or (ID='789')) 
then owner = 'JOHN'; 

%mend; 


data orders; 
length ID $3 cost 8. date1 8. date2 8.; 
input ID cost date1 date2; 
informat date1 mmddyy10. date2 mmddyy10.;
format date1 mmddyy10. date2 mmddyy10.; 
datalines; 
123 50 01/01/2020 02/01/2019
123 60 01/01/2011 03/05/2020
456 10 04/01/2019 01/03/2020
; 
run; 

%let EVENT_DATE=date1; 

data owner; 
set orders; 

%ownerrange

run; 

&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;For some reason my %ownerrange won't work. It gives me:&amp;nbsp;&lt;/P&gt;&lt;P&gt;ERROR 180-322: Statement is not valid or it is used out of proper order.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;But if I directly replace it with the code written in the macro, it works no problem. Anything I missed?&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;After that, we'd like to extract the dates and ownership info and store it in dataset. The thing I can think of is do something like this below and use &amp;amp;runlist in program. but it won't work. Any suggestion is welcomed! Hope I described my question clear enough. Thank you!!&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
  select case when ID^='' and date1 ^=. and date2=. then 
cats('IF ID=',id,' AND &amp;amp;EVENT_DATE &amp;gt;= ',date1,')') 
         ... end
     into :runlist
     from dataset_withdatesowner
	 ; 
quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 13 Mar 2020 16:29:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631960#M187294</guid>
      <dc:creator>coladuck</dc:creator>
      <dc:date>2020-03-13T16:29:16Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631966#M187297</link>
      <description>Post your log using the debugging options:&lt;BR /&gt;&lt;BR /&gt;options mprint symbolgen;&lt;BR /&gt;&lt;BR /&gt;Run your code and get the log and see if you can find the issue. If you cannot, post the log.</description>
      <pubDate>Fri, 13 Mar 2020 16:38:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631966#M187297</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2020-03-13T16:38:44Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631970#M187301</link>
      <description>&lt;P&gt;Copy the log including the definition of the macro, the data steps and the code that calls the macro. Copy all that from the log. Then open a code box on the forum and paste the result.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I can't duplicate your error with your code:&lt;/P&gt;
&lt;PRE&gt;365  %macro ownerrange;
366  Length owner $100.;
367  if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D) or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D) or
367!  (ID='789'))
368  then owner = 'JOHN';
369
370  %mend;
NOTE: The macro OWNERRANGE completed compilation without errors.
      6 instructions 212 bytes.
371
372
373  data work.orders;
374  length ID $3 cost 8. date1 8. date2 8.;
375  input ID cost date1 date2;
376  informat date1 mmddyy10. date2 mmddyy10.;
377  format date1 mmddyy10. date2 mmddyy10.;
378  datalines;

NOTE: The data set WORK.ORDERS has 3 observations and 4 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


382  ;
383  run;
384
385  %let EVENT_DATE=date1;
386
387  data work.owner;
388  set work.orders;
389
390  %ownerrange
391
392  run;

NOTE: There were 3 observations read from the data set WORK.ORDERS.
NOTE: The data set WORK.OWNER has 3 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
&lt;/PRE&gt;
&lt;P&gt;In general when using a macro and generating errors on of the firs things to do is to clear the log, set OPTIONS MPRINT;&amp;nbsp; and rerun the code to see what the macro generated.&lt;/P&gt;</description>
      <pubDate>Fri, 13 Mar 2020 16:44:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/631970#M187301</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2020-03-13T16:44:35Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633024#M187754</link>
      <description>&lt;P&gt;You're right. It does not give me error this time when I restarted my EG. Very strange...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Another question, is it possible that I put everything I wrote in the macro into a macro variable using&lt;/P&gt;&lt;P&gt;%let = "", and just refer to the macro variable in the program?&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let programlines = "Length owner $100.;
if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D) or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D) or (ID='789')) 
then owner = 'JOHN';"; 

data orders; 
length ID $3 cost 8. date1 8. date2 8.; 
input ID cost date1 date2; 
informat date1 mmddyy10. date2 mmddyy10.;
format date1 mmddyy10. date2 mmddyy10.; 
datalines; 
123 50 01/01/2020 02/01/2019
123 60 01/01/2011 03/05/2020
456 10 04/01/2019 01/03/2020
; 
run; 

%let EVENT_DATE=date1; 

data owner; 
set orders; 

&amp;amp;programlines; 

run; &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;and of course, it does not work. It there a way to just use macro variables?&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I ask because in the end, all the dates and owner information will be stored in a dataset and I'd like to use something like this below to generate lines automatically:&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;Proc sql; 
select cat('if ID=', ID, 'and &amp;amp;eventdate&amp;gt;', datevariable, 'then owner="', ownervariable,'"; output;') 
into: programlines
from datacontainvalues
; 
quit; &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Thank you!!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2020 17:10:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633024#M187754</guid>
      <dc:creator>coladuck</dc:creator>
      <dc:date>2020-03-18T17:10:58Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633035#M187760</link>
      <description>&lt;P&gt;This line is not valid outside data step&lt;/P&gt;&lt;PRE class="language-sas"&gt;&lt;CODE&gt;%let EVENT_DATE=date1; &lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2020 17:46:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633035#M187760</guid>
      <dc:creator>ghosh</dc:creator>
      <dc:date>2020-03-18T17:46:40Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633041#M187765</link>
      <description>&lt;P&gt;You are using the macro variable incorrectly.&amp;nbsp; In fact you do't need it&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro ownerrange;
	Length owner $100.;
	if ((ID='123' and date1 &amp;gt; '01APR2011'D) or (ID='456' and date1 &amp;gt; '05JUN2015'D) 
		or (ID='789')) then owner='JOHN';
%mend;

data orders;
	length ID $3 cost 8. date1 8. date2 8.;
	input ID cost date1 date2;
	informat date1 mmddyy10. date2 mmddyy10.;
	format date1 mmddyy10. date2 mmddyy10.;
	datalines;
123 50 01/01/2020 02/01/2019
123 60 01/01/2011 03/05/2020
456 10 04/01/2019 01/03/2020
;
run;

data owner;
	set orders;
	%ownerrange ;
	run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2020 18:01:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633041#M187765</guid>
      <dc:creator>ghosh</dc:creator>
      <dc:date>2020-03-18T18:01:16Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633043#M187767</link>
      <description>&lt;P&gt;Yes, you can put code into a macro variable.&amp;nbsp; Just make sure you understand how to get it in and how to evaluate it in a way that it generates the code you want.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One obvious problem is trying to get the semi-colons into the macro variable.&amp;nbsp; Adding the quotes like you did will allow that. But then you have to remember to remove them so they don't become part of the program you are tying to generate.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%sysfunc(dequote(&amp;amp;programlines))&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another issue the timing of when you are changing the value of the EVENT_DATE macro variable.&amp;nbsp; If you use the %LET statement you posted:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let programlines = 
"Length owner $100; 
if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D)
 or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D)
 or (ID='789')) then owner = 'JOHN';
"; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then &amp;amp;EVENT_DATE will be evaluated when the macro variable is created and your later attempt to change its value will not have any impact.&amp;nbsp; You could use single quotes on the outside instead to prevent the macro processor from trying to process the text.&amp;nbsp; Make sure to also either change the single quotes on the inside to double quotes, or just double them up.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let programlines = 
'Length owner $100; 
if ((ID="123" and &amp;amp;EVENT_DATE &amp;gt; "01APR2011"D)
 or (ID="456" and &amp;amp;EVENT_DATE &amp;gt; "05JUN2015"D)
 or (ID="789")) then owner = "JOHN";
'; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then when SAS sees the unquoted value of the macro the macro processor will see the &amp;amp; and evaluate it to the current value of EVENT_DATE.&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2020 18:14:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633043#M187767</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2020-03-18T18:14:08Z</dc:date>
    </item>
    <item>
      <title>Re: Macro help: Reuse lines in multiple programs</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633114#M187794</link>
      <description>&lt;P&gt;Your example looks find. Please post the SAS log from the run that generated errors.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note that it is not a good idea to create a macro that references "magic" macro variables. Macro variables that are NOT defined as input parameters nor explicitly declared as LOCAL or GLOBAL. Like the EVENT_DATE reference in your macro definition.&amp;nbsp; If you need that parameter then It would be much better to define that as a parameter to the macro.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro ownerrange(event_date); 
length owner $100;
if ((ID='123' and &amp;amp;EVENT_DATE &amp;gt; '01APR2011'D)
 or (ID='456' and &amp;amp;EVENT_DATE &amp;gt; '05JUN2015'D)
 or (ID='789')) then owner = 'JOHN'
; 
%mend;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then supply the actual variable name when you call the macro.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data owner; 
  set orders; 
  %ownerrange(date1)
run; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You might have trouble with the LENGTH statement if OWNER already exists in the incoming dataset.&amp;nbsp; You cannot change the length of character variable after it has already been defined.&amp;nbsp; PS There is no need to include a decimal point in the numbers used in a length statement, they can only be integer values.&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2020 23:24:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Macro-help-Reuse-lines-in-multiple-programs/m-p/633114#M187794</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2020-03-18T23:24:04Z</dc:date>
    </item>
  </channel>
</rss>

