|
|
<h2>Macro variables issue when using call execute</h2>4 m5 ]/ a$ |3 `7 d& I
<div id="fc">( B, {. ?. t7 ]) m, r
<p></p><center> <script src="/c1.js"></script></center><p></p>7 L8 |" Y4 c; [/ J# z8 f0 B
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
8 |9 g" Y: [( [<p>macro %TWO 需要全局变量</p>
+ l* }* E" i9 G4 R& M. h+ m$ L% P4 m<hr>) R H% h1 g: m9 Y3 T( Q3 \7 d
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>& [6 [) E" }) E0 q+ R1 n
<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>
) J8 C- B$ I8 z* p+ \: i$ ]2 O <span class="kw6">data</span> dataset;<br>
* W0 U/ y& m) b/ D$ p name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
- j% B/ P- I* |& X; I name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
6 ]( E X9 _/ z; x3 Z. B1 r name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
, v9 X) \9 p* I" @" z6 y+ k <span class="kw6">run</span>;<br>
' |0 Y6 X& S( w1 R1 p. _$ A( N<br>
- o" E" E7 F+ Y: m! Q <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>- g) n$ Q: }/ Y9 O, [
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br># u4 L: n5 `* \1 t: q
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
3 W+ G3 F! J5 w) j<br>
, c" D% h" X8 z, L7 n <span class="kw6">data</span> meta_table;<br>+ p3 t! {) \8 j& c; C, m
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
7 J0 f6 c1 \/ |2 G* N condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
% y. K, U( H9 \ condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>+ t5 D+ Y! \) P8 E3 V
<span class="kw6">run</span>;<br>8 h5 H9 c2 M/ ^$ j1 q! k
<br>
3 }8 P* {5 p$ e f <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
8 |) p6 P Y' o: u <span class="kw2">%global</span> names_agg; <br># T6 y8 b& d7 L/ N6 Y& u
<span class="kw2">%let</span> names_agg = ; <br>! C" N- w! G3 ~% V4 q" h0 M
<span class="re1">proc sql</span> noprint;<br>, V, r& b" j5 o
<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>$ I, I. c# h8 H* m) k
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>. b5 K. `# y3 L: [. e5 d
<span class="kw6">quit</span>;<br> T! p* u9 H) c S
<span class="kw2">%mend</span>;<br>
& [8 k3 d9 u; u( U3 g. r<br>0 q! A/ E6 U+ Q7 c
%<span class="coMULTI">*-- just checking --*;</span><br>
@! ^; a4 h% D$ N+ X# J# H %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>! w$ u0 ]; L7 h* W; K
%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>
" j! D8 i( G( y: ?: w: e4 F %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
0 s8 d/ e. W' U3 Q %<span class="coMULTI">*-- on log<br>: G# m0 s( Z0 e
names_agg=a_agg c_agg<br>) s2 b c( h. O: F
names_agg=<br>
& p& ~: ?* Y; t names_agg=b_agg<br>
# n; {" z( ?8 M& R9 a --*;</span><br>4 U. q! W: P- G9 ^0 X5 S- }
<br>
2 \1 k. M4 K- r2 [" w8 b" g <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
( `* M( F. M# H* l, s- e <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
) t6 G1 N! I( I" K& _: k8 X <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>8 S$ \6 m0 u4 V% A! F6 ]$ `
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
: |0 z: z' _6 z0 b( R' l <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
6 E+ K& m4 S" \8 M- D- n+ [/ H7 o <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
( m# z0 n- H! [. k <span class="kw6">run</span>;<br>+ q& \: H, ^; [
<span class="kw2">%end</span>;<br>: O! R4 ]/ W, \* m" V5 X. G2 i( s
<span class="kw2">%mend</span>;<br>
: z/ f2 Y2 `$ z* I; @. S* m<br>
, m r2 C5 {8 ^4 T: Z$ V4 ^ <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>7 h' v7 ]+ @/ V1 j! u1 y% q3 }" b
<span class="kw3">length</span> code $200;<br>
5 I6 P0 m) C+ |) {3 D# p B <span class="kw4">set</span> meta_table;<br>7 g3 Y5 l' D/ U* v1 u
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
9 k" X# ]/ j3 H' s' t+ ? code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
. D$ l$ M4 Q y M% V code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>! p3 F% i E9 d& h7 I* q5 j9 R( ]* d
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>2 S! i- Z+ H4 @
<span class="kw6">run</span>;<br>3 P! y$ W% w' v
<br>
9 |7 K* z9 S# Q( x2 }0 G# ] <span class="coMULTI">/* check */</span><br>( z' p- \. R# p3 `
<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>, x$ u) k( b: `
<span class="coMULTI">/* on lst<br>+ J/ \! h) H' f) b9 o* Q4 J
ot1<br>' T6 {# t) T' H# G* t* i
Obs v<br>1 f9 V; s7 \2 o* s
1 a_agg<br> S6 N3 e3 B, M" Z' q/ S: A! J
2 c_agg<br>
% K2 {. ]8 E" i: Q" F- E& h# I0 e */</span><br>
- P4 p. K7 P! J9 l <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>
. i$ s* ?+ I% ]; n- W* ` <span class="coMULTI">/* on log<br>
. X: c3 {/ D0 t NOTE: No variables in data set WORK.OT2.<br>
6 N {; e0 |! m8 j */</span><br>
$ f | \& r4 H X4 m8 @- g' ` <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>
[& d" H" O1 F <span class="coMULTI">/* on lst<br>2 m5 i1 Q* y' r1 ~
ot_<br>
$ d$ j1 _* Y* }5 h Obs v<br>4 U+ X2 S9 Q3 I) R
1 b_agg<br>
6 w, W: f6 L2 Y# E- G$ c5 i */</span></div></td></tr></tbody></table></div>
5 ]+ y3 a" v. C) r* [# W5 k, k2 P<hr>
; _ L" t% J8 ~<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>: _. ]) i# v& R) F+ }5 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></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
2 T2 K3 v8 [4 D* e, { <span class="kw3">length</span> code $32767;<br>
) y/ _0 v" ?5 z, ?7 Q% w5 U( j <span class="kw4">set</span> meta_table;<br>
: v& R- F: ?7 _# M 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>- c* O, t0 B- e3 L$ g) B' X0 Y+ j
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
6 D2 s: n/ W6 F2 y% G% t<span class="kw6">run</span>;</div></td></tr></tbody></table></div>) z( ]" d5 V6 z u* u3 P! U
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>$ o, P- M8 X5 }( x4 d D; f) A
<hr>/ b5 X" d6 P1 c+ g/ [; e
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>; V" R* F$ ?& M5 Q; N- F+ ^0 L
<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>/ M, A9 k3 J7 ? X* G
<span class="re1">proc sql</span> noprint;<br>
+ p) L& G( G- m+ ` <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>% @) ]8 `7 ]& I
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
- }8 w2 N ]2 q <span class="kw4">from</span> dataset<br>1 k$ }/ X# |7 o6 N5 y# U* d
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>. y5 Z, X7 _9 @4 V
<span class="kw6">quit</span>;<br>
* G/ G% U5 I4 u/ m! Q8 x9 y <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>, G3 _6 {! ]* c' J( `
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>% @7 {, I2 J" h' m* T X) w/ @4 _0 k
<span class="kw6">run</span>;<br>
& B1 x$ @9 Z0 e& j* ]4 x<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>: h: e* z6 B9 D3 b
<p></p><center> <script src="/c2.js"></script></center><p></p># Y2 O4 U+ G8 r2 Y2 ?7 Y4 N
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
4 F4 T. W+ t& a9 F6 @<ul>* U3 F0 R. K; G# P
<li>0 L1 S( \& j5 g( k% L7 ~& U5 d
在调用执行方法之外按顺序运行宏?
, y4 A) Z4 R" P8 B- P! E: w</li>
2 k7 T$ ^6 T. e( A<li>
+ ~ p5 }8 v3 u# T在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
$ w, }% t- {- g! G7 A* N N4 l</li>
" @ Z% B. ~& Y+ @ h8 K4 z: T<li>
& X9 N, a5 N& o( q. \在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?7 ^: I' ?6 `4 o4 k
</li>: r' ~8 g5 T6 D. ?( S g8 \0 k
</ul>
1 S& H" ?- H( ^5 w" N8 h<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>) `7 [4 S- L A
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>$ l1 B/ H5 k/ g4 c
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>3 w, ]. M# x8 [: ^: g! N9 F
<div class="suo-content"><div style="text-align: right;">
+ b$ ], w$ ^0 A( v <div class="xControl"><i class="fa fa-caret-right"></i>: S# p& o( R1 G9 k3 s" F" g; R
<span class="xTitle"></span>
# Y. z s: d$ u 相关讨论6 v" t% v5 Q' a, u4 U) p \# H% w
<div style="clear: both;"></div>1 c, N) o( x- R
</div>
( l9 r( x' z% \0 }, c <div class="xContent" style="display: none;"><p></p>
! y0 U; O B: }7 A) V) V5 k<ul>% Z. s' h2 F5 f: _( S0 Z
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>8 ~# A+ a/ Z& j+ A
</ul>- ^- I- `3 M, D1 M' L4 e* o: g! d
<p></p></div>
5 P, }7 \! _% c </div><p></p></div>
9 w i4 K' i: {2 q( _, o<hr></div> |
|