|
|
<h2>Macro variables issue when using call execute</h2>
- h7 ]# \0 X4 N' `/ X, R% ^<div id="fc">
: y7 @; | }$ w4 t# m" Z<p></p><center> <script src="/c1.js"></script></center><p></p>
2 B1 X$ F4 x8 i* ?* Q# H8 n2 ^<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>( Q" v; ~; |6 C3 k1 N
<p>macro %TWO 需要全局变量</p>, p- C: \( P* \5 H$ U
<hr>& Y; Z- U/ N& ^! R1 ?8 o
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
" G. r. V4 H0 A3 ^<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>
$ ^- x( i$ }6 J <span class="kw6">data</span> dataset;<br>4 }: s% B# L- E, Y
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>+ p7 |; x$ A* W0 ~
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br># o% W; b9 ]9 x2 S# u( f
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
" C m/ P4 y+ P# o8 E) y7 t <span class="kw6">run</span>;<br>; R5 X8 i4 y% Y$ G. H7 F+ W# y$ Y' ?
<br>
- e; p* j: u" M% q% e2 B <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>9 o E7 T4 u4 M! C9 j" J/ m
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
6 w* \2 I* N% ]" d" r2 ~( i, ~1 k <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
" [& Z X! T) O f9 A& m: k! q) d<br>
7 k/ P* Q+ e! i, W <span class="kw6">data</span> meta_table;<br>
1 C( ?- | V+ P condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>% e* v. U, J8 E) g# W' @
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>6 F! w$ w' G" b, I Q/ d
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>' l3 ~3 R5 j% ~* y
<span class="kw6">run</span>;<br>9 N1 V8 E/ p+ { L; h8 w
<br>. z5 @! b( R4 ?9 Z
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
! t# y1 L _: w9 B4 @ <span class="kw2">%global</span> names_agg; <br>
) Z1 v$ {' q0 y' c <span class="kw2">%let</span> names_agg = ; <br>
% {9 B5 [! i+ t l. g+ U <span class="re1">proc sql</span> noprint;<br>1 m! h6 U4 ^. r( P. I
<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>2 h4 B" Y- t) C
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
4 O* x4 p9 u, m <span class="kw6">quit</span>;<br>7 O3 G! k, g* c1 p
<span class="kw2">%mend</span>;<br>
+ a" U/ X3 H/ h/ U% ]' E<br>
! s6 o7 q3 X8 n. H1 L %<span class="coMULTI">*-- just checking --*;</span><br> T g% ]: |* q) P# F
%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+ a6 A9 F1 Q+ B9 D4 i# Y" {
%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>! G6 }! {2 f) U6 T! q7 j; s& I
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
! J' Z V1 j% D; |+ N1 A5 S %<span class="coMULTI">*-- on log<br>
( y8 {: x6 P# P2 N! j' b: } names_agg=a_agg c_agg<br> h& L1 g! F, [8 A7 D
names_agg=<br>2 e& N, h+ j, B- P. U3 m
names_agg=b_agg<br>
. s1 M2 w, j9 r& l --*;</span><br>) T, T/ y, ~, }( d
<br>
, ~6 G5 W% M# j. L <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>2 d9 u8 c6 T d- U) @
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
, L; t9 Y6 R% x+ w <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br># E' Y9 [8 e$ H0 N
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>% ?: t. h8 P' M0 ^& ^
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
J$ `* Y1 |9 m/ N" Z, G <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
D: b, p, U6 \7 ~1 E L' d2 q <span class="kw6">run</span>;<br>7 f i5 F6 s% m5 ?+ \5 K6 X. W9 U
<span class="kw2">%end</span>;<br>
+ I$ w6 @! M, e2 R <span class="kw2">%mend</span>;<br>' j+ A4 S; O( n! b0 ]2 F
<br>
- l3 A, @5 U, X; } <span class="kw6">data</span> <span class="kw1">_null_</span>;<br># l- k/ ~8 H; l
<span class="kw3">length</span> code $200;<br>0 M% w. p; _8 S% X3 ^
<span class="kw4">set</span> meta_table;<br>
: q q% F$ {3 O _% Y code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>3 c& R& W0 }% I1 V, A4 Q
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
" O/ N8 c) }. I2 B, e P code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
9 A/ }% l9 t: Q) W3 b <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
9 J" @. l6 Z, B* c. E2 | <span class="kw6">run</span>;<br>7 S' s- A) G. d# |( I
<br>, Y& S# Y9 O8 C! E5 f8 K- V! t
<span class="coMULTI">/* check */</span><br>
( `# w7 G+ d% t" b4 T <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>
! A i4 S+ M5 t$ g! h <span class="coMULTI">/* on lst<br>0 U( K* M" A/ W1 a9 Y5 M9 y9 W/ p
ot1<br>4 T7 h4 N! s1 i% R7 u# r n
Obs v<br>
: U* J( d2 F* ^3 S0 v' n2 A* F1 y/ U 1 a_agg<br>
2 K( U: Q% f3 Z# h 2 c_agg<br>5 ^6 y9 `/ C% ^& J2 z1 }- ?
*/</span><br>+ H. | e0 b9 B0 Z
<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>
5 O3 }4 [# [: d: D* u2 _ <span class="coMULTI">/* on log<br>
% N/ V$ j+ x+ y- t! S. V NOTE: No variables in data set WORK.OT2.<br>! o$ [$ h: N6 |$ _6 x0 |. F
*/</span><br>
* a4 {+ M( m! i <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>
3 s0 b: |# e2 d' x' V <span class="coMULTI">/* on lst<br>
; q8 _+ o& T9 R# w( i' K4 E ot_<br>/ j- K' C4 j2 C) O" g% y: N
Obs v<br>
' s5 f& \/ J- C* L" w 1 b_agg<br>
: Y3 [* z% X8 ?+ \$ k */</span></div></td></tr></tbody></table></div>* T/ f5 b4 ^3 d$ P) j
<hr>
9 P6 B2 L3 v5 g# Y# |+ `6 }<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
* r/ s& e( S& ~1 V( K, p. x<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>
& Q2 H- V' U7 O% B8 _ <span class="kw3">length</span> code $32767;<br>
2 {3 O! S8 q" q8 `1 G$ ~5 ? <span class="kw4">set</span> meta_table;<br>0 i; Y5 [* F3 O* K, o1 L* l
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>5 t4 {% N3 K% X2 m, a& E4 C/ |
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>6 O5 |% R5 {2 f5 C
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
2 P# B9 l( M. Q7 I q. O7 b<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>! a' d$ x' s W' \3 M
<hr>9 E% f/ R( h9 t& i
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>' c$ V; s p# l- F* ]$ 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>
& I! O u5 s, O: B3 m <span class="re1">proc sql</span> noprint;<br>0 m8 `1 A* f3 I9 c
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>& c3 U/ z4 o7 t: D( W! c
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>9 k; P; S# { W K N
<span class="kw4">from</span> dataset<br>
! ~. z8 l8 q) Z9 I0 U: w: F9 F <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>4 k: ?7 Y! E# j8 X! x7 [0 z# Z% y
<span class="kw6">quit</span>;<br>5 [% }3 F" S1 `$ {; E o
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>% M# D! w) ?$ }0 H0 [5 C
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
6 Z- C/ j$ [0 c, @$ g( _# N3 ] <span class="kw6">run</span>;<br>0 B: F; Z% r/ Z1 W
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
2 | j5 c* v- v<p></p><center> <script src="/c2.js"></script></center><p></p>- k S: b3 Q5 p1 ]2 y0 S! C1 { s
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
: c. c; b% ]: `( M! l<ul>
" ?9 G7 ]4 o. M& [2 l- @4 g+ D4 q- F# i7 p<li>( o( Z. z8 N8 M9 i' y* S) @
在调用执行方法之外按顺序运行宏?
- V) S3 n0 g2 w, M) r</li>
& T% c/ u6 Y" d<li>
3 @ m* A' Q0 f+ b! _: b [在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?: ^$ t3 h! ~, m' {
</li>; n/ Y& X$ q3 o# j- |8 R; @( L2 s0 g) w
<li>5 P5 ~3 c z( a1 i* T) g
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?& h' d- m2 P1 D
</li>
. G7 d, W) I4 K/ ^: d/ V) I</ul>
+ G1 H& L! l7 P* g<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>) W# M1 t- {- C; e, S% q4 w
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>2 f+ w& r6 g% p4 u. r
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>% J+ N) J0 O* M# s
<div class="suo-content"><div style="text-align: right;">
8 y: i" R( ?. u5 B# ` <div class="xControl"><i class="fa fa-caret-right"></i>( f0 O0 e: ~' y Z5 C; ~
<span class="xTitle"></span>
5 N, c! ^% V- w% } 相关讨论
0 X1 o1 F: q0 z+ _; R/ ?" W2 P# E <div style="clear: both;"></div>0 G9 f. F* b( y4 c% }/ T
</div>& P- g$ O* x& K; t1 d3 m; H
<div class="xContent" style="display: none;"><p></p>- R* l0 H, n3 S) T2 s; t" E
<ul>0 Y% y R( g5 ~% U8 \% E4 l
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>+ I/ _1 z* V9 B2 I+ @0 m
</ul>9 g4 _" {8 e( \8 @- s: U7 o
<p></p></div>5 c* G0 l9 J0 k
</div><p></p></div>0 y( F0 ~0 `! m/ c4 ~
<hr></div> |
|