admin 发表于 2022-2-12 18:06:13

关于sas:使用调用执行时的宏变量问题

<h2>Macro variables issue when using call execute</h2>
<div id="fc">
<p></p><center> <script src="/c1.js"></script></center><p></p>
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
<p>macro %TWO 需要全局变量</p>
<hr>
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br></div></td><td><div class="sas codecolorer">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>
&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
<br>
&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
<br>
&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
<br>
&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span> <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>
&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
<br>
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>
&nbsp; &nbsp;%one<span class="br0">(</span>condition=<span class="nu0">1</span><span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
&nbsp; &nbsp;%one<span class="br0">(</span>condition=<span class="nu0">2</span><span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
&nbsp; &nbsp;%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
&nbsp; &nbsp;names_agg=a_agg c_agg<br>
&nbsp; &nbsp;names_agg=<br>
&nbsp; &nbsp;names_agg=b_agg<br>
&nbsp; &nbsp;--*;</span><br>
<br>
&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
&nbsp; &nbsp; &nbsp;<span class="kw2">%if</span> <span class="re0">&amp;names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
<br>
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
<br>
&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>
&nbsp; &nbsp;<span class="kw4">title</span> ot1; proc print <span class="kw6">data</span>=ot1; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
&nbsp; &nbsp;ot1<br>
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>
&nbsp; &nbsp;*/</span><br>
&nbsp; &nbsp;<span class="kw4">title</span> ot2; proc print <span class="kw6">data</span>=ot2; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>
&nbsp; &nbsp;<span class="coMULTI">/* on log<br>
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
&nbsp; &nbsp;*/</span><br>
&nbsp; &nbsp;<span class="kw4">title</span> ot_; proc print <span class="kw6">data</span>=ot_; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
&nbsp; &nbsp;ot_<br>
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>
&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>
<hr>
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
&nbsp; <span class="kw3">length</span> code $32767;<br>
&nbsp; <span class="kw4">set</span> meta_table;<br>
&nbsp; code = <span class="st0">'%ONE('</span> || cats<span class="br0">(</span>condition<span class="br0">)</span> || <span class="st0">'); %TWO('</span> || cats<span class="br0">(</span>Name_OT<span class="br0">)</span> ||<span class="st0">");"</span>;<br>
&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
<hr>
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br></div></td><td><div class="sas codecolorer"><span class="kw2">%macro</span> TheOnlyOne<span class="br0">(</span>condition,name_OT<span class="br0">)</span>;<br>
&nbsp; <span class="re1">proc sql</span> noprint;<br>
&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>
&nbsp; <span class="kw6">quit</span>;<br>
&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>
&nbsp; <span class="kw6">run</span>;<br>
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
<p></p><center> <script src="/c2.js"></script></center><p></p>
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
<ul>
<li>
在调用执行方法之外按顺序运行宏?
</li>
<li>
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
</li>
<li>
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
</li>
</ul>
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
<div class="suo-content"><div style="text-align: right;">
                <div class="xControl"><i class="fa fa-caret-right"></i>
                        <span class="xTitle"></span>
                        相关讨论
                        <div style="clear: both;"></div>
                </div>
                <div class="xContent" style="display: none;"><p></p>
<ul>
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
</ul>
<p></p></div>
      </div><p></p></div>
<hr></div>
页: [1]
查看完整版本: 关于sas:使用调用执行时的宏变量问题