|
<h2>Macro variables issue when using call execute</h2>
- C" f+ E+ a+ Q# }. S0 U<div id="fc">6 V( d' H$ }, \
<p></p><center> <script src="/c1.js"></script></center><p></p>( |& K% r8 ], d6 [% h0 u
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
/ E7 ?. x0 ~$ b+ ^& `3 K% p. I( c<p>macro %TWO 需要全局变量</p>
8 k* a, ?# ]9 c<hr>
- [- P, X0 m+ a<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>0 l( l, l' P" E$ r# 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>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>* w' E7 k" c" ?1 }" U8 n$ l
<span class="kw6">data</span> dataset;<br>
" s, Y# U0 ]/ l5 r name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
1 q. A: H( V1 a; ~4 M* g name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
9 q& M1 f" O, c name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>. j$ w X# c0 M ~3 l# I& \/ k
<span class="kw6">run</span>;<br>
- m3 D0 E8 _5 v& U<br>
, ?; {4 j, x5 D# v; G1 C <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>! i2 Q/ P8 |6 c( R: [
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
) [( g+ s# [( j* D, b$ f: t <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
# B5 I/ A x: v5 q4 [5 `3 ^0 L# G<br>1 V9 [ f0 D h: B+ K% {
<span class="kw6">data</span> meta_table;<br>
# J! ^; T8 J8 Z5 Y. v! `. L condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>$ |+ V: O8 L B' R& J8 | |
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>& S% U# [- w! y4 {, x) Z) @
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>; y1 R5 X6 p# b, M
<span class="kw6">run</span>;<br>
( S' N/ g' {& d! {<br>
8 b" j S0 F* B1 Y: j <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
; q! z) n/ i3 a9 g! Y <span class="kw2">%global</span> names_agg; <br>+ Y: N: V- M! y! M6 h, j+ l# L) }
<span class="kw2">%let</span> names_agg = ; <br>3 h* `4 f: J; s) c/ ?
<span class="re1">proc sql</span> noprint;<br>
5 d9 J/ K8 U$ K. z <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>* c0 t& B# i+ [5 ]) b. \
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
- Z! M- u. P0 O& e; d% ^7 k <span class="kw6">quit</span>;<br>9 g- c' ~$ y3 J W
<span class="kw2">%mend</span>;<br>$ y" o) m: a( e7 a! i0 C1 X8 Q
<br>
: d7 ^3 O; N/ g6 a; K %<span class="coMULTI">*-- just checking --*;</span><br>
4 T# L: x' k% F6 ~; A$ L0 @ %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>
& @5 o- Z8 H! H. G6 U# w5 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>
. E# _9 G2 H7 V7 n' {5 E# T: 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>+ V/ R/ C/ M7 G' X. f7 { ^' z( |
%<span class="coMULTI">*-- on log<br>+ V- [- z! W6 e
names_agg=a_agg c_agg<br>1 m8 G" p8 b, G3 K9 \
names_agg=<br>: i% w: S4 x" X8 T- j! F7 f
names_agg=b_agg<br>1 P& Y' l% T# J6 a, _% o4 n
--*;</span><br>
2 N j. o; T) A<br>
. f' k" o; _+ h6 A, {3 f <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>* s. P. H9 _. ~& Y
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>% x" P$ ]) y6 l. G( K
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>/ I e- |$ G7 [/ K v5 d, s
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>8 Z& ]7 Z5 G" F) R* N7 m) ]
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>0 b! E( f( D1 z* o ^* W* a6 E% m# S
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>/ ~4 F8 Z" A( |& m! c2 m! M- S
<span class="kw6">run</span>;<br>
# g/ v! g6 H2 b" n" s w <span class="kw2">%end</span>;<br>6 ^0 `' {9 m" Q2 m5 j' H- N
<span class="kw2">%mend</span>;<br>
; E9 W# x1 v0 Y* \" J<br>0 @$ E& q$ L0 V% |' G+ Z
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>3 a4 h. A( v% t& I& C" \; ?8 w
<span class="kw3">length</span> code $200;<br>' q6 M. d' j; v" k
<span class="kw4">set</span> meta_table;<br>
4 G d( c9 l6 @; R code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>0 \8 ]( `/ w7 V" K/ [. D! |6 a
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
* p$ p' ~3 Z- P9 W5 X% Q7 l code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
( Z# F8 ^) V; f- h! i <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>' g2 t- U6 {8 p0 |% b
<span class="kw6">run</span>;<br>, {* ^& b9 J U" |+ w
<br>
. {5 W( y3 L8 k5 |( x <span class="coMULTI">/* check */</span><br>
" G5 ]' C7 y( ]4 g <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>
: Z) j# y) v" J6 o. i6 s <span class="coMULTI">/* on lst<br>! v8 a' t b M6 w# t8 v4 q
ot1<br># r' W0 R/ n6 k- @% b, D
Obs v<br>$ D; K# S- R8 @- ]
1 a_agg<br>/ ^, m8 a( @7 R% w( s: [) `
2 c_agg<br>
! i: ?. z+ Y$ } */</span><br>
5 i" w$ m( S2 y7 W4 ?7 @7 b' r# F$ A0 Q. 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>4 B' [4 R; d1 B1 Z" V) J
<span class="coMULTI">/* on log<br>
_3 t1 m& R* W5 E NOTE: No variables in data set WORK.OT2.<br>
- h5 J7 Q) V( P */</span><br>. r" X: a7 P+ o
<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>( m" c- k0 ]- L$ B! a
<span class="coMULTI">/* on lst<br>
) f, e0 P+ l+ V; C' L9 ^ ot_<br>" ?9 K5 }5 {5 b, e8 j9 n1 @
Obs v<br>/ _: P" Y* S7 q7 x
1 b_agg<br>
# p# z+ O( d% |9 I) v, W0 { */</span></div></td></tr></tbody></table></div>- e: r( B0 ?+ i% R) Y0 z
<hr>
5 y0 a* W% f: c$ e( P: ^# j! n<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
& W2 g6 T' c+ 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></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
) j9 P1 o* ]+ G: R" n/ P <span class="kw3">length</span> code $32767;<br>
; g) U7 @7 ?8 m+ `+ }+ p+ l" q <span class="kw4">set</span> meta_table;<br>
9 l$ v, \6 w" x1 w6 `- d T+ a+ ` 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>
0 X' Q2 E# S4 f* S o <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
' ^: `( e9 |% F/ l* I: h2 W6 F<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
. D+ m% C- Z, C4 |<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
5 [, d- o6 o. u<hr>/ ^7 B$ ?7 A: U9 ^+ M
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>/ S# L$ Z( j0 f5 v' M/ N7 }. {0 X( Y
<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>
2 ]6 H! r0 a& v! q <span class="re1">proc sql</span> noprint;<br>7 A! F) K$ s* J
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>3 B) {3 `/ o5 R0 R# m7 f, J
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>! T R1 \& ~9 q* J
<span class="kw4">from</span> dataset<br>
6 o% A1 o* A, X# Z% u o4 l <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
) E; z6 V* p( e* e' X& ?# e <span class="kw6">quit</span>;<br>* c/ U$ P1 p4 ?! M% u
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br> U5 X! }% }) g" S, ^
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>$ O1 A! d) A# z8 D6 o
<span class="kw6">run</span>;<br>
9 X7 D' f4 n* w$ v* {! ?# m<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
" i. i) E* L) f) ~3 T8 m+ D, {5 G6 D<p></p><center> <script src="/c2.js"></script></center><p></p>
7 N5 d4 F, @6 y6 W+ W: N: @- Z8 n<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
8 H, ]' }2 h6 t& @; C6 g0 a7 z<ul>
+ [) _! S# B3 Q/ Q+ V p% O<li>/ o7 u" H2 N: p3 }
在调用执行方法之外按顺序运行宏?
1 I% y' H9 I7 n/ v) @. J</li>6 f* S E |, n( g4 H; z
<li>" x }' [3 f1 {. `' g4 I
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?$ P4 d0 V5 Y$ k
</li>$ \* U4 C( ?3 `5 i+ F6 n: d9 n* ?
<li> u+ X ?6 r ^, r W
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?" u/ l9 J- p7 @- f$ p. y
</li>
B* |6 Q1 ~: u) M" M7 t- o1 v</ul>& v! N- P; e1 O- X+ l
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
+ g' I5 d9 x8 k- f( y<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>9 w! p: l# |. Y) \7 y- ^
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
, i& n7 ?7 V$ Y: J; G/ O2 {' _<div class="suo-content"><div style="text-align: right;">
0 s/ M$ k' g6 \5 b <div class="xControl"><i class="fa fa-caret-right"></i>
; ^6 s: [. i7 l, z/ v. X0 T& B <span class="xTitle"></span>/ r4 H2 t A$ C6 a5 {( o8 W+ v9 J
相关讨论
5 r1 B, _& ^( e' g1 O: _ <div style="clear: both;"></div>
) g( q4 \$ Y9 v9 C* ~ </div>! g- q( ]) v# m/ X0 J4 G% N
<div class="xContent" style="display: none;"><p></p># ]3 p4 O! W. _6 Y
<ul>$ F. o6 Z( b" I1 s# J. p; ~) J% l& k) G
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>7 x' @$ \6 N; r+ n$ F# V* n$ _9 O
</ul>
7 b: y, b% Y+ Q {8 H<p></p></div>' s3 a% ]- H0 W' _: I" [# [
</div><p></p></div>
* l( h* m2 j- C2 J2 h% P<hr></div> |
|