|
|
<h2>Macro variables issue when using call execute</h2>6 P: t/ G2 n$ R/ L$ x
<div id="fc">
, `( ?% ~- \) U }+ H<p></p><center> <script src="/c1.js"></script></center><p></p>
8 Z9 M2 H% X, A2 a<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
0 ]" A% g2 ?% u" J<p>macro %TWO 需要全局变量</p>1 J0 a- [. e# L, d
<hr>
( {- q8 F7 V- J1 O% N+ b, m4 t<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
8 S( e, j2 K9 S<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>
" e0 p9 M$ ~6 |2 i5 | <span class="kw6">data</span> dataset;<br>
; X& x4 K3 S" \4 P% Q name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br> H! G. c: d: p- L7 g/ z
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>: ]* o# W K" z: \: K
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>( ~7 C; \( O$ i6 {
<span class="kw6">run</span>;<br>& v* ~6 ?% v3 @$ h: i. X
<br>
+ Q+ m2 A8 }6 [0 S( J <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>: W5 p" T+ Q+ j
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br># Z* \1 B2 G$ d- ?: ^4 n, v
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
7 t. d9 P* a0 P0 G<br>' A K5 T" }2 }* p
<span class="kw6">data</span> meta_table;<br>
( E# f! ^/ m: G& M) |" w condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>/ H8 b3 d2 ]4 s" }4 s) ]
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
. ]2 Y; T4 a" O condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
1 F* @; i. i c8 [) E <span class="kw6">run</span>;<br>
$ `- Z6 @, ]) R, ^/ ]1 F<br>2 Q, O- n% i( T: I$ h
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br># Q8 V8 U9 A! x0 C2 m( T
<span class="kw2">%global</span> names_agg; <br>
* |$ d( H' U8 w4 X% S2 J <span class="kw2">%let</span> names_agg = ; <br>
! [8 M' O' h/ _- T <span class="re1">proc sql</span> noprint;<br>% d9 v% _' q) c1 x6 ^" \: K# h
<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 V6 ?4 W' @3 Z* X
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
' @$ a/ J% S! r9 S, N <span class="kw6">quit</span>;<br>! l8 x8 `- s L+ e8 n5 X
<span class="kw2">%mend</span>;<br>5 O; l9 H* d$ b: z" |3 `( m4 u
<br>' T) P( n" H+ K4 q7 b; ]& Q. g2 j+ j
%<span class="coMULTI">*-- just checking --*;</span><br>% x- B$ `# s5 z# j
%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>( }, V3 A' d8 G0 {( C. F
%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>
9 p4 e7 n0 R2 }1 ~ %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 L3 F$ ]' [5 }$ P. }
%<span class="coMULTI">*-- on log<br>
/ @/ d7 h- ^. L8 U0 n* q names_agg=a_agg c_agg<br>7 k+ c4 {4 U- L$ z
names_agg=<br>
0 V* X" R8 a7 ?7 t! x* b names_agg=b_agg<br>2 t1 U) u+ P; Y8 V; T6 [! R+ C0 Y# J
--*;</span><br>! X0 d( W- [7 H. ?
<br>
5 z0 b- }& c& L# X <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>, [6 {% E/ c5 m; |5 F A4 l
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>. I# k% y! Z1 H9 y. s/ O5 G k- v, k
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>" z4 o }- d& V3 r7 |: J0 ~' D
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
) a3 S5 c7 s$ T! m9 z3 ^ <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>$ H& F! Z+ ^6 N
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
% @6 k, P) }8 m Y& x$ P <span class="kw6">run</span>;<br>
$ z7 W& N6 d1 B9 S3 k, Y( \ <span class="kw2">%end</span>;<br>/ M a4 z- r8 ]3 `; z
<span class="kw2">%mend</span>;<br>1 V0 X" Z' x9 d( h5 Q
<br>+ Z2 I5 N* }3 M
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
/ }/ h+ E3 d$ X4 Y z: ^; ?& ? <span class="kw3">length</span> code $200;<br>% S9 ? Z8 o3 E# t* o: m9 X i& U
<span class="kw4">set</span> meta_table;<br>
, N+ N0 R+ b0 f. ^& e" R/ m3 h code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
) _! f; [# `, Q* z; D code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>) G! c" q3 l6 n1 n/ i: q! f: h
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
& w6 X3 ?2 [" p; Q. d <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>6 ~1 M `4 V/ M
<span class="kw6">run</span>;<br>0 f4 @" L! F8 O- e4 ~) O
<br>+ V* T y$ f$ l6 q1 }/ [+ h
<span class="coMULTI">/* check */</span><br>8 F6 o/ l" ?) E1 p
<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>
5 ~% E$ }2 ^7 ?% H% x/ B" [ <span class="coMULTI">/* on lst<br>- q, f9 ]& S& [- k* _3 p; m
ot1<br>1 P8 m7 c& L% X k* Z; A$ d" F
Obs v<br>
3 b5 {. I U* f+ J4 S% } 1 a_agg<br>" k- x, c6 N& e5 Y/ g" z
2 c_agg<br>
0 Q5 t3 q/ o! V3 t */</span><br>
3 ]" `7 q( M6 V# m" R <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>
% C8 S! _2 e7 g" f( C- p4 q <span class="coMULTI">/* on log<br>
1 o" x# D; S- l/ c$ w# G NOTE: No variables in data set WORK.OT2.<br>
# `; p2 ~; R0 ?1 W7 N */</span><br>
% d7 ]- x% ~5 |: X <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 f9 c/ \) a6 n% B- S! b
<span class="coMULTI">/* on lst<br>
" x! s- ? ~9 t ot_<br>! u0 I' z( x8 ?- V0 N: ]
Obs v<br>( D8 u. C3 U" e K2 A
1 b_agg<br>
9 O7 v9 l+ E% f& [$ l( q */</span></div></td></tr></tbody></table></div>
5 Q! u9 O, g/ u<hr>) Q9 P+ D: e1 g, K
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>/ {# ]2 P! Z% K, Q
<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>
/ v8 F# v- h% u <span class="kw3">length</span> code $32767;<br>
; d, b- s* C7 A2 S; ~ <span class="kw4">set</span> meta_table;<br>
: \" S6 `. a8 B3 e8 J* D6 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>
9 T7 m) Z6 \0 m: Z: Z1 {" N <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>5 J( A, l/ f$ D; U* {8 r, D
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
+ v: F7 g8 p1 M# W {6 R8 a# j<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
$ @4 h* X9 @/ h4 J2 X _$ E! q) K<hr>
& l4 x; p: t1 _: o# A<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>* i6 }0 `6 m5 u# p: q8 |
<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>; A4 f; N8 d, f3 I
<span class="re1">proc sql</span> noprint;<br>- O! j2 ~, O" b" O& j2 M" M: N* X
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>* F+ ]7 ~/ y" N$ s+ ?- e. D
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>; c0 l3 H, s) l7 ]& Y8 P4 _" X$ a
<span class="kw4">from</span> dataset<br>
0 R9 ]- }; j( ~4 @3 o <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br> t; q* W( S+ H/ j0 h$ J* j
<span class="kw6">quit</span>;<br>
, q2 _/ n* n4 A7 d2 J" i <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>9 T, x1 x6 ~/ f3 i
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>* N! C( H5 ~: q% _4 O; p, j
<span class="kw6">run</span>;<br>
/ d' d0 L' @9 c3 [6 v) E+ ~<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>3 B; V; o7 N( s O
<p></p><center> <script src="/c2.js"></script></center><p></p>
" g5 i# o" A6 N1 ]( f2 I6 q<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
7 |6 L5 h& R$ L<ul>2 q- b4 {% y0 l* I, h% v2 A
<li>& e' |) i- C n2 p
在调用执行方法之外按顺序运行宏?+ a3 n; z7 S9 l4 U; j( V( N- t* S
</li>- W! q0 b. v Z8 T& H3 m
<li>
6 d# Q8 h* ^* S; B) X9 F, e4 F在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?7 i. X6 d" a& s, k
</li>
$ V4 d# S7 a$ v+ r& G/ ]# m& I4 G<li>
* o+ l% R) L$ n3 h在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
6 M3 p- X8 e3 F! ?( U% L</li>& {! D- S9 t q% g( @% @- w& M
</ul>9 j& N1 X/ A) K: }
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
6 ]/ [; V2 s- E5 D) Z: |3 d<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>' v* K' O' h$ B" G
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>4 {9 c) C6 S' B! ]
<div class="suo-content"><div style="text-align: right;">
; m3 F) n' x5 ?: Q- z* ~ <div class="xControl"><i class="fa fa-caret-right"></i>
& j" S7 V1 y' l. h7 x: Y# Y <span class="xTitle"></span>5 r2 ~, s0 Y; |# c3 d
相关讨论0 t. U( [9 B; q# H6 W
<div style="clear: both;"></div>+ k- \( @$ u6 {1 ]' f, I4 r2 a; M
</div>% \ o# b7 j' v9 T: b! t
<div class="xContent" style="display: none;"><p></p>" f7 B _$ z3 i: [' W
<ul>, J+ u1 \1 u' {$ |) B7 T; n
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>% X' C6 i) Q& q/ v6 e" T$ v: w- |
</ul>* A0 x4 i3 I1 L# H& @% U) I8 w
<p></p></div>
4 Y0 X7 ?: a9 { </div><p></p></div>% c/ l* P( Z9 @
<hr></div> |
|