|
<h2>Macro variables issue when using call execute</h2>* C, k6 K* j4 @0 b k. t: ~
<div id="fc">
7 f' [) o7 r4 x. d<p></p><center> <script src="/c1.js"></script></center><p></p>
* J( j a. ?3 i2 w N& O<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
B: C( o& u0 g0 S$ ^; p<p>macro %TWO 需要全局变量</p>6 g# E' o6 }: K
<hr>
; e, p" n L8 W7 F$ j! T0 Y U+ P* t<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>5 S7 s; W; L: D
<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>
( k- g; i: i' d9 B( R* F. t <span class="kw6">data</span> dataset;<br>
' T8 F2 |" M% M, g- _9 W8 c( M5 E name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
1 d* W1 t# R8 w& u name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
, S2 m3 w H1 v3 c/ b name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>6 r A2 Y9 _) q- Q
<span class="kw6">run</span>;<br>: i( _& C, n, |. g& v3 }
<br>
$ |. U9 f: v$ I" i {9 b. C* j <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
8 x, t$ S5 M/ Y7 T T$ h <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
( h; N* U: m, V! w, U6 a <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
) o) i3 b/ i* q% ?8 B! E- c3 I<br>
2 |/ F" J- U5 D5 G% ` <span class="kw6">data</span> meta_table;<br>
& G. C+ H& A. Q* E condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>0 a# P$ n4 ~+ M+ M- O& q+ {
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>& `; D, H/ E( m: x- w
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
# c, ]9 R( n& ~- k: \ <span class="kw6">run</span>;<br>6 {/ _' q# I Z' T6 X6 {: q1 F
<br># Y: h, P* y! ?5 g
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
+ W8 d% c+ y# w) i$ c8 f+ x <span class="kw2">%global</span> names_agg; <br>
6 m# K% d$ [, t$ P <span class="kw2">%let</span> names_agg = ; <br>, n7 M+ U v( B
<span class="re1">proc sql</span> noprint;<br>/ B0 x p% P9 l7 n
<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>) c) Q4 B* [( K A8 d- M# O
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
( u2 v r' y5 ` <span class="kw6">quit</span>;<br>; C- ]; ]7 v$ Z# l+ ~4 _
<span class="kw2">%mend</span>;<br>3 g+ u2 x; \; b* R
<br>
7 L& E( ~# @( y9 Z %<span class="coMULTI">*-- just checking --*;</span><br>
, n% _: \" E" S' s$ Z# k8 [# b# p/ q %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>
1 E8 y: h6 E9 L %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>
1 x( R: V/ R2 Q [% B %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 K$ D% X- S5 I) \) U$ Y %<span class="coMULTI">*-- on log<br>* |& o+ w# I) g6 t9 l( C
names_agg=a_agg c_agg<br>4 z0 j5 v; a# p4 G# N7 D3 _9 `
names_agg=<br>
& W3 f! U+ j: T9 @ names_agg=b_agg<br>; G- |, R {) ^ v1 _3 K
--*;</span><br> ^' [# T- k& }
<br>+ t5 `0 O8 w" P. j# P4 N9 t5 L! n+ F
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
, T# z; W3 A: c2 L2 }9 s <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>. P+ f9 Y& ], ~2 d# e
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br> l% ]! P3 g- O) [" H& D
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
( p. l- `4 J9 ~! }+ d; m <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
3 ]: P7 b) \( ` <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
* {0 W3 R; L9 R& B" p <span class="kw6">run</span>;<br>" _7 [' T T7 m+ N% I
<span class="kw2">%end</span>;<br>
0 K4 z$ A! h7 c/ w1 A <span class="kw2">%mend</span>;<br>) d- g- ~" w! b6 r
<br>
8 @! k* ?7 i2 x/ @8 p2 P# ]" }) \ <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>$ Y, s W( |: z% J e! E$ ~7 O
<span class="kw3">length</span> code $200;<br>8 ?; x: V! o! B" ]
<span class="kw4">set</span> meta_table;<br>" q% Q3 G9 K7 K& s4 w
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
; @# D3 W* N7 [" s' V! ` code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>. F2 m, `; ^& X: f. X" v7 G/ |
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>0 D* w' A5 F, ~+ ]# u `7 k5 P
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
! }9 k8 I1 ^+ v3 o <span class="kw6">run</span>;<br>
- }! N$ H2 V: E, ?4 j8 T% R* [- o<br>0 Z$ N8 I# }5 W9 E Q
<span class="coMULTI">/* check */</span><br>
7 @2 F& N* m3 k. j, V+ 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- G! F, U4 u2 w+ W q3 N2 T
<span class="coMULTI">/* on lst<br>
3 X4 g. K) j4 C ot1<br>4 [1 @7 J& R% k! Y6 f2 i, K
Obs v<br>
0 F8 ~$ ~" F3 v& l& H' e1 k5 E, ? 1 a_agg<br>% Y0 ?3 }, }' z$ B
2 c_agg<br>
/ Y. _% P* R# r' V0 } */</span><br>
0 C# V& H5 }; ^) F' ^1 ] <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 }/ y; _" t9 X5 y( p <span class="coMULTI">/* on log<br>
) B: H" Z2 o2 G% J6 F NOTE: No variables in data set WORK.OT2.<br>
: `: b# M0 f2 h. j */</span><br>
s2 o4 |) e7 \ <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> J. @) @. {8 g+ }7 Z
<span class="coMULTI">/* on lst<br>
2 n K, G- C, G: ^. I% ? ot_<br>$ w7 m, g% Y- E) Z! K+ X( X( F
Obs v<br>
9 E8 N; Y% |3 m% c; N 1 b_agg<br>
* ]& V! w8 ]) L& l: j5 ]: L4 X */</span></div></td></tr></tbody></table></div>
: w0 M# A, j# E1 _7 C8 R9 I<hr>
, q- l" c( P( Z9 E<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
8 p6 g& h4 ]; s+ U( _<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>
( U1 o: ]9 O& Y& p <span class="kw3">length</span> code $32767;<br>: R- K/ ^1 g6 ^. [2 ?+ W
<span class="kw4">set</span> meta_table;<br>
5 Y* v+ D; }; d6 r! Z 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>
# Z* g7 C( z6 y/ w7 i+ \; I <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>. h, A5 C% v+ {1 S. ?4 v+ B
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
. V Z3 P) ?1 J6 ^+ F' ~, y<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>, h5 ], W1 a( U: C& ?
<hr>& h u3 h6 D$ X/ ]; x/ e' S
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
9 Q" s. w3 L; N/ |2 o3 u# X5 H<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>
& a3 i# f. {" F' ^; j <span class="re1">proc sql</span> noprint;<br>0 H' v2 J+ w: r1 U* l5 }
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>) V) E# {5 c8 h a' v
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>5 K8 @& y0 }( o, l9 I! k% a$ _7 N
<span class="kw4">from</span> dataset<br>
0 _$ d) O' ]& v1 S1 H! V6 x) L9 } D <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
# }$ U7 S% L5 K6 ]$ W* g <span class="kw6">quit</span>;<br>( w/ Y! B2 D9 a8 ~
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>/ M9 H& o# f. W" J1 m, {% y
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>. @; ?, `- I$ B( W: g4 f
<span class="kw6">run</span>;<br>; C4 u& U! O4 y5 x; D" n
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
( Q |5 K* {4 |- t% b( N<p></p><center> <script src="/c2.js"></script></center><p></p>
. y9 _. ?. @! e/ E2 F( I<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>; ^" [8 r5 Y! C
<ul>- M6 X* f* K4 q* u( B) s
<li>
- J( p* Z; u- S: |5 N. z: T; c! ~在调用执行方法之外按顺序运行宏?
' g8 z2 U" u+ w6 G9 X& }</li>
2 G* Z7 j" l9 _' @5 @<li>
1 H5 O3 c! F" T+ F. n在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?( F* h: ^! g' U. j. p
</li>
( B4 U. |% h9 k$ m) r& l. G<li>
, b6 e( s% T4 Y/ ^; [! \6 O在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
1 U! p1 O9 H- u- x! O0 r</li>
( m# y: `& I* |$ H* ^</ul>$ d' |# F" Y: a) c$ h# ~8 U5 l
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>, k0 l/ |! f3 ?/ d/ K8 T
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
/ h5 n7 J8 k( t3 W: ~7 A* U" J<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>) o+ h" I. c6 W# D$ X* `! f* R
<div class="suo-content"><div style="text-align: right;">! S+ N: I4 V5 {2 l& i/ R
<div class="xControl"><i class="fa fa-caret-right"></i>
+ I( D2 D, D! G, Y# K <span class="xTitle"></span>
& x7 J" @) s7 G! l 相关讨论' ~0 _/ q0 X' G& e' x$ x
<div style="clear: both;"></div>
& `# j- }% K) H+ o </div>+ ^0 n7 _8 _/ W1 X- X" {8 t: e
<div class="xContent" style="display: none;"><p></p>
) R( k( B. e4 ?0 ^<ul>
' U. u! y: s0 \, [' Z3 I<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
1 c/ K. c' e& Z% s; M" }9 r</ul>" g( N: C7 H7 d8 E2 \/ p, c A5 W; ]
<p></p></div>" F: D ~; l% a+ w% Z e1 n! }
</div><p></p></div>
. q2 u1 c0 U: K) B, M2 C" x<hr></div> |
|