|
|
<h2>Macro variables issue when using call execute</h2>
1 v! V# y$ ? V: K7 _) P<div id="fc">- \4 M7 b+ O3 _
<p></p><center> <script src="/c1.js"></script></center><p></p> F* i& N, t1 @) }* }3 W
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
* M) Q$ _" v" e5 Z$ i3 H' F<p>macro %TWO 需要全局变量</p>
+ E r! `& A/ n O<hr>* _" e. m4 n4 C4 E( d
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>1 n, |" P0 C& Z8 ]5 ?+ s h8 X
<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"> <span class="coMULTI">/* test data */</span><br>
% H% K: C E* U2 _ y, A0 X8 F <span class="kw6">data</span> dataset;<br>8 W' H) D8 N/ m) N
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>$ `* `7 i$ Y& q$ h) g
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br> S5 w! o( k) F/ o$ t
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>; {0 U3 @& Q: Q
<span class="kw6">run</span>;<br>% y8 T0 a& m: ~' ~7 }" b
<br>
9 p8 J# W. R) ^ <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>0 i! r, a* J/ {/ @
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>9 |. Q% |% f+ N
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
6 y+ P# N. G% c9 N# X<br>
* V/ [9 c* F1 Q4 }9 c; P% r <span class="kw6">data</span> meta_table;<br>
( V1 \. G% L3 T4 p$ | condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
3 U+ |* X# I9 B2 a6 [. A, _+ M condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
) }) n8 C8 w2 x9 C4 Y/ I condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>- Q1 K) l4 [* c8 }
<span class="kw6">run</span>;<br>$ T) W+ d# p* b; [. w8 w
<br>
- p' G s; D+ d( ~; U X <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
' h1 Y: D. y5 ?! |* X3 |2 x1 Z <span class="kw2">%global</span> names_agg; <br>+ Z4 W/ C8 f! ?9 V" S3 J
<span class="kw2">%let</span> names_agg = ; <br>
! u, ^, \. | S- p+ C" z* e <span class="re1">proc sql</span> noprint;<br>% ]+ f$ |/ s0 x6 k8 _. {
<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>
7 Q5 e4 X; v' R9 v2 ?6 Y <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
6 x, P" K$ }! k6 W& h! p <span class="kw6">quit</span>;<br>4 W3 b) `; I$ V
<span class="kw2">%mend</span>;<br>0 X, l# K8 {/ p, }" j+ `7 E# t# r T
<br>; E) f2 ~1 g! |( F0 V
%<span class="coMULTI">*-- just checking --*;</span><br>/ r6 V1 }' E1 x$ G4 a9 N- q& w% V
%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">&names_agg</span>;<br>
% U% `! y* R- G* f %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">&names_agg</span>;<br>
) x! l; x% j& y$ l$ d %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
9 {5 e- Z# A) l7 L7 S6 p$ V/ a4 B7 t %<span class="coMULTI">*-- on log<br>4 l6 b }4 r4 h6 f2 n0 P0 {
names_agg=a_agg c_agg<br>. D3 \& N$ l+ J' J' w
names_agg=<br>
4 l4 f) O& T9 h8 H names_agg=b_agg<br>
* x% d; H7 Z3 O9 `0 s8 F. [) S |) L --*;</span><br>
! l& G0 U8 s+ b6 L: u$ L( o u<br>
, ^ {9 v2 l' A: y6 }! } <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
1 Z8 w9 @7 K! `% W <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>! W$ }" l; m7 M: E" ~
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
3 z8 M3 f5 c: S$ b# K <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>" R1 h8 M( {4 W
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
" l! ]( _* T& s9 l <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>8 N( `6 {* ~( s7 t
<span class="kw6">run</span>;<br>6 e7 W% n7 ]% I6 ]
<span class="kw2">%end</span>;<br>9 g$ v! D9 K( ]9 a6 B5 g+ [
<span class="kw2">%mend</span>;<br>
: c* v. J8 o% t& E$ m5 W. g# H( ]<br>
% U$ w w% [" I" t2 I* d$ [+ S% E <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
# x! ~: Z8 n$ g* s6 R) M0 e7 k5 \6 V T <span class="kw3">length</span> code $200;<br>
( ]1 n6 b: u; C1 [: a, t <span class="kw4">set</span> meta_table;<br>
4 `8 K/ z4 U8 \! B code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br> ^1 L4 P: D2 X+ Q( {% a( `" I0 w
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br># o2 H, J& e3 a; B3 p# I
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>3 b2 v* u8 Z7 q2 s! ?4 Q
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
8 u X: i( Z; L, v <span class="kw6">run</span>;<br>
3 h6 X8 _, t( D, o3 e6 m0 v. h! N<br>
2 h q" R4 B, K6 {: u4 c- E7 L <span class="coMULTI">/* check */</span><br>
. r5 Z8 E3 H! n: ?0 X P, ^! Y <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>
, h& [$ Y# V, w) a' w1 o <span class="coMULTI">/* on lst<br>
2 R) x7 H0 J$ [6 s# k ot1<br>. A) C- H! D- C
Obs v<br>& v5 t& N4 _! Y2 w5 k' V4 a7 |
1 a_agg<br>
: H/ i: T/ q+ N; `: K 2 c_agg<br>4 c- ~' g& G/ Q! C
*/</span><br>+ F* |8 i+ q: C% f4 ~+ @. \) C
<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>
2 q, |$ o4 Y# d+ H, X9 q5 Z <span class="coMULTI">/* on log<br>
6 E3 j6 c3 Q) P& F1 C$ L+ ?6 k, a NOTE: No variables in data set WORK.OT2.<br>
9 \) Q5 B2 B4 e5 J* a5 z& E */</span><br>. F2 R. w$ v+ h0 v- T3 L; s
<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>
1 w/ K3 N# Q! F6 M <span class="coMULTI">/* on lst<br>
# I% G: {4 T+ Q/ l3 \ ot_<br>
- R8 Z' j, g- ~' \( q Obs v<br>, H2 |- }- Z& @- L, V
1 b_agg<br>
) E% k% v6 U# X9 D& i, L+ `! _ */</span></div></td></tr></tbody></table></div>
+ i2 H8 D3 m* }- P<hr>0 v/ i/ S# ^9 D" g5 z! r
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>3 \1 s& f0 o( t3 A4 ]
<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>4 N" c' M6 L4 P" O% R
<span class="kw3">length</span> code $32767;<br>% M @ K( c- \# |+ }2 h
<span class="kw4">set</span> meta_table;<br>5 [" P2 }! |/ J/ M# x" `
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>: e9 T/ h( s8 M. g2 E0 n- X' H
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
7 t6 D; y- D% t; }: _<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
5 }! @& ~0 r, E5 Y, M<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>$ ~% ?4 k) `/ m8 L1 L
<hr>* I6 b9 @6 B! ~% g+ |1 f( O; N
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
( \; P1 @4 A$ K' i# t% c<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>1 v; ]. z0 `% |! A
<span class="re1">proc sql</span> noprint;<br>2 G+ B' M( c& D. v3 n. _3 X3 y
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
7 B, s% K9 q" G2 g5 O <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
$ h3 ~. Q* K1 R" l4 B% L- k <span class="kw4">from</span> dataset<br># ~4 c. |: O3 a7 ]# t" p# [. S6 R
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
) z+ X. K+ k8 }) F7 z+ T( K <span class="kw6">quit</span>;<br>& N5 q, A& M8 N8 z: j
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>9 I& F0 u! M( N! q6 E1 X( ^
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
6 R. u( n U7 O <span class="kw6">run</span>;<br>
- j8 y4 @: T, R8 e0 A7 Y9 ?4 j! C; P<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>7 o% K C* ~, w: ^% U
<p></p><center> <script src="/c2.js"></script></center><p></p>0 Z. ]% H- W# w7 m7 z# b8 u
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>+ W0 u- y& C: G. X
<ul>& `1 |! B; p! e7 a
<li>- k* m- k: K0 M- Q& X- I
在调用执行方法之外按顺序运行宏?
8 O& v+ V, E5 b y2 A. w1 [</li>
$ l/ t' m/ M% c# O; s* C0 ]" V; ^<li>2 ^ t( s6 p( t; S9 B
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
% Y; {& \6 k u" a8 {7 Z</li>
7 s' N! b I+ c6 Y<li>4 y H( z/ k, ?
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
- o3 [; Y8 @1 Y$ d. O; o</li>$ K _8 v- Q2 z/ R$ R0 B: e3 R
</ul>" q+ d- H6 l& k+ L( |) p
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>9 w& q2 [% y$ y' z9 f% V" ]
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
- k3 s8 c( e) w# }& g8 v<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
5 B* P( o C" z$ X" E5 C6 x* Y<div class="suo-content"><div style="text-align: right;">7 s- t! s- }/ j, N* w' w' s) [
<div class="xControl"><i class="fa fa-caret-right"></i>4 f" s+ Z. Z3 i. v: i
<span class="xTitle"></span>
+ U! }+ f/ D# Y1 n* u$ G# Z5 v 相关讨论! X8 c& L2 j4 V# y+ L. R: o
<div style="clear: both;"></div>$ e1 c3 k; @5 P4 K
</div>
7 t8 L) ^! Y i9 Q% }; e <div class="xContent" style="display: none;"><p></p>8 p6 `3 M8 X R2 q# e
<ul>1 i9 R. {7 ]5 Y& r! _7 x: o( ~
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>. z' H" P3 V# |3 ]* j
</ul>
* Y9 o; _* e% f) H<p></p></div>
# @! z- _$ [- U </div><p></p></div>
: O/ i1 q; b. X$ C" P; ]<hr></div> |
|