飞雪团队

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 9931|回复: 0

关于sas:使用调用执行时的宏变量问题

[复制链接]

8292

主题

8380

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
27206
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>
% m9 I1 @3 Z$ j0 |; }<div id="fc">8 O8 G  c6 ]$ J! o0 d0 v7 d9 |
<p></p><center> <script src="/c1.js"></script></center><p></p>
& a  M1 T/ X. g* V<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>5 J8 ]" F9 T" ?# L5 A
<p>macro %TWO 需要全局变量</p>, |4 o$ w/ S; N3 S9 u/ }
<hr>" T6 \& X3 P0 w( Y0 W! x) b* C
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>. c# F2 H6 I6 K6 c7 O$ J  C; u8 m1 g
<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">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>6 R$ x" x1 c# V
&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
" k: q: _" Z9 r&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>% x3 m, e# _7 g
&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>. K/ l0 C6 k, u: U
&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>/ \0 i( B- }( t: o
&nbsp; &nbsp;<span class="kw6">run</span>;<br>1 h6 ?6 ]0 [5 _" \
<br>
" p1 u: X. q. o" ^# }5 A  ]) ~&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
+ f; _! t8 u' u) m&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
' q) D4 b( I" O# t&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
3 R7 H3 s0 V% l& R% {<br>- o0 q) ~9 r& J( l- D4 C( ~' n+ _
&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
- i5 j4 H. }9 [# {; C8 b1 d" e&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
5 {1 m9 g0 `6 O/ s$ j( s&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>+ f3 E3 v" T4 e% K! y) w9 \
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
- c5 h0 [% @* X7 N0 U  c&nbsp; &nbsp;<span class="kw6">run</span>;<br>
1 y" F2 O$ H7 l% z2 [- A<br>- L  b" [! Y# T0 P# w% Q( l" f! h$ D- F
&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>5 u7 k- M& M" h; ^' G
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
) e' O. l1 ^( |. `&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>- ~8 ~+ I& y- l6 U  i
&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>% g1 C8 ], |$ q5 @5 T3 H' X8 |6 N$ p
&nbsp; &nbsp; &nbsp; &nbsp;<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>
/ Y  |, K% Q9 x8 S8 T! e&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>. _* a' v* _. Y/ u+ B/ v# Y
&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>6 S9 `2 z  {1 U- O9 D% I
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>$ C  X& H+ l0 l/ ^) |  ]! T
<br># r* J3 K; s; X1 J
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>3 C2 h# S; q& x. V
&nbsp; &nbsp;%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">&amp;names_agg</span>;<br>4 s& u8 ^& c+ h$ s! J3 f" d
&nbsp; &nbsp;%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">&amp;names_agg</span>;<br>' y; j4 {* U+ n; Y1 ?+ C8 x% i/ P
&nbsp; &nbsp;%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>6 D4 ?* O$ W, t! x
&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
9 d: Y) m) g6 V$ b&nbsp; &nbsp;names_agg=a_agg c_agg<br>/ \$ Q2 y7 N& @. p; D" ^* g
&nbsp; &nbsp;names_agg=<br>
: K3 s7 c4 N6 d&nbsp; &nbsp;names_agg=b_agg<br>% f: q8 ?& d" K! a1 L1 J
&nbsp; &nbsp;--*;</span><br>+ K7 h6 Z3 ~/ ]# I
<br>, \  m- u" X' l
&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>/ y/ c" n& v7 k2 [* Q; N# X
&nbsp; &nbsp; &nbsp;<span class="kw2">%if</span> <span class="re0">&amp;names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>7 l' ^$ o8 P, I- k& P
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>6 t/ `% B: N1 [% z  @$ k
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>+ J3 Z5 r, r0 ^$ j# ^- i" }' g4 F. \
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
* g. P* w7 `) S) A&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>7 J$ Y/ p$ R+ `8 a6 W  \/ {
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br># ~% y; _5 l+ T- q! M: n
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
* g- M' \# [9 ^' R) s&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>5 M/ B! h! H' p: P7 M7 m* A+ r
<br>+ O4 ]6 t; R3 r& B  p+ \
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
' [5 E2 k/ F) z/ z&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br># V5 K9 s1 I0 [6 m' V  H
&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
3 Y5 A2 U$ y3 Y3 ]&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
4 u" {. |' n/ S/ f$ B2 ?; `! @&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
. y. c2 H8 x8 r% c' H) ?6 e8 O&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>" P9 f6 [3 l5 D$ Q" Q
&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
, W' K- a/ I4 O&nbsp; &nbsp;<span class="kw6">run</span>;<br>8 h7 A1 s2 _: Y$ o" x/ v2 G
<br>* h! S7 i9 L! g& }3 ?$ D0 p1 K! b
&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>
$ X% B) V2 D% s+ k  k; a  c&nbsp; &nbsp;<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>" q( p# f$ m0 l# k+ G7 d0 N
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
7 c. c& G) Z* Y( n  M7 {&nbsp; &nbsp;ot1<br>
: f9 j) P0 H' F6 e% b# B; t2 v: `* w&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
! Q" M0 o4 V* s&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
6 y; ?* |0 }7 `&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>! G9 u+ p$ N" X: e) G2 X0 d
&nbsp; &nbsp;*/</span><br>
2 D/ x; G& [5 R% |; }&nbsp; &nbsp;<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>
: U$ V7 H# F1 ~$ h&nbsp; &nbsp;<span class="coMULTI">/* on log<br>, o3 H+ z( R: i/ {+ D: p
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
, o: {2 ]1 P; O; ^5 Y; l&nbsp; &nbsp;*/</span><br>
3 K! b) p2 ]5 k. {. [/ d' `&nbsp; &nbsp;<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>, Y( @9 P) Q! {4 W, J
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
4 i& s( J6 T" t' _" t: O1 I' T&nbsp; &nbsp;ot_<br>
+ G9 ?. z. \( B8 I&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>; N/ h% j1 O+ B# ]8 i7 p: u
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>1 f5 O) @2 \$ b* ]4 j
&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>+ k9 i8 d  |3 p* ]7 z' R! ~0 g
<hr>, p, Z9 V& h' D. E$ s
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
9 _8 a. \5 g3 ?' z) }<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>
9 O  y8 p3 ~2 p( Y# i6 h&nbsp; <span class="kw3">length</span> code $32767;<br>. g  _2 W: n0 D7 E8 I, X
&nbsp; <span class="kw4">set</span> meta_table;<br>% u9 S5 e! {) Y3 P
&nbsp; 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>. e2 P$ P2 H  h* [
&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
' b+ v  y1 l0 @- v<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
0 K. s, X; M) H: _+ H<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>( m) `# i2 o# O! j4 u! X! y
<hr>
4 {. ^/ b1 l2 Z5 q. F  E% s; D<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>- Q& |, E6 t. m7 l0 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></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>, Y! ]0 q6 ^8 |
&nbsp; <span class="re1">proc sql</span> noprint;<br>/ k1 k' D2 t* g1 p6 {
&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
/ [8 o# ?9 b# |5 P- s( ]9 x&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>5 e% N% i0 Z* o8 w0 ~; S' }2 F! c
&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
1 @% U/ M# X/ }' o/ T&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>
8 f1 `+ ^; I4 a0 a3 U! ]; x&nbsp; <span class="kw6">quit</span>;<br>9 H3 G! _4 o( m
&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>
" J. B! L4 ~8 V& c1 p' x&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>& _( y4 _% u( ^/ |  z" N
&nbsp; <span class="kw6">run</span>;<br>4 E$ r3 t. ]2 S
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>- C- S) D$ E) Y1 u( S3 z9 i1 ]6 a; R
<p></p><center> <script src="/c2.js"></script></center><p></p>7 j7 m! z" P7 j1 G* o( ?( d
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>$ a0 Y8 o+ ]$ G) H
<ul>8 D+ o* r4 a: C$ x  W! K
<li>
; y2 E. [. m# h* q+ h/ a( F% ~; r在调用执行方法之外按顺序运行宏?
3 S. k' `% `$ S8 E2 b# Y5 ~</li>/ V1 J8 G& z+ b% f1 B) o. M
<li>
" O, u$ g6 b% }在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
3 r6 R, N2 _( s; ^! `</li>
6 ]5 Q6 [; a# o2 {5 p<li>
! i6 u/ \: l" P% R在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
; q" J4 i( B" _9 }2 e: t7 {( Y1 u</li>$ \6 M) B1 ~/ B0 O# I4 a5 p0 C
</ul>+ a4 @' l6 r1 |7 X
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
: Z' i$ E+ q3 w8 y9 k" S9 b<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
; `4 l8 i) a8 H* R: I<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>, @  {$ G/ ~1 G- d$ @9 u
<div class="suo-content"><div style="text-align: right;">$ Y3 z5 F* N9 M; e# I
                <div class="xControl"><i class="fa fa-caret-right"></i>
5 H! d# v7 }9 A! ^1 _# T" K3 O7 Q2 S. Y                        <span class="xTitle"></span>
7 w' U/ d/ c: \9 q                        相关讨论
" S+ \/ J/ l" P/ l& f9 \1 e                        <div style="clear: both;"></div>2 F3 h7 C; E, u! O  X. S7 w7 a
                </div>
/ R9 `& E/ x2 @8 D; z, p, L                <div class="xContent" style="display: none;"><p></p>
8 E% ~% P7 A0 E# u/ P, j* b<ul>
% F" u7 O9 g& v& a' C' J<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
$ P/ ]% s; H* N) e1 P</ul>
0 v3 g( N" j2 Y  f( s! H8 o! Y<p></p></div>% i" Z& i/ _0 x) D$ H8 ]
        </div><p></p></div>" L5 P6 P. t1 N1 U- n9 p
<hr></div>
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|飞雪团队

GMT+8, 2026-2-28 14:41 , Processed in 0.602977 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表