|
|
<h2>Macro variables issue when using call execute</h2>0 c' A" ~- n" n M
<div id="fc">" B8 A$ X" n9 }9 _: X2 B
<p></p><center> <script src="/c1.js"></script></center><p></p>
; w* z6 U$ O; B- P" O0 o/ i<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
! ~* b8 R8 d9 U<p>macro %TWO 需要全局变量</p>+ z" s0 [# X3 b. Y+ S
<hr>7 k1 |- e0 x0 u1 \
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
* ]* i; ?' b: w, w<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>5 m- H Z1 ]0 l: n
<span class="kw6">data</span> dataset;<br>
: {* C6 n @- ?% |/ T9 v1 f5 ]: J- f name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>: c" _) u* b: E& @4 g2 b
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>( R$ e. A9 ]/ G5 n5 M9 b
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>$ B2 S: v: _0 V0 H
<span class="kw6">run</span>;<br>+ |: s* A* [) Q9 [6 @- j
<br>& @7 }8 e+ m' E. `) M7 f
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
5 a1 N P. a8 w/ _ <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
. Q! l* x$ r! m/ }( n4 T, o <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>. N: {2 \7 F% ]5 r n3 g( P
<br>0 J. j4 r3 Y7 X+ k8 a6 ]9 X
<span class="kw6">data</span> meta_table;<br>
2 A6 ]. _* D5 C$ X condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
, I( `+ y+ s# n/ T B- h condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
2 G; C9 g, k$ H1 Z6 ] condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>. H5 S9 E( e1 { e) W
<span class="kw6">run</span>;<br>; t5 E, ^) f; n
<br>
* f5 A& ?3 Q' K9 k+ l <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
b2 W. j q4 @: ]4 x. h- f <span class="kw2">%global</span> names_agg; <br>9 X# F, S6 R8 ?
<span class="kw2">%let</span> names_agg = ; <br>) T: W0 X. J0 G4 A6 I. L$ V2 p
<span class="re1">proc sql</span> noprint;<br>& [7 Z8 ~, t/ ], g9 T
<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>
0 L* t& y) W; F5 b6 B: W2 H <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>; f+ `! p1 c' G) {' l1 q9 P3 n' C v
<span class="kw6">quit</span>;<br>
, R: D5 ]4 @& F! \( C' D# W- j <span class="kw2">%mend</span>;<br>! Q" S! d* }8 Z- K7 z
<br>
" d( i6 C, U4 S) B' w %<span class="coMULTI">*-- just checking --*;</span><br>
3 D6 O: t$ E0 V& w" U; d; p% } %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>8 s% Q7 J" a% R2 e/ J+ E
%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+ w9 W! b& V7 E* r1 Z %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
1 p6 ]. x. K# Z. o %<span class="coMULTI">*-- on log<br>
5 b) f; p: z3 K names_agg=a_agg c_agg<br>9 P( p) i4 C$ ?+ r2 V5 o4 ^
names_agg=<br>
7 R' I- ^* @! y( j; s, A q- N& [* D names_agg=b_agg<br>
1 p$ h/ P. G3 x- Y; P# F, z6 L --*;</span><br>1 F$ G a- F0 K; o" S# R
<br>6 q4 `4 j" r% v8 `8 x# E
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
; E( _! y' S5 A <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>- V+ ?% k/ Q0 Y1 i
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>. }6 ?" d% j" B8 C; R" A; |. r
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>; ^" `* W3 V, k
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br># \3 |5 f/ h- U$ C/ c
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
3 O4 b7 z3 h% k4 k <span class="kw6">run</span>;<br>' K. A6 V& m' R" J
<span class="kw2">%end</span>;<br>
: @" ^: Y B3 U6 R9 [4 T <span class="kw2">%mend</span>;<br>+ S. j0 y' x; G d; `" c6 C
<br>
* |: a' q( I0 ]3 [: K2 f% z <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>3 h& @$ ~ E/ T Y8 s; K: D+ V
<span class="kw3">length</span> code $200;<br>. _* L( ?( X3 t# `! M: @" K: G
<span class="kw4">set</span> meta_table;<br>
F) u( h4 x& W, Q6 i5 S1 f8 ] code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>5 Q# P( G N) [, J) K
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>( u! t( `( f h( w* G M, d2 i
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>' S' k0 j, p I9 [7 J8 r
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>% W# k( u$ [3 N$ B' Y
<span class="kw6">run</span>;<br>8 M: k( z: z7 o% H. y- i C
<br>
8 y' d2 ^8 H) \+ D <span class="coMULTI">/* check */</span><br>
1 d9 p) m+ l( p: F; n$ M4 h <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>
; u! X2 v6 R8 W! f7 } <span class="coMULTI">/* on lst<br>
1 h( `0 A8 \/ C4 L$ { ot1<br>
6 c5 X; s0 G8 W/ G( w! j( z" v9 m Obs v<br>
, q* {* C6 Y- a. k: b; X3 c2 Z 1 a_agg<br>& _8 z! k0 T% r, ~8 f
2 c_agg<br>8 f3 b) }# ]9 h) C" g
*/</span><br>
3 M" Q) m5 j; a! Q8 k+ e <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>
; d9 K# a' L; E ?- \8 ~ <span class="coMULTI">/* on log<br>
) Y; ^" ]* w. A E' P+ b: N9 L c NOTE: No variables in data set WORK.OT2.<br>
( B8 I* r( Y4 C+ P. f- d' Y& b */</span><br>
, T3 R6 { Y/ N* r <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>/ E) S# q* L. h1 m9 Q8 V
<span class="coMULTI">/* on lst<br>
! z0 `% X1 e8 o: u$ Y! ~ ot_<br>! `3 i3 x- z; u3 p
Obs v<br>* f4 H7 q" ]3 d2 h/ R
1 b_agg<br>
7 E) H# U! u9 P */</span></div></td></tr></tbody></table></div>- @; e" y2 W; j3 A' W
<hr>
) H6 C A- V' I. C( y8 g6 E1 N<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>6 D& r; {' z* w; w- z8 v5 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>3 R$ F& P1 \" K& S2 n& X9 r
<span class="kw3">length</span> code $32767;<br>
: j: W9 q a8 H$ l6 t: I/ b3 F+ D <span class="kw4">set</span> meta_table;<br>! [8 b* t" K1 Y5 ]: 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>( v2 E- ^; T9 w* t$ T
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>/ F6 n% i4 x; ~- V s
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
9 `* s& w& J# a) F. l- u+ ]6 E' V<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>% f' S/ _) O& Y! U
<hr>
3 I2 q) R8 B; p0 @<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>6 N$ N [! X }" i& H3 n$ Q) 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>
& k" Q. K1 L# s k: u <span class="re1">proc sql</span> noprint;<br>
/ d8 Y. {$ b O7 U* a2 k2 w! b; h <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>9 K, u c5 f# B/ Q# \% l
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>( J9 u4 }5 p* Z
<span class="kw4">from</span> dataset<br>5 l. T, |& s- U: g$ f. v- g
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>4 q# b% b% l8 ?5 @& C$ d
<span class="kw6">quit</span>;<br>: J' X+ A; ]. ?) x
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>
) m( H/ Y& ^ D9 d <span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
) Z1 R4 F) x, X' h <span class="kw6">run</span>;<br>
" i' r) Q5 }# W6 e3 t<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>4 M: U. u/ j: ^3 s6 D/ s
<p></p><center> <script src="/c2.js"></script></center><p></p>
; q: V5 x/ C' j<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
$ v5 d, }& n7 f9 y<ul>' O4 V2 O* { f! G+ n
<li>
: @' N. y+ h3 [& {0 X在调用执行方法之外按顺序运行宏?
+ k# Z+ e& w$ c" D9 O0 E) [</li>* `: e1 t7 n2 [
<li>, K* O) A0 z- G6 E2 r& h6 r7 ]' ]1 B
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?" u3 b0 ]# N7 u4 z R: N; `" x6 K6 n
</li>) _7 t5 B+ ~9 E9 \8 E
<li>
: }" }& p F% [ J) }9 k在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?' D/ r) u# t) I- A# d/ Z! D7 Q: @& ~
</li>
$ c* P+ s: H9 o- G</ul>
) A3 @6 w0 Q7 A% t/ ?! y<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
9 G0 i# |7 u. a$ _7 U( k<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
; P6 G1 h+ x4 h5 M<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
: Q0 ~* y# `4 ^0 d4 V<div class="suo-content"><div style="text-align: right;">7 \9 ^: ?) y1 m
<div class="xControl"><i class="fa fa-caret-right"></i>+ H9 F: S3 d6 r; b
<span class="xTitle"></span>
, N8 n1 N$ q! q 相关讨论
* g, R, n* y2 `+ u8 T& P <div style="clear: both;"></div>
0 `8 U% T$ N( F& c </div>
- R% V( J p( O4 ]. k$ n <div class="xContent" style="display: none;"><p></p>' b* y3 l' g! R$ @+ C/ E6 C& x
<ul>. w/ u! K0 w7 M8 a9 Y) V0 ]0 ?
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>, B8 A: y$ g/ {9 d/ R& ]
</ul>$ }, F" e! z) y) C3 e
<p></p></div>4 T$ k) h3 n: l9 f6 Z
</div><p></p></div>
9 e& h; O/ x4 _( p: w; A+ W* F<hr></div> |
|