|
<h2>Macro variables issue when using call execute</h2>! o! E! b( f4 w5 I5 o4 s+ i
<div id="fc">
! K/ `, k5 H+ G<p></p><center> <script src="/c1.js"></script></center><p></p>: s$ Y8 M) y8 W4 E- g; s4 v
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>; l9 E- O! W% H0 \$ X5 z6 ?
<p>macro %TWO 需要全局变量</p>
) {& V* ]* A' m6 N+ R<hr>
* c. L, u; l8 J<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p> Y+ R+ o% i% Y u5 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"> <span class="coMULTI">/* test data */</span><br>$ s, ]" b' v: O4 s1 u
<span class="kw6">data</span> dataset;<br>* }. `" w! w! m7 v% {
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
0 v2 d% G' s" I name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
K7 d! r' ^& N) G5 h! B+ ^ name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>( }0 ?+ L7 @1 f7 m( q/ V
<span class="kw6">run</span>;<br>
9 ^( U' B; K3 g# `; Z6 ^<br># S2 I) j l3 }9 X
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>) z; N1 Y! A; [( b2 N; d. v* K
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>1 R+ y" K8 J: e- k5 t+ x
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>7 M: p4 C0 {: R- Z7 C
<br>6 ?: i$ O' G9 s9 P' W
<span class="kw6">data</span> meta_table;<br>: E: }% v' f3 z) A: {& P
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
' A. a# j6 q5 Y condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>7 S- E1 Z3 F2 I2 ]. T R
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
$ g" Q& q& E+ l <span class="kw6">run</span>;<br>
0 M$ \$ V0 d2 W) m$ K7 @<br>
4 \/ e1 }/ |6 }: g) v <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br> l0 Q6 Y% \: O0 V; v
<span class="kw2">%global</span> names_agg; <br>
, [$ C; H# w) D4 M) p( S <span class="kw2">%let</span> names_agg = ; <br>
/ k- K7 R# J% X8 s v( ]: x: X9 Q <span class="re1">proc sql</span> noprint;<br>
' L- e6 ~8 @3 j! ? <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>3 u* T8 N D* T% ^
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>& V- e& X; {9 a8 i9 j4 F! c
<span class="kw6">quit</span>;<br>6 s% a& s6 M. t% z9 I
<span class="kw2">%mend</span>;<br>
. a$ T# U: n; u% C- W/ s<br>, M$ P* Y5 V; X/ F
%<span class="coMULTI">*-- just checking --*;</span><br>
& [* D W% m6 _! w %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>
' t# n; o# \: K9 V4 `# _ %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>
- h! i3 q0 j: P. c: y: ~3 L %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
6 U7 B; G' A, U( L+ P& O %<span class="coMULTI">*-- on log<br>" h+ K& Q& K8 K( K
names_agg=a_agg c_agg<br>2 N, g8 t& F0 S6 d3 o0 U- b' Y
names_agg=<br>$ \$ O' Z0 l4 ?; t1 b1 G
names_agg=b_agg<br>3 B. U+ i& N6 x! [8 b) q ^
--*;</span><br>+ E& D9 R' g" K' h
<br>/ ?/ n1 y1 W$ F2 h. P; A9 j: u. @
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
7 {9 a, B0 k) K% C2 x/ I; } <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
# S0 x) t/ J) a/ O <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
( @$ R+ H* ?: h$ i" t4 O- G% I <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
# Y t# x7 p E2 e <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>% Q) Y+ h0 t) W1 S' D4 R% \4 w
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
7 }7 o0 v. P; T+ y$ I: p: l- i7 g <span class="kw6">run</span>;<br>: P1 ]2 _9 p! A6 Q* C, L' i
<span class="kw2">%end</span>;<br>
$ y, x/ v$ j* K <span class="kw2">%mend</span>;<br>
; D3 m8 Z4 q. M<br>- T2 S) j) Q" X3 A4 b# A5 k: `
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>6 U# D2 M8 T- \/ r/ E3 |/ K$ q
<span class="kw3">length</span> code $200;<br>
# y* X/ t* ?) A, u# ~, s <span class="kw4">set</span> meta_table;<br>
$ M5 E7 D0 a8 N( A9 S" `- j code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
7 q1 \" Z' N! q1 n3 |9 J. p code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
" L; `5 l! V5 F s code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
4 ~, J" }+ H3 B3 _ <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
) W7 f+ j2 h! M. \* M <span class="kw6">run</span>;<br>
9 o0 J' X$ e7 j, l8 ]: I<br>* E6 u2 ^8 G% s6 y& T
<span class="coMULTI">/* check */</span><br>7 X( _+ b: @2 \( K+ _/ O/ {/ M
<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>" X: F" |* J# {
<span class="coMULTI">/* on lst<br>
/ b0 n+ _/ L' O2 N ot1<br>3 O+ B. i2 V" S6 _0 U w6 ~ h, H' [
Obs v<br> M; ^! |3 v! A: l3 Q
1 a_agg<br>) E" a# x( n0 g- G
2 c_agg<br>
+ d! W4 Q$ {! J9 q0 U, @ */</span><br>! g" L6 H9 k3 u- f5 d& o" }& l" |
<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>, J$ G M% |# a5 [; I
<span class="coMULTI">/* on log<br>$ d, [; {1 i& A) |
NOTE: No variables in data set WORK.OT2.<br>) Z2 V. A% p% V) p0 N0 ?+ X
*/</span><br>, @8 T# Q* V; P( h* Q
<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>
; w3 |2 r( ~4 T3 s) \4 O& O+ J <span class="coMULTI">/* on lst<br>
- a& [3 T9 m `1 K5 s ot_<br>/ X' ^2 o" C4 M$ g
Obs v<br>0 @0 \3 ~. a* T9 O z: @# V, g
1 b_agg<br>7 a9 _) G: f0 ^$ g' L6 `; R
*/</span></div></td></tr></tbody></table></div>8 F' k9 ]' P! y. ~0 a( b( w
<hr>' u7 x% D( u; [% q, O. h. [8 }
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
! N- \5 b1 W. E<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>0 g' J. c; X; x2 u5 b: m$ ?
<span class="kw3">length</span> code $32767;<br>' ?5 ?1 \: m8 `. S
<span class="kw4">set</span> meta_table;<br>
5 f; X* j$ N* e3 U# ^ 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>( `+ l5 ]& G9 F
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
0 U) q- m+ W) v<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
% ^# Q& l5 n# u8 {2 d6 x, }; P }<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
' @3 @5 @. Q0 M0 T<hr>
' o/ A" b2 S" |2 R. u! c( R p( w<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
& w& P2 ^. l# e' C8 m<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>
$ u) R& f: w7 \8 m) o8 l" `/ E <span class="re1">proc sql</span> noprint;<br>
7 g) o' J+ S# ^' u" v+ n! [( m/ }/ B <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>" _& `; i) V# n; D
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
* K, z' S: t3 ^; ]4 r <span class="kw4">from</span> dataset<br>! Y7 I0 a5 j$ V1 m
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>) e# X$ k$ v* d9 F( X2 z4 C( u
<span class="kw6">quit</span>;<br>) ]! W% j7 ]; G$ n, n
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>
$ ~% P. [" O, C! f b <span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
% ]4 x) c6 E9 C6 P. F7 \ <span class="kw6">run</span>;<br>. g7 G/ \# ?$ E0 m3 u' P2 x
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>& O7 e$ |* W; Q2 s y" J1 t
<p></p><center> <script src="/c2.js"></script></center><p></p># k4 y2 z3 `3 u9 e* d
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
( ?0 S. g5 @# P& s<ul>3 E2 K- u1 m: W8 Q j
<li> M/ G8 e# S5 o: y+ z1 q4 D- v) I& G
在调用执行方法之外按顺序运行宏?
0 [4 R/ i# b! Y6 {+ I- ]</li>" P: [% P+ `' S _. @, V6 M
<li>) T g( \ r9 z
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
. E7 j+ Q) n7 L; m; D+ z: n7 N4 ~: ^- ^</li>
4 k2 n9 V) J9 @/ b& ]<li>5 g2 s: G% ]/ Q, y/ ~* ^7 F
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
( _4 h0 Y5 k9 X</li># e2 J0 u) V5 P6 @; t6 ~9 o' ?' ^
</ul>8 h' _" _9 r. h5 M
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
: x, A \9 ~8 w9 |+ i<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>3 c; }9 ]6 }# E6 W
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
" c8 R4 l6 n( x% N6 w% [<div class="suo-content"><div style="text-align: right;">/ V. Q& l. \+ Z% j: L, n
<div class="xControl"><i class="fa fa-caret-right"></i>
* I2 ~5 v- H9 r( W! @8 {6 z <span class="xTitle"></span># U: }0 a$ r1 I2 s; [ K
相关讨论
; r2 b; V* q& `0 L& \- i! J' P <div style="clear: both;"></div>( B# e x9 E" W9 Z/ p2 `8 z! K" G
</div>
0 `- \5 @; n5 g <div class="xContent" style="display: none;"><p></p>" f' T a8 s$ U, Z8 {
<ul>
6 H6 n9 K# ~3 n% T$ j<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>! Q& i; z1 `+ {/ Y8 ^0 _
</ul>5 z) |; f; L2 u' ?) H" c3 L
<p></p></div>
' Z+ X7 ^$ s3 ~ </div><p></p></div>; d# G2 {: ]( ] P
<hr></div> |
|