<?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 Receiving a macro result as return value, instead of into a global variable in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898978#M355326</link>
    <description>&lt;P&gt;&amp;nbsp; &amp;nbsp; Hi _ALL_,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'm facing a strange problem, while I'm trying to understand if a "day" (numeric) is a working day, an (italian) holiday or a weekend.&lt;/P&gt;
&lt;P&gt;The weekend part is working as expected:&lt;/P&gt;
&lt;PRE&gt;%macro isWeekEnd(dateToCheck);
	%let isWeekEnd = %sysfunc(weekday(&amp;amp;dateToCheck));
	%if &amp;amp;isWeekEnd eq 1 or &amp;amp;isWeekEnd eq 7 %then %do;
		%let isWeekEnd=1;
	%end;
	%else %do;
		%let isWeekEnd=0;
	%end;
	&amp;amp;isWeekEnd
%mend isWeekEnd;
&lt;/PRE&gt;
&lt;P&gt;so that I can write&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%if %isWeekEnd(&amp;amp;moggin.) %then %do;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;having &amp;amp;moggin =&amp;nbsp;23300 (which is Tuesday 17 Oct 2023) gives back 0 etc.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tried the same with an isHolidayIt() macro then:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro isHolidayIt(dateToCheck);
    %local LCisHolidayIt;
    %let LCisHolidayIt=0;;
    proc sql noprint;
        select count(*)
        into :LCisHolidayIt
        from Festiv_ITA
        where datan = &amp;amp;dateToCheck;
    quit;
	&amp;amp;LCisHolidayIt
%mend isHolidayIt;

%let festa=%isHolidayIt(23315); /* 1 Nov 2023: holiday */
%put &amp;amp;=festa;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;after preparing a Festiv_ITA table with italian holidays for the year (4 variables, 13 rows, with first variable is datan: numeric holiday): if the dateToCheck is holiday it finds 1 record, and finds 0 of them if not, so we have the 0/1 situation again.&lt;/P&gt;
&lt;P&gt;All good but I'm not getting back the return value in any way, here's the log:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;26         /* DEBUG: _VERBOSE_ */
27         OPTIONS mprint mprintnest mlogic mlogicnest symbolgen syntaxcheck autocorrect fullstimer source stimer threads;
28         
29         %macro isHolidayIt(dateToCheck);
30             %local LCisHolidayIt;
31             %let LCisHolidayIt=0;;
32             proc sql noprint;
33                 select count(*)
34                 into :LCisHolidayIt
35                 from Festiv_ITA
36                 where datan = &amp;amp;dateToCheck;
37             quit;
38         	&amp;amp;LCisHolidayIt.
39         %mend isHolidayIt;
40         
41         %let festa=%isHolidayIt(23315);
MLOGIC(ISHOLIDAYIT):  Beginning execution.
MLOGIC(ISHOLIDAYIT):  Parameter DATETOCHECK has value 23315
MLOGIC(ISHOLIDAYIT):  %LOCAL  LCISHOLIDAYIT
MLOGIC(ISHOLIDAYIT):  %LET (variable name is LCISHOLIDAYIT)
MPRINT(ISHOLIDAYIT):   proc sql noprint;
SYMBOLGEN:  Macro variable DATETOCHECK resolves to 23315
MPRINT(ISHOLIDAYIT):   select count(*) into :LCisHolidayIt from Festiv_ITA where datan = 23315;
MPRINT(ISHOLIDAYIT):   quit;
SYMBOLGEN:  Macro variable LCISHOLIDAYIT resolves to        1
41                  1
                    _
                    180
2                                                          The SAS System                            12:57 Tuesday, October 17, 2023

MPRINT(ISHOLIDAYIT):   1
MLOGIC(ISHOLIDAYIT):  Ending execution.
ERROR 180-322: Statement is not valid or it is used out of proper order.

SYMBOLGEN:  Macro variable FESTA resolves to 
42         %put &amp;amp;=festa;
FESTA=
43&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another strange thing (at least to me) is, if I don't put double ";;" before the proc sql, I see in sas log that its code get assigned to the macro variable:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;MLOGIC(ISHOLIDAYIT):  %LOCAL  LCISHOLIDAYIT
MLOGIC(ISHOLIDAYIT):  %LET (variable name is LCISHOLIDAYIT)
41         proc sql noprint;         select count(*)         into :LCisHolidayIt         from Festiv_ITA         where datan =
                                     ______
                                     180
