|
|
<h2>Macro variables issue when using call execute</h2>4 Y: ^ @" ?6 c3 _+ I
<div id="fc">
8 S# \) g- D; k, I8 s" @9 b7 s<p></p><center> <script src="/c1.js"></script></center><p></p>" x2 O5 g: U7 I4 G
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>6 S$ q0 ^! Y* K& o1 K
<p>macro %TWO 需要全局变量</p>
! g, _% f7 ]' N: @6 F<hr>! J+ u/ y; y* ~+ G8 S2 M
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
6 G' s5 W+ m: y7 [, q<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>
$ e" @/ n+ x9 ?+ U$ c8 x6 W <span class="kw6">data</span> dataset;<br>) Q( G: z0 x/ E' X5 {. }, h9 A, R
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>4 O8 S. ]2 d. e5 I) x
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
/ v6 ~( A" |; M% L name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
- i. e- g. H, t* K' I! h( F0 p H0 l <span class="kw6">run</span>;<br>1 r6 e4 b) u' ^8 ?
<br>: Q. L6 y2 b: L0 F
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
/ W! Q* Z* f4 {% [# P; k2 q8 R" G <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
* Q- k8 P/ L, b8 S <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
9 f( e# p+ x- X6 C<br>
) A( B( {/ @& E* S) u7 a- B <span class="kw6">data</span> meta_table;<br>( W9 g' ^0 B1 t/ a
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>' P: y4 V) u: m: |5 j
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
Q Z4 b; D+ I7 A condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
( T5 ?! P( v) r% }2 k% G8 ` <span class="kw6">run</span>;<br>! A& @5 e0 P" F( l/ B
<br>) H$ y, d! l" @# y0 p' q) }
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
3 o7 ?6 f! Q2 e' s' n2 r <span class="kw2">%global</span> names_agg; <br>: X9 l& I. L; |8 J( [ j
<span class="kw2">%let</span> names_agg = ; <br>
: x) R! c5 K$ i <span class="re1">proc sql</span> noprint;<br>( }1 r- {& P% w- t% r/ a( \
<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>
$ Z! q9 d b9 V3 c9 x6 l, l <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
+ n" R& j' ?7 Z7 r: w7 V K! ]1 g <span class="kw6">quit</span>;<br>
) q9 ` M3 A! b/ S% M' J$ g1 Z <span class="kw2">%mend</span>;<br>0 y8 I4 ^. K. Q) L# U
<br>
; p+ C* N5 w- B+ w1 \0 X9 y %<span class="coMULTI">*-- just checking --*;</span><br>
- u' |6 ?3 x" B' H6 a! L %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% R7 Y2 L: ?2 z- f4 x
%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>
9 u* v/ Z+ M( v0 ?9 q" @" 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>* v# c% ]+ s; C( N5 n
%<span class="coMULTI">*-- on log<br>" v$ t8 w% ?% L
names_agg=a_agg c_agg<br>, w4 |3 S7 w4 Q3 Q0 r2 A
names_agg=<br>2 Z/ m9 w) y2 S1 q
names_agg=b_agg<br>3 \1 ^) }& E2 ~; ?& ?: \/ @4 r
--*;</span><br>
4 p& }5 c) r' O7 U- S<br>, J# l( b; Y w% R, a/ x7 \2 ~
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
+ Z3 i. E4 M3 p6 S3 N" t7 ~! h <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>) M5 Z& `: M' m U
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>1 A6 X N& \% A2 O2 v9 i
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>/ X- x: |0 c2 V- ]1 X" x3 O V. l
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>% u1 P" J9 W: A4 ^. U0 P
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>/ U: X9 p7 x8 r( W. i1 J, E1 G
<span class="kw6">run</span>;<br>6 }. S3 B% h& M) K% H3 o
<span class="kw2">%end</span>;<br>* n% ?5 M* k; w
<span class="kw2">%mend</span>;<br>
2 y4 W* h& N" [% Y1 J' }<br>
+ i; X( p2 r! ?+ B9 ? <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>: _% W/ z5 z' i$ ~! G& ~- B/ f V
<span class="kw3">length</span> code $200;<br>3 h) K# n7 u: R0 l a
<span class="kw4">set</span> meta_table;<br>
. S# _1 P y0 I9 [% l1 r code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>( n' \' l: K& P9 ?& [* Q: }
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>! N: M; f2 V. e( K; `$ L. a. v
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>' ]; R) S1 D- k% h9 W" q2 b4 x
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>* s/ M2 x2 b4 O- L7 V* h& |
<span class="kw6">run</span>;<br>
& S; p3 V' E/ I- N2 t/ ^( j8 d<br>
4 I1 ?0 ]2 ^4 Q0 {0 g* k, Z <span class="coMULTI">/* check */</span><br>4 V& U, b$ z; b* b
<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>
) D* Q& z' S) X9 q! A r <span class="coMULTI">/* on lst<br>2 e8 o) y9 l: [( [$ {0 D6 a
ot1<br>1 l& \6 U/ e$ k$ r
Obs v<br>
7 }2 m# D0 j' K; ]' q9 }4 Q 1 a_agg<br>. F* w4 c2 p9 r* Z) o* }, n
2 c_agg<br>! I" b1 P: W7 i3 e; m/ c5 v) ]( X
*/</span><br>
" u+ o" X2 m* ~% h# 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>3 ?! f; u3 c/ @4 \4 O
<span class="coMULTI">/* on log<br>! t% E& Y3 Y" ~8 n% ~( ~* ?/ `
NOTE: No variables in data set WORK.OT2.<br>
: f. g- k- `% p: F */</span><br>4 L& @( T5 X" v
<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># B, I) \" e$ U& L
<span class="coMULTI">/* on lst<br>
l+ b3 u) m9 `% U ot_<br>* }/ F+ ^4 J' ~. N! }, Q
Obs v<br>
Y1 ]9 Z7 }' z" W0 z: X 1 b_agg<br>5 `4 k& M6 M* |; t2 w
*/</span></div></td></tr></tbody></table></div>
( d) S9 z+ \& p* ?<hr>* ?: M* m w3 V; Y, q7 ~# x
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>, d! Q4 ^) S, K+ ]' R0 r
<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>
$ f4 _ q* `6 N9 k+ V4 p# r5 _ <span class="kw3">length</span> code $32767;<br>3 T. c; i( G- r5 ?9 J* ?) d9 I) Y9 m
<span class="kw4">set</span> meta_table;<br>
$ ?; f8 v5 o C* ~) r% i$ G0 b 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>
8 |* F! ~, m2 u2 r <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
2 F! B. C* }# Y" m+ T# q( |<span class="kw6">run</span>;</div></td></tr></tbody></table></div>& n. _; O8 Q5 v' Z6 |5 g
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>7 |3 c: l- X/ v) ?1 J' f' P/ w
<hr>
2 [6 w0 I5 F& B. J% T& c6 o; W% I<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>+ P) w8 L4 K+ P0 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></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>
% T: }- [( }- ] <span class="re1">proc sql</span> noprint;<br>3 G4 Z2 [( {1 G- F: i" Q) o
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
, K" v9 |8 O. g1 D( w" |. i7 R- v) [ <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
" Z6 U; N# I: S5 z" g4 F9 Y <span class="kw4">from</span> dataset<br>8 C, d# ?; I6 k. I& f6 J
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>* B2 K5 H2 ~3 V1 T, v
<span class="kw6">quit</span>;<br>
$ k! b: j+ n7 j2 a3 G& a <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>1 k! i' `+ Z2 @* A* P
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>) D7 |1 b8 } ^5 g* H+ Q' |# x- h* ~
<span class="kw6">run</span>;<br>
% q4 a* i) |: b0 Y<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>- W' X- d, n8 ^2 x
<p></p><center> <script src="/c2.js"></script></center><p></p>
8 S% ^9 X. {/ d! ^/ K5 Z* e& z8 ]<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>$ p. I. c6 O; y3 N" H/ J( k/ f$ v6 e! m
<ul>) N: V: h0 Q2 v1 s1 o
<li>$ h' P' [" ]/ Q% z w" w3 T
在调用执行方法之外按顺序运行宏?! G, s! A/ k" _4 t' e4 X7 y
</li>
+ M" g k$ U& P% K# d<li>; e9 Y$ @( w. V% b+ q2 ~6 p! K
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?( j/ x! Z8 J9 Z: j3 V
</li>& H& r) c7 r3 ] v" T! A, x
<li>
( B. D3 w6 f4 q在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
) x; G7 c9 {9 T* h</li>
4 N5 [7 C# B1 ~, E, s</ul>) C* B$ r: Q& K/ h
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>) y! \8 J) j: q4 y: r2 x4 t
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>" i: ^, y. D- A5 T! p F, K* G
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
0 S4 f9 y4 F+ k1 E6 S<div class="suo-content"><div style="text-align: right;">3 i& t) m/ H, d7 r, G; T
<div class="xControl"><i class="fa fa-caret-right"></i>
* Z% r& {5 [, A2 d' g2 j' Y2 i <span class="xTitle"></span>
' Y/ ]/ N$ {4 g" u7 \ 相关讨论9 p) r- J& J+ b4 \* l
<div style="clear: both;"></div>
) x; V' v: Y2 C% } </div>9 j% I) I0 H! d! B Z7 h
<div class="xContent" style="display: none;"><p></p>
- {9 l6 H0 w i, G<ul>/ g, ~5 e& Y: S! Y, B
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>! t3 J! x/ O0 T: A4 J
</ul>
7 S. R1 ?; ?. ` p<p></p></div>
, D N! r1 I6 M( ?7 O6 d# Z </div><p></p></div>1 @# h7 A2 t( w+ u' R
<hr></div> |
|