|
<h2>Macro variables issue when using call execute</h2>1 m4 }1 g" [8 V! ^ d0 }
<div id="fc">2 v' A3 r( [# P7 H& S9 U2 X+ c
<p></p><center> <script src="/c1.js"></script></center><p></p>
7 u/ m" O# [9 [+ O u<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>' o. e* Y) z1 D% ?) x
<p>macro %TWO 需要全局变量</p>! R# c8 F5 x, V* E( {5 }' m% ?
<hr>! N/ c/ c, j Q8 k- N& }* p
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
8 U/ n* M4 X2 c; g3 Y/ x. o9 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>& T/ h3 f. j; @: r% ?5 T
<span class="kw6">data</span> dataset;<br>2 w& U0 V3 b' M& I
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
$ _/ n, r! D# T! q name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
* n0 C6 v- Q& Q0 n8 S6 s+ ^ name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>4 d, R5 B( c1 V2 I* @0 n
<span class="kw6">run</span>;<br>
) r5 I* R$ q. p9 Y<br>; s$ m1 e( e0 j- |3 ~
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
( @/ T1 m2 `0 X- b+ p% W* C <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
7 Q$ j S. I8 @" Y <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br> W0 G, V4 k, I1 i
<br>
3 N. y. c0 ^: z9 @: K <span class="kw6">data</span> meta_table;<br>6 E* B% M* Q X' Z
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>4 c. y9 p6 m, d- l5 x
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>" S5 R& ], P7 @) K- s
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>8 M5 C. k) m# i8 K
<span class="kw6">run</span>;<br>( k2 k3 O" K* f
<br>
" g* D' c# W3 {- H: X! d! N <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
% b; }" M4 w5 h! H <span class="kw2">%global</span> names_agg; <br>* _. Y8 O' }$ H
<span class="kw2">%let</span> names_agg = ; <br># ? j. V4 X/ N
<span class="re1">proc sql</span> noprint;<br># y# y; j5 p6 K
<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>) J; o& K5 G8 m3 t; |$ R( |- r
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>' \( J L% C% ^2 p' {8 s" m+ L7 ]
<span class="kw6">quit</span>;<br>
3 |4 g5 c' |- s <span class="kw2">%mend</span>;<br>% _% F' G7 ?8 B% l) ]7 e m& Y
<br>
; }9 _' w E+ l+ e8 f6 Q %<span class="coMULTI">*-- just checking --*;</span><br>1 I- k- u1 y0 B: C9 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>
; Z' ~+ p% [; b" B- Z/ } %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>' C/ [4 k `1 s, u- H) d
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
6 [, ~# z( a- ?) K %<span class="coMULTI">*-- on log<br>/ u; ~' W2 ~7 ^ ?2 G
names_agg=a_agg c_agg<br>$ q5 ?$ V9 V2 Y( g4 g7 w6 @
names_agg=<br>- j7 N: v4 M9 ~- j# b; k& r
names_agg=b_agg<br>$ d- c- h# C9 O/ C7 W
--*;</span><br>
3 R! v q) g8 N8 W4 u5 g R<br>/ r" p% `; E* W8 z% `! N
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br> X; H2 @7 M% o( D
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>0 I( S' h) E4 Y4 |+ O* `; N& Y5 G
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
+ `: ]$ c& P- V <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
, l1 z0 |0 }. m <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>5 p8 f/ e5 I' A
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>/ e z1 ~9 }8 \) N% G+ B \
<span class="kw6">run</span>;<br>* J) e8 g/ ~5 S* S0 U
<span class="kw2">%end</span>;<br>+ b2 S0 C- f$ Q
<span class="kw2">%mend</span>;<br>9 \ G( n% Y2 S7 N0 ?
<br>
/ r5 T4 X! X3 e0 e5 @' r <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>) A; c j8 h5 g3 U' v: L
<span class="kw3">length</span> code $200;<br>
4 l# c! ~( x+ d4 b2 `$ M <span class="kw4">set</span> meta_table;<br># m4 u! d% X. r3 B7 \0 A6 i, J7 |
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
: Y! h: ^- Y g' O! Z code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
5 L% G( q# X8 M6 D& X- z) C3 C8 I- z code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
' `7 L- C1 S2 I' ^, D9 Y( B5 k <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
! U$ L+ J6 R4 T! { <span class="kw6">run</span>;<br>) ]5 W8 u+ Q' K+ |$ r" Y! Q! J
<br> c g$ T i% |: J D: V! I
<span class="coMULTI">/* check */</span><br>
& n* x6 q/ B# B8 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>, k, ?- ^3 Z- d. y1 j3 `
<span class="coMULTI">/* on lst<br>
^+ K/ _* |4 m, \% t; c0 h ot1<br>. D* I- W6 q4 D! T" M ]$ v
Obs v<br>
m& y$ r. w: _/ Y# ? 1 a_agg<br>
% a1 o! F' |0 o, X+ Y0 D 2 c_agg<br>, Q* r) r% O; u
*/</span><br>- p2 Z4 ?$ [, M/ `
<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>8 {7 U, M. O" j
<span class="coMULTI">/* on log<br>8 ^. \, v: B0 g% i0 O& i
NOTE: No variables in data set WORK.OT2.<br>1 P1 l, }% ^$ L/ w6 A
*/</span><br>
8 X' t) O, s2 m <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>
2 s9 @* b! B+ J2 o <span class="coMULTI">/* on lst<br>
' ~8 F- }- G% J* g ot_<br>$ ]: M/ A! @4 f+ {9 C/ W
Obs v<br>
- w: o9 w4 K; H/ \! s V( x" { 1 b_agg<br>
6 j% t) l" o! y* ]2 D! N q */</span></div></td></tr></tbody></table></div>
+ z+ e0 z( q6 e2 F/ r! L0 V<hr>
7 O! y% P- F4 C1 S2 g; Y" P. B<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>+ t: }" C& x6 ?4 S; 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>) X4 t2 p; @% ?" o, `! H. W% g' \
<span class="kw3">length</span> code $32767;<br>8 I! O8 _: l5 Y
<span class="kw4">set</span> meta_table;<br>, {8 Z+ j4 [2 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>3 m5 A2 R H- v( X
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
- A1 _" Q6 r4 X8 p: X- Q<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
: U0 a2 L; J0 r- i% }" f<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>- [. U' y6 L0 k1 b$ f: o) D Q7 R
<hr>& \* ?0 k+ P2 o q( N7 Z
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>& y" A+ S2 J4 i9 M
<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>0 i2 n$ D; c/ p' z5 b
<span class="re1">proc sql</span> noprint;<br>
% {/ j5 w1 T1 c9 `5 A <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
# t: F7 _$ w5 Q! s& v1 H' ?/ Q: l <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>4 q& s" B' \- c" N6 G5 P
<span class="kw4">from</span> dataset<br>6 K3 I+ Z( y5 G A2 W. c4 Y* Q9 K y
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br># z& o ~3 i0 ^) e
<span class="kw6">quit</span>;<br>
: i8 J: s$ \0 u# H <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>
" H4 a) T7 a! F: z! z <span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>3 w; D3 r- @0 `/ l# K: `
<span class="kw6">run</span>;<br>
5 C6 p2 f1 t* m+ R<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
5 q: R/ [" B: K<p></p><center> <script src="/c2.js"></script></center><p></p>
& j9 C) b6 `$ ^+ d0 l( g. s# B3 o$ y<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
8 c* l8 a$ q5 s6 B* j$ c9 a; K3 ~2 o<ul>
2 a4 b& }9 Q$ Q( @( M* v5 I<li>
2 Y: }6 P0 I: x! h在调用执行方法之外按顺序运行宏?; S$ o% o Z" O0 J7 M4 r
</li>& |9 a# K. T; S; M
<li>8 l5 o! w: h! g2 S( g3 s
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?; J+ z+ U. a# C; x* t8 b
</li>
: |% c2 m b: L% W( [% \<li>, }, y ^- F" I# C+ E
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?9 n( Q- K7 b+ W
</li>. c1 v3 G- D+ N
</ul>
r( _4 U9 t( D% `5 c& A3 O<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
, x* Y1 B$ h3 s/ y<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
0 j0 n0 ]# i3 C" `$ N$ B1 Q# N<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>5 w1 \) G8 n% @% K" G) e9 p( G4 W& k
<div class="suo-content"><div style="text-align: right;">' n- [5 B5 q+ l* C! M8 W9 U
<div class="xControl"><i class="fa fa-caret-right"></i>
( i4 @8 z- o* i/ z$ S <span class="xTitle"></span>; }+ _! W' l% e) E+ V
相关讨论 |" q- G( R9 X
<div style="clear: both;"></div>( w0 O% S9 v& U8 n4 T* }) N, t% E
</div># `' v8 w( J" M9 ~( W" X
<div class="xContent" style="display: none;"><p></p>0 o: @2 Z: R' K/ Z: `- I
<ul>
6 ^1 W) m- X% @9 X1 P) E/ \! H<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>) h% u, _( \+ i9 W* S
</ul>
) z1 {& L8 o! }% y( e! q8 e<p></p></div>
' ?8 j9 d/ U9 M; @" d </div><p></p></div>+ W; C$ h' g* G
<hr></div> |
|