41       ! &amp;amp;dateToCheck;     quit;  &amp;amp;LCisHolidayIt.
ERROR 180-322: Statement is not valid or it is used out of proper order.&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;;; seems fixing it but the first problem remains: how can I "capture" the return value to assign it externally?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Assigning the value internally, to a global variable, works, but it's not what I would like to achieve: if I do that, all the programs which will use such macro will have to define a global which exact matches the one which macro uses, so the macro won't work as a "black box" (which I prefer).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tried to use the same logic and syntax, into isWeekEnd() and isHolidayIt() and I'm not getting why the second is not working like the first one.&lt;/P&gt;</description>
    <pubDate>Tue, 17 Oct 2023 16:50:17 GMT</pubDate>
    <dc:creator>lc_isp</dc:creator>
    <dc:date>2023-10-17T16:50:17Z</dc:date>
    <item>
      <title>Receiving a macro result as return value, instead of into a global variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898978#M355326</link>
      <description>&lt;P&gt;&amp;nbsp; &amp;nbsp; Hi _ALL_,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'm facing a strange problem, while I'm trying to understand if a "day" (numeric) is a working day, an (italian) holiday or a weekend.&lt;/P&gt;
&lt;P&gt;The weekend part is working as expected:&lt;/P&gt;
&lt;PRE&gt;%macro isWeekEnd(dateToCheck);
	%let isWeekEnd = %sysfunc(weekday(&amp;amp;dateToCheck));
	%if &amp;amp;isWeekEnd eq 1 or &amp;amp;isWeekEnd eq 7 %then %do;
		%let isWeekEnd=1;
	%end;
	%else %do;
		%let isWeekEnd=0;
	%end;
	&amp;amp;isWeekEnd
%mend isWeekEnd;
&lt;/PRE&gt;
&lt;P&gt;so that I can write&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%if %isWeekEnd(&amp;amp;moggin.) %then %do;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;having &amp;amp;moggin =&amp;nbsp;23300 (which is Tuesday 17 Oct 2023) gives back 0 etc.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tried the same with an isHolidayIt() macro then:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro isHolidayIt(dateToCheck);
    %local LCisHolidayIt;
    %let LCisHolidayIt=0;;
    proc sql noprint;
        select count(*)
        into :LCisHolidayIt
        from Festiv_ITA
        where datan = &amp;amp;dateToCheck;
    quit;
	&amp;amp;LCisHolidayIt
%mend isHolidayIt;

%let festa=%isHolidayIt(23315); /* 1 Nov 2023: holiday */
%put &amp;amp;=festa;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;after preparing a Festiv_ITA table with italian holidays for the year (4 variables, 13 rows, with first variable is datan: numeric holiday): if the dateToCheck is holiday it finds 1 record, and finds 0 of them if not, so we have the 0/1 situation again.&lt;/P&gt;
&lt;P&gt;All good but I'm not getting back the return value in any way, here's the log:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;26         /* DEBUG: _VERBOSE_ */
27         OPTIONS mprint mprintnest mlogic mlogicnest symbolgen syntaxcheck autocorrect fullstimer source stimer threads;
28         
29         %macro isHolidayIt(dateToCheck);
30             %local LCisHolidayIt;
31             %let LCisHolidayIt=0;;
32             proc sql noprint;
33                 select count(*)
34                 into :LCisHolidayIt
35                 from Festiv_ITA
36                 where datan = &amp;amp;dateToCheck;
37             quit;
38         	&amp;amp;LCisHolidayIt.
39         %mend isHolidayIt;
40         
41         %let festa=%isHolidayIt(23315);
MLOGIC(ISHOLIDAYIT):  Beginning execution.
MLOGIC(ISHOLIDAYIT):  Parameter DATETOCHECK has value 23315
MLOGIC(ISHOLIDAYIT):  %LOCAL  LCISHOLIDAYIT
MLOGIC(ISHOLIDAYIT):  %LET (variable name is LCISHOLIDAYIT)
MPRINT(ISHOLIDAYIT):   proc sql noprint;
SYMBOLGEN:  Macro variable DATETOCHECK resolves to 23315
MPRINT(ISHOLIDAYIT):   select count(*) into :LCisHolidayIt from Festiv_ITA where datan = 23315;
MPRINT(ISHOLIDAYIT):   quit;
SYMBOLGEN:  Macro variable LCISHOLIDAYIT resolves to        1
41                  1
                    _
                    180
