|
<h2>Macro variables issue when using call execute</h2>
1 ]( n3 O! z4 y: ?2 q/ e% x<div id="fc">4 Z4 M9 k% t3 W9 g% Z( T
<p></p><center> <script src="/c1.js"></script></center><p></p>
8 [* ?* A. [. f! i<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p># L9 b' z2 v/ a- j" P6 i
<p>macro %TWO 需要全局变量</p>
3 V2 |8 a. ^3 |( H, H/ a3 K7 S" o0 N<hr>
1 Z5 X& }5 F5 Y, S2 I4 B<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>8 ?# ^* w: u( X: a$ D+ 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>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>, i5 u* N$ W' M: Q9 ^: U+ V9 G
<span class="kw6">data</span> dataset;<br>( P4 {# \8 b0 h
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>* l) N! g$ Q6 Q' W! s
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>/ H- U& F7 p# ]4 {8 k
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
% ]2 [9 h& h, Y1 P; n: f: ] <span class="kw6">run</span>;<br>6 `" K: ^. u: l. K0 j y; p
<br>
- m' S9 \/ A/ k5 J2 f" [! @; S <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
t2 l+ ~! ~# D+ E* M! l% ?0 M# c <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>7 B9 F( L7 F7 v. v- B r
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>( `' H$ K" U) W+ t
<br>
$ X( V4 M: V$ t* g% T* J+ c! Z1 ^ <span class="kw6">data</span> meta_table;<br>) }9 k$ u- A# h
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>; g* k9 w; t! Y9 }
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>! \8 x7 b$ w8 i" X/ f: P5 j' W, _
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>! A' J6 T2 d9 n( \. N6 J
<span class="kw6">run</span>;<br>& c4 C% W2 k ]% ~$ A
<br>0 G( E1 r$ R0 X8 p `
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
/ s z g: Q4 w4 z% k <span class="kw2">%global</span> names_agg; <br># j `- z5 c% o* ]$ Z
<span class="kw2">%let</span> names_agg = ; <br>/ z: \9 a6 H9 t; r1 q3 B n4 `
<span class="re1">proc sql</span> noprint;<br>
0 N0 T: X) x* r( |6 |7 |1 ~0 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>
1 `8 x; B2 U/ y8 n3 D- _% }9 G4 k( E) H9 h <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
1 x- H" R: M4 W/ `3 N <span class="kw6">quit</span>;<br>" { B7 H" R2 s6 R
<span class="kw2">%mend</span>;<br>9 b0 |$ |/ r& S* L# Q; E
<br>1 V! [( t' o7 A# e4 O8 ~5 J
%<span class="coMULTI">*-- just checking --*;</span><br>" f0 n! m& D" V) N% P! U1 D
%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>
$ s$ g# |/ t$ E0 ` %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>* v7 ~ `4 F) V' S
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
) r8 x: P+ |$ x) D: U %<span class="coMULTI">*-- on log<br>
/ Z3 r2 r5 D3 l: C names_agg=a_agg c_agg<br>
% G; F3 i' k: \7 S* F names_agg=<br>3 {# v8 K8 X2 {$ P
names_agg=b_agg<br>
% c! d0 b# {' ?' F6 ?2 p5 m --*;</span><br>+ m8 V% x1 |7 B6 `1 n7 R
<br>
) [9 c1 U* [6 u( ~+ ` <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>- P8 \$ S$ h+ g! ?( q& }
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>6 ~3 Q: D( E% a. x: |3 y5 k5 u
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>6 V1 y# X% g* H
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>: f' q3 D& b; R( a3 o) _3 `& _# R
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
5 ]8 [+ q* r g# v; F7 Q <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>$ v$ ^* j0 s7 C0 Q! G( x2 K
<span class="kw6">run</span>;<br>
& }) j. m# L. G! J# a8 D <span class="kw2">%end</span>;<br>
8 L/ p5 h9 _* e9 r' A <span class="kw2">%mend</span>;<br>
3 }9 O. r) n; Z# I- L! s<br>* B$ N# l* Q T7 _( A# b& L
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>+ t$ Q5 d3 b/ X) N
<span class="kw3">length</span> code $200;<br>
* e {1 T7 Y* J& C3 }$ `" i. R4 ? <span class="kw4">set</span> meta_table;<br>
/ o! I+ D; Y8 m+ Q) L code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
& P4 Y5 |3 L9 o code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>8 C! T1 G! B1 O
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>3 F* g$ S F, s
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
3 b7 n0 V9 \) t9 d- L: f* Y <span class="kw6">run</span>;<br>
% S! V3 Z, w4 i. z1 u5 x X<br>$ z% V! Y L+ [; @! B1 v, m
<span class="coMULTI">/* check */</span><br>5 y+ ~6 L6 h# H4 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>
3 w. k, \6 V; l& V m- w5 M <span class="coMULTI">/* on lst<br>/ C/ ~$ N. m T& b) p+ f
ot1<br>7 U }3 t+ Q4 N- G
Obs v<br>" Z9 U& S3 |. I1 w+ a9 M# Z) d
1 a_agg<br>
0 u! j9 C% C/ ^9 `0 @& d 2 c_agg<br>, b& y1 t, ?1 L1 M f. q6 A9 I
*/</span><br>
' A& b K' s0 R7 m: Z- f1 u <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>* U* q0 p: B( Z* V
<span class="coMULTI">/* on log<br>
7 b7 V5 V0 Q# o) v- z NOTE: No variables in data set WORK.OT2.<br>
! K. B9 x1 L- `8 ]% Q6 n, e */</span><br>4 {6 g/ H* X( O! @- n$ e7 T6 \* w
<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>( |) f- }1 z2 U4 ^5 W0 Y2 G( {4 Q
<span class="coMULTI">/* on lst<br>! J4 Z8 f7 X, P9 [1 z
ot_<br>1 I6 g. F# h2 e6 a
Obs v<br>
. P+ e9 [9 o. Z9 Z 1 b_agg<br>
- l% f9 `, `( l( v# D* o3 |3 M- K) C: @3 d */</span></div></td></tr></tbody></table></div>
, U; F8 }5 q+ A5 ~; f2 q5 F<hr>; R* i/ _& q9 C' |/ ~( A
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>' g9 G9 t' x4 ~. X, i
<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>& w5 E: h# n5 i( t+ D L
<span class="kw3">length</span> code $32767;<br>) Z2 c% }: l* W& O$ p3 K
<span class="kw4">set</span> meta_table;<br>/ }6 X; J/ \4 Z6 r% ^. b. e( T
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>
1 W6 F! B- M- R& { <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>0 x" _$ k# c- Q1 B- s/ G
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>' |' h5 ?8 F; u; {; f* M
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
' S) c7 T1 @% |# g/ T3 n9 u<hr>+ }( y/ i5 U, V; e0 h( L I
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>0 w% c8 g* H6 R0 L& C
<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>
7 e4 Q- M N, m- U <span class="re1">proc sql</span> noprint;<br>
! r4 o! p& ^- F1 a- G3 D" A <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
, k5 k1 D3 L% j0 A; H <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>9 @1 i8 D% t/ _$ M& `# l7 m
<span class="kw4">from</span> dataset<br> h+ G* w8 U6 _ L8 m$ O$ r1 U9 q
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
5 g i O$ {3 i/ X; p' Y1 Y <span class="kw6">quit</span>;<br>
w! G: E4 }1 b! l; v7 B1 d <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>7 ]3 b9 z0 e4 n- Q% z3 Q! U% U
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
8 }% K7 J8 f+ g/ J5 G. J9 h, H( l' n <span class="kw6">run</span>;<br>9 c0 i6 l% U8 t: Y0 O
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
1 o9 ^+ s! i- k" Y<p></p><center> <script src="/c2.js"></script></center><p></p>& u! r: H x' `, w0 K
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
, M" m& [ ^$ n% i) }* M0 r<ul># ^- j) X8 H2 u8 k
<li>5 N& A! m0 s" _
在调用执行方法之外按顺序运行宏?' y" \ _- K: A# z: }% D
</li>/ J" v0 |# N; D& S# \' V
<li>
6 ^% L$ k$ N+ i; x在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?3 B0 Y8 j( h8 l6 J
</li>
7 N; F! a) }9 v3 o+ |" j<li>- ]( A6 c5 |5 m# R
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
: Z# w6 O% I, a6 {9 l</li>4 ^1 c2 s5 N8 D% i3 n
</ul>8 g8 m" m1 e. X: a+ }+ g: z+ ~
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
5 }5 U, T. x' m- M6 K8 Y4 H) _2 q<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
: `' }5 n. U+ o/ _+ {<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
Y4 i; d5 e4 d5 I( C<div class="suo-content"><div style="text-align: right;">& H3 a9 s- D. ~" |; r
<div class="xControl"><i class="fa fa-caret-right"></i>8 t. F2 E, z7 H3 G9 [- {
<span class="xTitle"></span>9 v; ]+ s7 Y- K' q: q
相关讨论! l( |- [7 @& @' c7 v" u( W
<div style="clear: both;"></div>$ t/ v) }: n6 E) u4 m8 @
</div>7 u) G, }+ }. u& A R- m
<div class="xContent" style="display: none;"><p></p>
& b+ R3 J- U- M# Q6 i<ul>
' m0 {! [/ d2 i7 P9 r0 j! G<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>- @ Y" v1 u, O9 z$ |( ~# A: X' f( T
</ul>
% N5 S. O; j' }/ u# y2 ^<p></p></div>
$ V1 I3 v4 }0 R5 l </div><p></p></div>
: r9 S+ x/ k4 F' B4 J$ S$ C3 a<hr></div> |
|