|
<h2>Macro variables issue when using call execute</h2>3 ~: R( |0 P* C0 \# ^$ |# _
<div id="fc">
5 K% t5 S, p5 ?( d4 X. J2 W) [<p></p><center> <script src="/c1.js"></script></center><p></p>
6 s' L, \$ @. q( y<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p> a: L$ `/ }3 d* J: ?; Q W
<p>macro %TWO 需要全局变量</p>- u, B9 P$ F, L$ H% t& K
<hr>
, G4 q. V: Q# T+ `3 V. i6 b- N<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
0 a0 b, ]" ~- U" ]; F<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>4 G/ ?5 M$ M7 { d9 A& m
<span class="kw6">data</span> dataset;<br>' t* U! u# C) j; t
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br># D5 J ?4 _ S' h) r7 M0 @
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>7 W& G" C. S1 c4 ^( q* N+ P
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>1 b8 r4 A/ j! h3 m4 k- _
<span class="kw6">run</span>;<br>& I& N+ Y3 ]2 G) F
<br>$ {! M% {0 G; L' C) a0 P
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>4 t F: ~, V& U
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
) I$ `' o, f$ A- Q$ b) d9 N1 e <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
9 _! t4 n6 c+ ~. p<br>7 X$ ~5 F, ?# c Z( {
<span class="kw6">data</span> meta_table;<br>: j9 m5 `# F: q; P$ ?9 c9 _3 c
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>9 p7 \0 a) J! j7 c* E
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
" F# C% D7 g# ` condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>4 o) T* I! c0 V; u" R
<span class="kw6">run</span>;<br>: T0 m7 x7 t; n& B( m
<br>, k8 A5 G9 Z* t
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>- c: E! L8 } _4 O
<span class="kw2">%global</span> names_agg; <br>, r& h$ a6 H) {# W. H% I' f
<span class="kw2">%let</span> names_agg = ; <br>
$ H8 l' I2 j* A; c3 H6 ]3 L <span class="re1">proc sql</span> noprint;<br>
1 W( Y+ y* p! s <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>
# P# i% V: B1 E <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
% ^, O- s. n" E2 K7 W <span class="kw6">quit</span>;<br>
* \6 r1 s0 c/ X$ W. S! R4 h- u <span class="kw2">%mend</span>;<br>
6 R; Y) s7 s# B" }- ~9 Q<br>, `7 V F l' ^# r, @1 k- L
%<span class="coMULTI">*-- just checking --*;</span><br>. [) k$ r( }! ^* Q2 u3 x" ^; T% X
%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>
1 s2 [: \" t7 Z0 P %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>" O" C5 `7 s5 I) g, A
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br># J8 M; p2 o& C+ @
%<span class="coMULTI">*-- on log<br>
5 N( w2 l8 p5 k( _4 r names_agg=a_agg c_agg<br>* C& z) B8 r1 `+ ]+ E( k- J
names_agg=<br>
! Y3 A& k E O% n [% { names_agg=b_agg<br>
4 @! M" Q7 Y0 W+ n2 b --*;</span><br>
1 q. t0 a! v5 x+ k% X<br>
" D8 ^) m7 C" o; S" W <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
7 ?1 {' ?% V+ j3 x4 Q- V! w <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
& f4 J, x2 n: w9 H. r+ Y9 o <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>6 g+ Z; i( p$ O+ w) r. y% K
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
$ n' u% O/ M$ J% v) k [2 V3 A <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
. \* \' d3 ^$ G7 Z7 E3 o( m <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>+ ~# H7 I7 ]( s7 w3 n
<span class="kw6">run</span>;<br>" G7 r2 o. `8 m2 }; i
<span class="kw2">%end</span>;<br>
: ?/ D( n p5 F$ [) `4 c <span class="kw2">%mend</span>;<br>
J. b+ t; {3 }( k9 D, f) @9 E<br>. t) g" M0 l2 {; @9 X! l8 x
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>; V+ P* M3 b! q$ q3 d
<span class="kw3">length</span> code $200;<br>
* c7 M7 ~+ l7 H( [3 ^: S; \ <span class="kw4">set</span> meta_table;<br>3 X/ g' H, \+ n$ B4 F
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
$ X' q0 @" L! v; F code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
+ S" [( Q2 [7 V% m, S" M code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>! ^3 Y4 W1 u6 A" f8 K F1 c) Q
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
, x9 \0 |1 H4 h" i <span class="kw6">run</span>;<br>5 H7 B. v3 E% o; y9 V
<br>
- K9 H5 ^2 t8 e! Y, \( v <span class="coMULTI">/* check */</span><br>
+ j! g7 ]2 V% J <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>
I* ]$ ^; d( A; x2 z <span class="coMULTI">/* on lst<br>% E) ]8 m6 S# n5 l0 ]4 I
ot1<br>' r$ a, C5 z: R: v% f) v1 v& [; j
Obs v<br>5 Q& [( V- J, o. E& U; _
1 a_agg<br>+ I( h1 P9 t6 ]' v/ T! ^4 O5 U% x
2 c_agg<br>
: v* S w/ ?7 u8 h& T* z */</span><br> F4 K1 V" x2 s0 f
<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>
# n, Y- ]" K. O( C. b% X) A <span class="coMULTI">/* on log<br>0 q2 A9 v: h' j# Z/ w% Z4 ]
NOTE: No variables in data set WORK.OT2.<br>
- Q, j: r2 M. C */</span><br>
' t. E3 P! B; r& R* g% W W <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>
, ]/ A6 ~: ]/ b3 Y <span class="coMULTI">/* on lst<br>% R7 N5 ]; o! T% U! Y
ot_<br>
/ [' _* j; `& z4 x: s9 d9 b, N Obs v<br>' @0 N: a- B/ F; j
1 b_agg<br>
/ W# m0 p! f Y1 M& Q */</span></div></td></tr></tbody></table></div>
" f+ ^3 F! I# V/ e7 p9 z$ h/ b<hr> F1 Q/ D# B4 n4 Z
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>0 y2 y) s9 d, r( ?0 p8 L/ V
<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>" e6 G ]5 |1 C
<span class="kw3">length</span> code $32767;<br>
4 E5 r4 _1 S7 j) k) ] <span class="kw4">set</span> meta_table;<br>
7 X7 D6 o, Q0 z. q9 @2 P) r 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>
- G! z5 {9 D; M5 {0 E <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>) [6 F! T% T# _& I( u4 y: V4 q
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
4 D" A7 a3 C$ b% O" w<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>6 t) L3 z2 }& _( T/ p C
<hr>
& q8 H4 Y' C$ |( Y/ C d: r# r<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>+ {0 o0 e* c$ y9 l5 K
<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>
- D. W( s* [8 D- S5 d <span class="re1">proc sql</span> noprint;<br>
$ n7 U+ d" N K; D; ?5 d! ~, M <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
1 T0 z1 d' b& J3 _6 N <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br> O! ?( U4 q3 u) L$ I. @
<span class="kw4">from</span> dataset<br>
1 k& O( Z7 J; j/ b5 M <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
4 H; w1 R! H! F: o/ |2 C <span class="kw6">quit</span>;<br>6 A* k4 ]. p/ A9 y& c& }
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>8 ^, J7 T$ Y1 S: B I
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
/ M, d, M+ U% p$ @ <span class="kw6">run</span>;<br>
; J0 ?8 M' o9 G7 [, a; d" m1 ]<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>5 Q. b' U1 h' f' e- `$ |
<p></p><center> <script src="/c2.js"></script></center><p></p>
& I' S# i a+ l# S4 x7 w<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>* z+ g) ]0 ~0 q2 B6 e, N/ q# i9 C0 \
<ul>; Q9 @# i, q& D
<li>
# \ S2 G7 H: k) D# w" c# A" m5 f在调用执行方法之外按顺序运行宏?! J1 Y$ j) B: q$ {+ x
</li>5 k' d, ]7 q8 h) x7 ?+ ^5 H3 b8 t
<li>
6 e4 l& N; l6 r& }在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
( A' w' }0 Y$ ?$ |6 g5 j</li>
& R- C z# |4 ^) \# ^" l% o! F<li>, s) Z/ ?" @3 D! \- J
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?1 ` m' }0 `1 e% `$ G5 R
</li>/ L! D* x/ w( n) [
</ul>
% `, w1 g: |2 X2 z \, ]$ |9 p<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>9 A# S0 w+ V8 @
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
" J6 F S( x9 h<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
* U( K- `# t$ r<div class="suo-content"><div style="text-align: right;">
& w1 I: s7 ~% g: ^0 ~& _: k9 o9 u N <div class="xControl"><i class="fa fa-caret-right"></i>
; i& i, V2 f! q$ \ <span class="xTitle"></span>2 @: @8 N4 o* G1 G9 H8 }
相关讨论/ j: _, `. U& D3 [
<div style="clear: both;"></div>
9 b& \2 j( |6 m# g4 x, G# T8 ?4 g </div>! [0 p6 q _! c* o4 H
<div class="xContent" style="display: none;"><p></p>
' J$ X8 [) _9 v( x. q4 n<ul>0 M1 R: h; L' B& \& A$ d/ U
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>3 S' `/ \+ z1 g: V6 E. n, h
</ul>* s8 s4 s( h$ K
<p></p></div>
' J' t# B% Q! ~ T/ K1 _ </div><p></p></div>
' t. ]+ S, ?( B# U<hr></div> |
|