|
<h2>Macro variables issue when using call execute</h2>) l3 b, V! V% p5 v( L
<div id="fc">* c. F9 U! K% L9 |& `
<p></p><center> <script src="/c1.js"></script></center><p></p>
1 c+ M" _, ~0 r3 }" c<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
# {) g/ R0 a# Y' j<p>macro %TWO 需要全局变量</p>
. m# }9 [+ i/ C6 _<hr>
8 }$ e4 h, ?7 a/ I. E<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
2 ^+ ~( m4 M; G4 f: [+ J<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>
9 q: Y, H% d) |3 H* ~# J7 m <span class="kw6">data</span> dataset;<br>/ m' Q1 ?% r, D: S, ^
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>9 R4 L1 b3 [3 S
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
) K9 f. _% `* e* _' ] name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
* M/ |& o0 z! J! C <span class="kw6">run</span>;<br>
; d' Z( o0 w! D7 N4 n; K4 V<br>" X2 E- g* w: X" P
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>4 L6 y e: k2 M* t) W+ p, w( v* t: e
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>2 y/ S. Y' G; j4 Z5 D" `
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
# u: z% `# q, T F3 p<br>
/ W& c& i, U. g/ p9 d <span class="kw6">data</span> meta_table;<br>
$ m" g3 j3 z$ V; o H condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
+ T+ a1 {+ g6 }" V& X, K( g9 ` condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
- B) L" h( L) Q8 i condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
9 A8 y! r+ m; C5 k! D- u <span class="kw6">run</span>;<br>
9 U4 g2 G+ r+ A: r8 S0 }<br>/ T0 p1 r) O# G- n0 E8 B
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
2 _( P* D: {! E% z <span class="kw2">%global</span> names_agg; <br>
* B$ K! x5 \- I <span class="kw2">%let</span> names_agg = ; <br>
) H8 Y' l$ h9 o* @; s5 f <span class="re1">proc sql</span> noprint;<br>
1 s, D& Z1 O. p$ ?4 s <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>1 M0 `2 I( H' ^- j
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>9 x: u7 p4 z, l) c4 x/ s- {
<span class="kw6">quit</span>;<br>
$ H8 N6 T& h2 l9 i' R2 n <span class="kw2">%mend</span>;<br>
x& q! b& K$ f t5 v3 ^1 _<br>
! J- l% }2 `1 ~" | w %<span class="coMULTI">*-- just checking --*;</span><br>
$ S9 _/ H2 q7 \; @+ 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>3 k( R: z- }, _) @* E7 w7 ]
%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>
8 ?' U; z3 Z* D; y %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
5 }0 M* o5 N- u- [; T, |8 H6 E %<span class="coMULTI">*-- on log<br>
s6 \9 O" r5 L5 I names_agg=a_agg c_agg<br>6 V. W( l# `1 ~$ y0 j: x( \- o
names_agg=<br>" I4 ~, K" n/ x; J, w
names_agg=b_agg<br>2 \6 q) d3 [4 d& h) [0 a# M
--*;</span><br>1 g3 I9 i; `% a8 k
<br>
- K: [2 X W# i <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
& ?+ ]& E3 g6 @- z+ S <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>( U3 V0 ^% s1 V4 B) W Y: l
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
- t# s7 V0 s/ u; R( x <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>2 y; _" Z. f" F' s3 ?7 I* l
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
) e$ P' w! O9 K/ n <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>+ |5 \" n5 {0 S# T+ ~! d9 m- V
<span class="kw6">run</span>;<br>
3 d' z! Z! \4 L! Y- j <span class="kw2">%end</span>;<br>/ j. O/ o) ?- M, v/ u9 m- n
<span class="kw2">%mend</span>;<br>' w" ? ^4 U0 T+ E3 p6 @2 @
<br>; J5 v0 J1 G m3 v, Z
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>9 `2 U( [ f, r7 \- A d
<span class="kw3">length</span> code $200;<br>
' l* V# C5 p6 X8 C3 H, @$ ~5 x/ e <span class="kw4">set</span> meta_table;<br>
3 D! _0 G* e" J9 h- b code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>) S$ s5 p7 b) Z, X
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>) E& Y1 m1 U4 }. K
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
+ v% d! @& m& x! T; b <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>) P$ L# l6 G3 }8 }0 W. H8 s
<span class="kw6">run</span>;<br>5 o% u" w0 x' D! E8 J/ Y
<br>& m5 f# V+ c9 D1 p! l8 ^/ ~
<span class="coMULTI">/* check */</span><br>
8 H* Q2 b3 X5 T6 A; ]; v6 ` <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>
+ w6 H( r. I6 m5 f H <span class="coMULTI">/* on lst<br>$ [( Y* W5 Z6 |9 \3 Q
ot1<br>+ _! D' X2 j# `3 k( n
Obs v<br>( l/ q u# Z+ A$ h" K2 d) ?5 ?
1 a_agg<br># F! t% [ `. [8 b' b" n
2 c_agg<br>: H }6 \* o; r' L0 d2 m
*/</span><br>+ T" Y Y2 W4 R! i% [8 b9 T
<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>
. R" ]) @6 h! T: F+ @1 @& Z <span class="coMULTI">/* on log<br>
6 ?, q3 }1 B, @; H6 e5 d# E+ S4 _) P NOTE: No variables in data set WORK.OT2.<br>& ?) W2 i/ x) Y
*/</span><br>
$ E' f: o/ h+ L e6 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>
6 Y! p/ Y4 H, G! M <span class="coMULTI">/* on lst<br>
Y: C1 R! w; v; ]; K- j ot_<br>: S% U7 L; z) ~/ U
Obs v<br>4 W f1 E4 b5 S' d5 F. m
1 b_agg<br>
5 | ]' l' w% q9 C3 `& w3 K& ^0 H */</span></div></td></tr></tbody></table></div>3 `) m4 x1 D {$ T$ R' x" D
<hr>3 n1 o. N/ i4 G/ [! z0 Y% ^- L& X
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>' c" i4 e9 S- c8 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></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>4 }$ \" |) [7 ^' p2 I
<span class="kw3">length</span> code $32767;<br>
' k7 l% S: u4 [7 M <span class="kw4">set</span> meta_table;<br>7 u! n' Q4 P% j
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>$ G) [1 C5 A. a) c; _
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
9 A& V9 ]# d* H9 u<span class="kw6">run</span>;</div></td></tr></tbody></table></div>' z& {2 _7 U6 W) f! @7 \( Z. R
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
& q; s! u) B2 ~0 v( O<hr>7 j8 l \) y U3 m( N; x F
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
$ ^6 |& I6 W: H0 Q, f# ?# ?<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>
: ?8 y! d7 k! i' J; D3 l <span class="re1">proc sql</span> noprint;<br>
! x' I0 c# f/ p U& U <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
; m" S" ]. y* G) Z <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
& t3 T- K) V" I& Q <span class="kw4">from</span> dataset<br>
6 S$ u6 o4 |" ^! h/ i <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
: S4 m* b* {" } <span class="kw6">quit</span>;<br>+ D) w, M) g$ R1 M/ \
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>9 P: S; _* ?! K b$ W
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
) u# \, o. `8 P- T+ [ <span class="kw6">run</span>;<br>: ]- }- u4 l; p. y3 ?
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>. Z; d' n# c7 m
<p></p><center> <script src="/c2.js"></script></center><p></p>1 z6 J( a/ I+ `. O) S* @$ X c
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
/ N2 G% s- T2 {<ul>
3 }* E, P$ S. u% [<li>4 s+ b b% v# T# I; z
在调用执行方法之外按顺序运行宏?
. b( E! V4 e& E</li>
* x9 H- L& v7 x- T<li>- k6 |1 ~0 q$ ]9 D8 {- [
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
8 `( U7 b$ X& d2 o9 w- A9 z% ~</li>
- t8 r" W$ r# z9 b" a7 Y) z<li>
- B* R: |" k1 M- |% `在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?5 ^+ l1 R" r5 n! v7 d
</li>" M$ F1 c: z9 S/ U
</ul>* h$ G! G- v5 S' H$ X6 m
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>* _9 ?& U* G( i8 I6 t9 m5 f
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>$ I( }0 s1 O' I& s
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>- ~7 @& E8 A" d Q2 q% r' j* k
<div class="suo-content"><div style="text-align: right;">
& f( V7 N' ^4 G4 q6 h. i$ b d2 ] <div class="xControl"><i class="fa fa-caret-right"></i>! M3 c v1 e [. H9 N; S' i
<span class="xTitle"></span>- n9 M! f$ ~2 \$ L$ v
相关讨论; j8 [4 r+ O4 C$ w9 X
<div style="clear: both;"></div>8 v6 d H2 o3 e1 d
</div>! u4 M6 y3 X7 u# V! V) Y" p
<div class="xContent" style="display: none;"><p></p>+ R% G- _# Y% Q' @* s
<ul>. Q+ E1 _$ w2 I6 A
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
' Y8 i) E- S# g0 X& e</ul>
4 h: M/ M: _9 R' y<p></p></div>7 t" G0 y! H1 d( c. p1 j
</div><p></p></div>6 Y; u7 m2 E0 X5 h7 o
<hr></div> |
|