|
<h2>Macro variables issue when using call execute</h2>
" `$ C1 E9 @$ @' |9 \% n8 @<div id="fc">
7 [- @+ w% ~* M" A4 S# A<p></p><center> <script src="/c1.js"></script></center><p></p>' d- Z8 D: ]5 U; P
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
8 }% @8 O; M* @<p>macro %TWO 需要全局变量</p>5 \1 g+ J. p- O! L$ [& ?
<hr>
. G7 P! }' J% z' X. e1 G9 i: O<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
# H* ^1 K: y/ L& o; f" \# B<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>. d' y* R3 F7 z
<span class="kw6">data</span> dataset;<br>
, T" R7 x$ [# u9 r; `3 [6 [ name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
Y8 v1 |: Q9 W+ R name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
- _5 }- Z2 k m( u. X4 l- } name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>8 `# M; U1 g+ Z& f1 U& e* b
<span class="kw6">run</span>;<br>, e$ `( X0 r3 T+ q2 `
<br>
/ |3 t/ d/ t: g <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
" y* N4 j V" w' c& k! u <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>2 y4 E# P* h2 S, \
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
* i0 ~. y( R6 q2 C' w8 D& X<br>
9 T7 S" k" h3 E9 d$ k( L/ W <span class="kw6">data</span> meta_table;<br>
7 P3 F( [* F1 V2 i5 N5 U/ Y condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>4 X- o- s0 U" d! ^, S
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
* A: I0 H& R% R+ @ condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>6 e l. R0 z0 g. v1 b- z
<span class="kw6">run</span>;<br>
& C. `+ [6 x% H* s9 {, R/ W<br>
# m4 N1 T9 a( Y( v" ^ <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
- ? u* M; c# ]( U3 L <span class="kw2">%global</span> names_agg; <br>4 w! W, e" r, G2 }( U! Q9 p0 \
<span class="kw2">%let</span> names_agg = ; <br>6 t% e3 e3 s, O Z" v$ ]
<span class="re1">proc sql</span> noprint;<br>& K2 W6 \9 q' G8 x/ e/ H
<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>
% Y" g& P; e& R* o$ Z+ ~ <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
+ \# }! z$ L) ?; u' V5 d: \ <span class="kw6">quit</span>;<br>
- x3 y( h) q: S <span class="kw2">%mend</span>;<br>! x) W6 x9 H8 z3 O; e3 J# r
<br>
9 p8 Z) m# Q; Y# F3 E7 ?; S %<span class="coMULTI">*-- just checking --*;</span><br>
; d2 q4 |' h1 p( i- {# H% y8 C9 O %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) b. B# S4 i! @3 l %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>- {0 h/ o# v9 V
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
; a4 v) e4 K6 v; u' r %<span class="coMULTI">*-- on log<br>( ^; h, _ _) y/ U3 V% @
names_agg=a_agg c_agg<br>
+ H+ E1 O E3 I0 g8 h$ q3 r9 x1 O names_agg=<br>3 {& L: i" f* ~% t) }% U9 \
names_agg=b_agg<br>
/ Q3 h( ~1 K( b: R" L3 K V --*;</span><br>1 Q$ |8 c& a5 V; T0 A; u) q
<br>
2 F9 z5 x" C8 T$ p9 N$ L <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
+ h7 S3 W/ Z' A" I4 {( j <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
2 s/ ], E; Q+ m6 i7 _* m <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
P% J% G0 J6 a# H: |8 x) Q. ? ^ <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>/ y( E0 N9 h: K
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>$ y. A4 T' z$ S+ h6 P2 `0 y
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>7 a, W% w0 N- `: m
<span class="kw6">run</span>;<br>! c' k- h, {" Y0 Y7 u2 X
<span class="kw2">%end</span>;<br>1 u9 W2 p: |8 [: d: r, d' a' ]
<span class="kw2">%mend</span>;<br>
5 i8 R. c8 @: ^<br>
7 m. U7 v" F2 \8 f <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
. Q+ q" x; r" a <span class="kw3">length</span> code $200;<br>
7 x; q9 n9 N. x' f" K <span class="kw4">set</span> meta_table;<br>, N- w1 o: k8 ]" H
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
' \' z" Y2 P/ u) x code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
8 _0 o8 G4 c9 ~+ i% m code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
+ k" y. }' G* ^& r <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
" N4 P( c6 H. \+ c) e <span class="kw6">run</span>;<br>/ w2 o( r7 R& R _, e
<br>4 ?0 w r( d) a2 i
<span class="coMULTI">/* check */</span><br>
& |& R2 a' X: k0 p. ^2 @$ R) @ <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>
* C$ S6 m: }5 k* o4 Q, i; [7 b: y <span class="coMULTI">/* on lst<br>& \5 J0 n% a" A1 P( n6 f9 g
ot1<br>% B7 Q" p) m5 p% m" G1 s3 R: u
Obs v<br>
" w& R2 `/ {0 N- z9 x 1 a_agg<br>" I0 g0 [- D q. G
2 c_agg<br>
/ E" q0 S2 X: i! S" Y */</span><br>8 j7 @3 _+ F! g. x0 }- }/ 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>
9 q+ v; Q- @% G7 ? <span class="coMULTI">/* on log<br>
4 I7 _1 e3 J9 t: x9 c7 n7 Q NOTE: No variables in data set WORK.OT2.<br>
& k7 E# T' Z- s+ X& z5 v */</span><br>2 q9 i& N; B% F4 I* L
<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>$ A% H! g' V- _# {; f; I
<span class="coMULTI">/* on lst<br>+ ?9 _' o n7 i2 d( J
ot_<br>) Z$ ^, ] x9 Y2 m; y( i
Obs v<br>
; S# ?, s. a. p 1 b_agg<br>$ ~8 p1 i: @; D+ m' V. s
*/</span></div></td></tr></tbody></table></div>7 }! V+ s% a! N3 Z
<hr>4 E# l* R; d0 @& _
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>" y2 U5 v2 P D5 q1 C! q( L" A
<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 F; X/ p/ Z5 {9 W! W, |: [ <span class="kw3">length</span> code $32767;<br>- k7 I. M; `8 r* j
<span class="kw4">set</span> meta_table;<br>
V; Q; O" c' t: H 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>5 F: z% l: E) J6 k$ u
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
5 u5 Y! o6 K! q: U8 ]* ]$ ?7 e6 X<span class="kw6">run</span>;</div></td></tr></tbody></table></div>4 W4 g" G) _7 c8 O
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
+ v" S& j6 ?+ j$ `7 [<hr>* J* N I) f- c5 y8 P3 O
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>6 X+ q" u) n( s1 B; V7 g
<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>
- w. t5 Q6 S3 K1 ]3 q; A0 b <span class="re1">proc sql</span> noprint;<br>$ o3 d+ |; ^, Z0 a
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
+ X: F2 }( Y3 O <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
5 ?9 X f* W, s! o6 Y: E <span class="kw4">from</span> dataset<br>/ Z3 C) q* V# Z0 a( c( i) ?( m; G* x
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
8 E6 A. x' @7 H8 v- b <span class="kw6">quit</span>;<br>
1 d" q& [; S( w | <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>
+ |: ~. W h& e% b9 Y3 j5 {( p7 L <span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
$ R" V: k. y' D$ C3 k <span class="kw6">run</span>;<br>
' r3 h, y& {) \. z5 @<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>2 o5 O( l- k6 o
<p></p><center> <script src="/c2.js"></script></center><p></p>
. u: V0 Z+ A0 ?& ?1 c# p<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>2 m1 X# w. w6 I" z# J# ]! D8 ?
<ul>4 b! z* `# Z3 J2 ]# |
<li>( K( v1 w( P: O- x5 n
在调用执行方法之外按顺序运行宏?% q" T F8 {- n4 x
</li>% p0 M+ u. J% e. @- E' ~0 O
<li>
2 t$ F* R* ~0 D! ^ P- N在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?8 @7 @6 N/ Z5 _3 ^9 |
</li>6 ~; n. ^2 H' L: B& \% E4 x. I. O
<li>! d2 ]9 Q: y" _9 u5 l
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
- d6 V% d6 ~1 c$ }</li>
8 F& L/ t$ ]8 {0 h8 j' X</ul>
4 t6 x) d1 _4 t! v0 x2 Y<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>+ M8 f6 C7 y6 Z7 n3 u2 Z' S% `
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>' T: `! z- _# q q
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
, e: s |+ f! ?<div class="suo-content"><div style="text-align: right;"># X. P* m: `& o
<div class="xControl"><i class="fa fa-caret-right"></i>& G' s! C$ s9 k9 S
<span class="xTitle"></span>' ^$ N* a. l6 ~5 Z; q+ p
相关讨论
- s$ l5 z* y+ s6 O. I3 c <div style="clear: both;"></div>
" L% o+ L" M6 L$ J5 _8 C2 a! s% @ </div>
7 }: @! z: F( k1 q1 u0 [ <div class="xContent" style="display: none;"><p></p>% I* x; q8 m7 c( R) n* Q+ f' `
<ul>1 u! l4 W, D0 V5 i% ^" O" z
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>/ n9 V& L4 V* |4 @7 S' i6 {
</ul>) I' {# K" z- D4 B* Q T, }
<p></p></div>- Q! d+ T& I1 L: g
</div><p></p></div>
5 c+ b) B: {6 L( E! A<hr></div> |
|