2                                                          The SAS System                            12:57 Tuesday, October 17, 2023

MPRINT(ISHOLIDAYIT):   1
MLOGIC(ISHOLIDAYIT):  Ending execution.
ERROR 180-322: Statement is not valid or it is used out of proper order.

SYMBOLGEN:  Macro variable FESTA resolves to 
42         %put &amp;amp;=festa;
FESTA=
43&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another strange thing (at least to me) is, if I don't put double ";;" before the proc sql, I see in sas log that its code get assigned to the macro variable:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;MLOGIC(ISHOLIDAYIT):  %LOCAL  LCISHOLIDAYIT
MLOGIC(ISHOLIDAYIT):  %LET (variable name is LCISHOLIDAYIT)
41         proc sql noprint;         select count(*)         into :LCisHolidayIt         from Festiv_ITA         where datan =
                                     ______
                                     180
41       ! &amp;amp;dateToCheck;     quit;  &amp;amp;LCisHolidayIt.
ERROR 180-322: Statement is not valid or it is used out of proper order.&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;;; seems fixing it but the first problem remains: how can I "capture" the return value to assign it externally?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Assigning the value internally, to a global variable, works, but it's not what I would like to achieve: if I do that, all the programs which will use such macro will have to define a global which exact matches the one which macro uses, so the macro won't work as a "black box" (which I prefer).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I tried to use the same logic and syntax, into isWeekEnd() and isHolidayIt() and I'm not getting why the second is not working like the first one.&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 16:50:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898978#M355326</guid>
      <dc:creator>lc_isp</dc:creator>
      <dc:date>2023-10-17T16:50:17Z</dc:date>
    </item>
    <item>
      <title>Re: Receiving a macro result as return value, instead of into a global variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898979#M355327</link>
      <description>I think macros is the wrong tool for this job.&lt;BR /&gt;&lt;BR /&gt;You seem to want to implement a custom calendar instead or possibly PROC FCMP which is a function or even a format instead.</description>
      <pubDate>Tue, 17 Oct 2023 16:59:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898979#M355327</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2023-10-17T16:59:09Z</dc:date>
    </item>
    <item>
      <title>Re: Receiving a macro result as return value, instead of into a global variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898982#M355329</link>
      <description>&lt;P&gt;When you put code other than just macro statements, such as your Proc SQL then the usage as a macro "function" is going to break.&lt;/P&gt;
&lt;P&gt;Suggestion: Look at the documentation for the Holidayname function.&lt;/P&gt;
&lt;P&gt;You can create a data set using the DATEKEYS procedure to provide your additional holidays and then reference that data set with the SAS option EVENTDS= to make a custom list of holidays available to the SAS holiday related functions.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Holidayname, when used correctly will return the name of the holiday or a blank. The Index parameter comes into play when you want a specific version of the holiday. The example in the online help for Holidayname shows use of a holiday that in the US may have multiple observations on the same day (or not if&amp;nbsp; occurring on Saturday or Sunday).&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 17:10:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898982#M355329</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2023-10-17T17:10:03Z</dc:date>
    </item>
    <item>
      <title>Re: Receiving a macro result as return value, instead of into a global variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898985#M355330</link>
      <description>&lt;P&gt;Agree with others, you are better off using the HOLIDAYNAME function.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As a learning exercise, what you are trying to do is create a 'function-style macro'.&amp;nbsp; The challenge is that a function-style macro can only contain macro language statements, not SAS SAS statements.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you had asked this question 11 years ago, the answer would have been "You can't use a PROC step inside a function-style macro."&amp;nbsp; But 10 years ago Rick Langston decided to add a function, DOSUBL, to SAS, which actually makes this possible.&amp;nbsp; See:&amp;nbsp;&lt;A href="https://support.sas.com/resources/papers/proceedings13/032-2013.pdf" target="_blank"&gt;https://support.sas.com/resources/papers/proceedings13/032-2013.pdf&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Basically, you use %SYSFUNC to invoke the DOSUBL function, so the macro definition is still pure macro code.&amp;nbsp; Then DOSUBL creates a magical 'side-session' which can execute the PROC SQL step.&amp;nbsp; e.g.:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro isHolidayIt(dateToCheck);
    %local rc LCisHolidayIt;
    %let LCisHolidayIt=0;
    %let rc=%sysfunc(dosubl(%nrstr(
      proc sql noprint;
          select count(*)
          into :LCisHolidayIt
          from Festiv_ITA
          where datan = &amp;amp;dateToCheck;
      quit;
    ))) ;
	&amp;amp;LCisHolidayIt.
