<?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: Check Macro parameters in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201367#M37633</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;You cannot query anything at runtime to find the list of parameters defined for the macro you are currently running.&lt;/P&gt;&lt;P&gt;I would suggest one of two approaches.&lt;/P&gt;&lt;P&gt;1) Have a general utility for checking parameters and enforce coding standards that macros call this utility.&amp;nbsp; If you modify the macro to have more parameters you modify the code of the macro to test them.&lt;/P&gt;&lt;P&gt;&amp;nbsp; %macro mymac(parm1,parm2);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checkparm(parm1,....)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checparm(parm2,.....)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %mend mymac;&lt;/P&gt;&lt;P&gt;2) Maintain a database of parameter checks using the macro name as a key.&amp;nbsp; Again you will need to enforce by your coding standards that the data in the database matches the macro definition.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %macro mymac(parm1,parm2);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %let _macro = &amp;amp;sysmacroname ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checkparms(&amp;amp;_macro);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %mend ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; data parameters ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; length macroname $32 parameter $32 test $2000 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; infile cards dsd truncover ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; input macroname parameter test ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; cards;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; mymac parm1 REQUIRED&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; mymac parm2 OPTIONAL&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; ;;;;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Wed, 22 Apr 2015 16:55:53 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2015-04-22T16:55:53Z</dc:date>
    <item>
      <title>Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201363#M37629</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I am trying to create a utility macro (check_params as shown below) which is when invoked from a macro - it should check all the parameters defined in that macro's definition.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro abc(aa=, bb=, cc=);&lt;/P&gt;&lt;P&gt;/* Utility macro invoked here */&lt;BR /&gt;&amp;nbsp;&amp;nbsp; %check_params;&lt;/P&gt;&lt;P&gt;/* Actual code starts from here */&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%mend abc;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%abc(aa=mm,bb=nn);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;When I explore, I see PARMBUFF option with SYSPBUFF system automatic macro variable as a way out. But, this will only give me the parameters which are passed during macro invocation. E.g. In the above call SYSPBUFF = (aa=mm,bb=nn). This is not the full list of parameters defined in the macro definition, I would need all params i.e. (aa=mm, bb=nn, cc=) &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Is there any way I get this (aa=mm, bb=nn, cc=)into a macro variable then I can play around and have checks?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks in advance,&lt;/P&gt;&lt;P&gt;Satya &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 05:34:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201363#M37629</guid>
      <dc:creator>SatyaG</dc:creator>
      <dc:date>2015-04-22T05:34:01Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201364#M37630</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I understand you're playing around a little, but I am not sure, if this would be a proper approach. If your macro list is a tupel, this is, if you always have aa, bb, and cc combined, you could simply check, for example, if cc has a value at all with "%If (&amp;amp;cc^=) %Then ..", etc.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro abc(aa=, bb=, cc=);&lt;/P&gt;&lt;P&gt;%If (&amp;amp;aa.^=) &amp;amp; (&amp;amp;bb.^=) &amp;amp; (&amp;amp;cc.^=) %Then %Do;&lt;/P&gt;&lt;P&gt;&amp;nbsp; *execute something;&lt;/P&gt;&lt;P&gt;%End;&lt;/P&gt;&lt;P&gt;%Else %Do;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %Put **something is missing**;&lt;/P&gt;&lt;P&gt;%End; &lt;/P&gt;&lt;P&gt;%mend abc;&lt;/P&gt;&lt;P&gt;%abc(aa=mm,bb=nn)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;However, if your macro parameter list is dynamic, you might want to do the checking before you split your list up into individual elements.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 08:23:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201364#M37630</guid>
      <dc:creator>user24feb</dc:creator>
      <dc:date>2015-04-22T08:23:51Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201365#M37631</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;You could.&amp;nbsp; There are plently of posts on parameter lists.&amp;nbsp; In most of them you will find me advising against it.&amp;nbsp; The code gets large and unreadble very quickly having to maks/unmask, reference other references etc.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;IMO if you are writing macros/system for other people you will first want to read up on Software Development Life Cycle.&amp;nbsp; Sit down and plan what it is you want to achieve, how things fit together, what the standards will be, how things will be tested.&amp;nbsp; Once you have all the documentation - Functional Design Specifications, Testing Document etc. then start looking at coding.&amp;nbsp; In the companies I have worked for the first thing I notice when I get there is at least one folder full up with undocumented, untested, vague bits of code put into macros over 10 years or more.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In response to your point, there are various methods, yes parambuff is one of them.&amp;nbsp; However me personally, I would put paramters into a dataset.&amp;nbsp; The reason is that datasets are very easy to work with, do checking on etc. Its also easy to pass parameter tables through:&lt;/P&gt;&lt;P&gt;%macro Do_Something (Parameter_Table=work.abc);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %Check_Parameter_Table (Parameter_Table=&amp;amp;Parameter_Table.);&lt;/P&gt;&lt;P&gt;...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;You can set up your dataset any way you like with as much information as you need, and example:&lt;/P&gt;&lt;P&gt;PARAMETER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VALUE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CHECK&lt;/P&gt;&lt;P&gt;FILE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\temp\temp.xlsx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXISTENCE&lt;/P&gt;&lt;P&gt;OUT_LOCATION&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:\temp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXISTENCE&lt;/P&gt;&lt;P&gt;...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Then your check is simply:&lt;/P&gt;&lt;P&gt;data _null_;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set parameter_table;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call execute('%'||strip(check)||'("'||strip(value)||'");');&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;And this will generate the following two macro calls:&lt;/P&gt;&lt;P&gt;%EXISTENCE("c:\temp\temp.xlsx");&lt;/P&gt;&lt;P&gt;%EXISTENCE("c:\temp");&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;That said, that is just an example and heavily depends on what you want to do and where.&amp;nbsp; For simple macros, its quite simple to have your checks up front and then then jump to the end if fails:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro Test (file=);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %if %sysfunc(fileexist(&amp;amp;file.))=0 %then %do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put Macro Test failed to find &amp;amp;file. and has stopped operation;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %goto exit;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Process file */&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put Macro Test passed execution;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%exit:&lt;/P&gt;&lt;P&gt;%mend Test;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 08:31:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201365#M37631</guid>
      <dc:creator>RW9</dc:creator>
      <dc:date>2015-04-22T08:31:57Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201366#M37632</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;This looks like a repeat of your earlier post:&lt;/P&gt;&lt;P&gt;&lt;A _jive_internal="true" href="https://communities.sas.com/thread/75519"&gt;https://communities.sas.com/thread/75519&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I posted one approach there.&amp;nbsp; I think what you're looking for is reasonable.&amp;nbsp; In my check macro I usually pass the list of required parameters explicitly, because I sometimes have optional parameters with default null value.&amp;nbsp; So my macros end up looking like:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro abc(p1=, p2=, p3=);&lt;/P&gt;&lt;P&gt;&amp;nbsp; %if %MissingRequiredParameter(p1 p2) %then %goto mexit;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %mexit:&lt;/P&gt;&lt;P&gt;%mend abc;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;And %MissingRequiredParameter is the helper macro that checks them all for null, and %PUTs and ERROR: message to the log etc.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 15:58:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201366#M37632</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2015-04-22T15:58:17Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201367#M37633</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;You cannot query anything at runtime to find the list of parameters defined for the macro you are currently running.&lt;/P&gt;&lt;P&gt;I would suggest one of two approaches.&lt;/P&gt;&lt;P&gt;1) Have a general utility for checking parameters and enforce coding standards that macros call this utility.&amp;nbsp; If you modify the macro to have more parameters you modify the code of the macro to test them.&lt;/P&gt;&lt;P&gt;&amp;nbsp; %macro mymac(parm1,parm2);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checkparm(parm1,....)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checparm(parm2,.....)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %mend mymac;&lt;/P&gt;&lt;P&gt;2) Maintain a database of parameter checks using the macro name as a key.&amp;nbsp; Again you will need to enforce by your coding standards that the data in the database matches the macro definition.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %macro mymac(parm1,parm2);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %let _macro = &amp;amp;sysmacroname ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %checkparms(&amp;amp;_macro);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; %mend ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; data parameters ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; length macroname $32 parameter $32 test $2000 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; infile cards dsd truncover ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; input macroname parameter test ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; cards;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; mymac parm1 REQUIRED&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; mymac parm2 OPTIONAL&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; ;;;;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 16:55:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201367#M37633</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2015-04-22T16:55:53Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201368#M37634</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;&lt;A __default_attr="2431" __jive_macro_name="user" class="jive_macro jive_macro_user" data-objecttype="3" href="https://communities.sas.com/"&gt;&lt;/A&gt; did you see my suggestion in the other thread?&amp;nbsp; Would be interested in your thoughts.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;While you can't query at run time to get the parameters in the current macro, you could query to get the list of local macro variables in the current macro.&amp;nbsp; And if you do that early enough (before creating any local macro variables other than the parameters), in effect you get the parameters.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Pasting that response below, since this thread is now more-alive:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;****&lt;/P&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt;&lt;SPAN style="color: #000080; background-color: #ffffff;"&gt;&lt;STRONG&gt;%macro&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; GetOuterScopeVars(debug=&lt;/SPAN&gt;&lt;SPAN style="color: #008080; background-color: #ffffff;"&gt;&lt;STRONG&gt;0&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;)&lt;/SPAN&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%local&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; MyVarList;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&amp;nbsp; proc sql noprint; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; select&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; distinct(name) into :MyVarList separated by &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;" "&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from dictionary.macros &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where scope eq &lt;/SPAN&gt;&lt;SPAN style="color: #800080; background-color: #ffffff;"&gt;"%sysmexecname(%eval(%sysmexecdepth - 1))"&lt;/SPAN&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;BR /&gt;&amp;nbsp; quit;&lt;BR /&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%if&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; &amp;amp;debug=&lt;/SPAN&gt;&lt;SPAN style="color: #008080; background-color: #ffffff;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt; &lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%then&lt;/SPAN&gt; &lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%put&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; Macro vars in &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%str&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;(&lt;/SPAN&gt; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;)&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; %sysmexecname(&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;%eval&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;(%sysmexecdepth - 1)) are: &amp;amp;MyVarList;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000080; background-color: #ffffff;"&gt;&lt;STRONG&gt;%mend&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; GetOuterScopeVars; &lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000080; background-color: #ffffff;"&gt;&lt;STRONG&gt;%macro&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; abc (aa= , bb=, cc=)&lt;/SPAN&gt;; &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&amp;nbsp; %&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;GetOuterScopeVars&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;(debug=&lt;/SPAN&gt;&lt;SPAN style="color: #008080; background-color: #ffffff;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;)&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; %&lt;/SPAN&gt;&lt;SPAN style="color: #008000; background-color: #ffffff;"&gt;*main stuff;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000080; background-color: #ffffff;"&gt;&lt;STRONG&gt;%mend&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt; abc;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt; &lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt; &lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt; &lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt; &lt;/DIV&gt;&lt;DIV style="font-family: Consolas; font-size: 11pt;"&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;%&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; background-color: #ffffff;"&gt;abc&lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;(aa=mm, bb=nn)&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 17:21:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201368#M37634</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2015-04-22T17:21:56Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201369#M37635</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;That helps a little, but to properly check you would still need to have other metadata.&amp;nbsp; Is the parameter required?&amp;nbsp; What are the valid list of values?&lt;/P&gt;&lt;P&gt;Plus many macros will also need to validate options that are passed in via macro variables instead of parameters.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 18:06:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201369#M37635</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2015-04-22T18:06:13Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201370#M37636</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks Tom.&amp;nbsp; Agree, that suggestion only works for the limited use case from the OP (get a list of the parameters), and could check they are non-null.&amp;nbsp; Your suggestions would allow for a more complete parameter validation framework.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 22 Apr 2015 19:01:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201370#M37636</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2015-04-22T19:01:45Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201371#M37637</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Dear All,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thank you very much.. I am overwhelmed with the responses.. this is the first time I posted something on board here.. Great to have such supportive programmers around. Thanks a lot!&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Yes, with %sysmexecname and &lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;%sysmexecdepth we can only get the list of parameters and check for non-null. However, to have further checks like if it is required/ optional and is restricted to values. So, I would have an excel sheet located centrally which has all these details for each of the macros and macro parameters and I use this as a kind of metadata. &lt;/SPAN&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;Thanks a lot.. I appreciate everyones participation in the discussion and look forward to contribute more to the forum. &lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;Nice day all,&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;Satya &lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;P&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 28 Apr 2015 05:01:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201371#M37637</guid>
      <dc:creator>SatyaG</dc:creator>
      <dc:date>2015-04-28T05:01:25Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201372#M37638</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Seriously, for yours and everyones sanity, don't use Excel!&amp;nbsp; Worse case scenario, save as CSV.&amp;nbsp; You can still use Excel as input, but the output is plain text file you can write a datastep read.&amp;nbsp; Even then, get a database, or metadata management software.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 28 Apr 2015 07:56:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201372#M37638</guid>
      <dc:creator>RW9</dc:creator>
      <dc:date>2015-04-28T07:56:35Z</dc:date>
    </item>
    <item>
      <title>Re: Check Macro parameters</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201373#M37639</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I am reminded of the famous quote from an engineer.&lt;/P&gt;&lt;P&gt;"Sure I can idiot-proof this design.&lt;/P&gt;&lt;P&gt;How big of an idiot do you want me to proof it against?"&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My first response is to suggest that all your macro parameters have default values.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%macro Demo(data=sashelp.class,var=age);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The macro runs with no parameters&lt;/P&gt;&lt;P&gt;and the user is already aware of the expected values,&lt;/P&gt;&lt;P&gt;e.g. that data is a two-level name.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My next suggestion is to examine the assumption(s) that an unassigned mvar is indeed worthy of concern.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here is a sas community org wiki page on assertions.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="http://www.sascommunity.org/wiki/Assertions" title="http://www.sascommunity.org/wiki/Assertions"&gt;Assertions - sasCommunity&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This page has a number of reality checks for existence of various objects, data, var, catalog, etc..&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="http://www.sascommunity.org/wiki/Conditionally_Executing_Global_Statements" title="http://www.sascommunity.org/wiki/Conditionally_Executing_Global_Statements"&gt;http://www.sascommunity.org/wiki/Conditionally_Executing_Global_Statements&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My solution is to write my macros to do nothing gracefully.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Ron Fehd&amp;nbsp; testing-aware programs maven&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="http://www.sascommunity.org/wiki/Writing_Testing_Aware_Programs" title="http://www.sascommunity.org/wiki/Writing_Testing_Aware_Programs"&gt;Writing Testing Aware Programs - sasCommunity&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;... and, of course, being an introvert, I thought of a couple more comments to add&#xD;
&#xD;
* Here is a macro with the code for checking existence of various objects.&#xD;
&#xD;
&lt;/SPAN&gt;&lt;A class="jive-link-external-small" href="http://www.sascommunity.org/wiki/Macro_Exist"&gt;http://www.sascommunity.org/wiki/Macro_Exist&lt;/A&gt;&lt;SPAN&gt;&#xD;
&#xD;
&#xD;
* from a design perspective, what you are doing by adding the parm-check macro to any other macro&#xD;
is changing &#xD;
from a subroutine which calls no other macros to complete its task&#xD;
to a routine which raises the level of complexity of your test suites.&#xD;
&#xD;
Message was edited by: Ronald Fehd, Friday morning May 1.&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 01 May 2015 02:12:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Check-Macro-parameters/m-p/201373#M37639</guid>
      <dc:creator>Ron_MacroMaven</dc:creator>
      <dc:date>2015-05-01T02:12:50Z</dc:date>
    </item>
  </channel>
</rss>