%mend isHolidayIt;

data Festiv_ITA ;
  input datan ;
  cards ;
23315
;
run ;

%let festa=%isHolidayIt(23315);
%put &amp;amp;=festa ;

%let festa=%isHolidayIt(23314);
%put &amp;amp;=festa ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Again, not suggesting you use this approach for this problem.&amp;nbsp; But as you are developing macros, it's helpful to know that DOSUBL provides you with this ability to write function-style macro that executes SAS code.&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 17:38:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898985#M355330</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2023-10-17T17:38:42Z</dc:date>
    </item>
    <item>
      <title>Re: Receiving a macro result as return value, instead of into a global variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898997#M355341</link>
      <description>&lt;P&gt;Thank you very much, all, for the quick answers and solutions (I was struggling on that since two days): all answers have been &lt;STRONG&gt;very&lt;/STRONG&gt; useful (as always) and yes, I previously saw the &lt;STRONG&gt;EVENTDS&lt;/STRONG&gt; thing but, to be honest, I didn't know &lt;EM&gt;how to manage it&lt;/EM&gt; and figured out how to write a small "&lt;EM&gt;perpetual calendar&lt;/EM&gt;" (which gives previous, current, and next year's holidays: 39 obs at all) taking a millisec to update every time I launch my EG project, (while I'm not sure I can "write our local holidays somewhere" into a dataset read via EVENTDS: I probably have to ask This and That department... I'm not sure: it's not &lt;STRONG&gt;that&lt;/STRONG&gt; clear, here, who manages what).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So, at last, and despite Quentin's comment ("&lt;SPAN&gt;&lt;EM&gt;not suggesting you use this approach for this problem&lt;/EM&gt;"), his suggestion seems saving my day: I tried it on my Festiv_ITA full calendar and it works as expected there too.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I'm going to apply the same logic to a &lt;STRONG&gt;&lt;EM&gt;PrevLabDay()&lt;/EM&gt;&lt;/STRONG&gt; macro too, which is giving the same problem since I enabled it to work with &lt;EM&gt;isHolidayIt()&lt;/EM&gt;: while it was working with &lt;EM&gt;isWeekEnd()&lt;/EM&gt; only it worked like a charm (and now you explained the reason behind).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;I was nearly modifying my code, to make it use of &lt;STRONG&gt;&amp;amp;rc&lt;/STRONG&gt; &lt;EM&gt;global var&lt;/EM&gt; instead (so that my colleagues, which are working at the data side, can go forth), but I'll implement the DOSUBL suggestion, now, and will give a look into EVENTDS things, later, as it's probably a better/more robust way: even now I'm basing on &lt;STRONG&gt;holiday('EASTER')&lt;/STRONG&gt;, which is luckily in common with non-ita-custom holidays&amp;nbsp;(GREAT luck, as it's a &lt;EM&gt;variable&lt;/EM&gt; holiday date, "base" for two other holidays here: all others are &lt;EM&gt;fixed&lt;/EM&gt; ones and can be summarized with 10 datalines).&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 17 Oct 2023 18:25:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Receiving-a-macro-result-as-return-value-instead-of-into-a/m-p/898997#M355341</guid>
      <dc:creator>lc_isp</dc:creator>
      <dc:date>2023-10-17T18:25:04Z</dc:date>
    </item>
  </channel>
</rss>

