飞雪团队

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

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

[复制链接]

9321

主题

9409

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
30293
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>: W! E9 v, e3 X1 \
<div id="fc">0 Z& }) x9 {0 Y5 B
<p></p><center> <script src="/c1.js"></script></center><p></p>
$ G6 a- F7 [  v% C7 u<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>4 {- T1 n1 K/ i% ^0 b: b/ l
<p>macro %TWO 需要全局变量</p>
3 K1 Y" l# F! n<hr>
4 M( p: a: j( B( v" `: x  f<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
. l7 M1 d9 C7 f$ [* 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>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>
2 G, E2 I5 d7 w% c&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
! t6 T, {! N; N- z&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
% \1 p8 C: t* E&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
7 j2 L' t! D% {/ ~& F&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
2 y# e+ y/ U3 C! x/ W+ t$ y* N&nbsp; &nbsp;<span class="kw6">run</span>;<br>: y0 y8 z5 |+ f8 r
<br>
8 ^5 \% B: S  L5 d. _&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
) @  b  H' U6 O4 ]&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
* o* m( v6 E& X8 O&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>7 q' Q, ?1 R8 i+ M3 w
<br>+ R5 b. x$ \& n$ i# {" F6 J( c% o
&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
8 ^8 q3 {7 `! l5 e% H&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>$ W- @* A) M4 `
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>7 ?' }1 o4 d' Y+ ?# \" \' K
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
) }6 |% P% ~, M6 M4 n% e&nbsp; &nbsp;<span class="kw6">run</span>;<br>; m- a" [+ i* v9 P8 ?! m- s
<br>
& K' c* m' R% a0 u&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
  f& |: L8 T; a' y2 a  N3 V&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
  Z  \: o2 C: `8 y" ^&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
9 L, h- H5 N; O9 h7 @&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>
4 Y, i# ^# @  L6 S2 \6 ~&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>! Z% b9 L  k& h) g; @# G% [! ?
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>
+ U$ T# E/ m2 g&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>
1 p( J' d6 K5 ]; J&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>! o% y5 `4 i7 A/ f1 p  u
<br>
5 J' j7 q+ x: E6 M7 T( M" E$ `# x&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>
6 f" r0 B& V* m&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>
- Y0 }+ j  _+ m, ]6 V: p&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>6 |( C% E5 n, E+ G
&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># v; i0 N6 Z9 x5 |# x
&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
5 v: L  E, r: J; ~- p! G; I&nbsp; &nbsp;names_agg=a_agg c_agg<br>
' `$ k* |1 ?1 S  s) |&nbsp; &nbsp;names_agg=<br>
1 I1 I  l5 i7 i$ U: U6 H&nbsp; &nbsp;names_agg=b_agg<br>2 e# f+ \" v0 Q" G. ^% f7 h
&nbsp; &nbsp;--*;</span><br>/ _" ?) H/ `& u  g) M. }
<br>  K4 k0 L# Y; j1 m  S/ N
&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
, V- u' @' l+ @4 U' m&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>
' s! b4 ~; F7 o&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>
) N5 C+ _: r( A&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
. N8 h$ C6 B* @2 B' f3 W( b2 k&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
( Y8 U) t$ }7 B' ^8 T+ I&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>
# E: B9 A4 I; V' t1 I&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>1 G) K. ^3 G6 Z2 \7 k3 T+ w& }
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
. A' k& m, I3 a) X&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
! @( S4 N. r" `<br>4 _$ q$ Z! s* D! p
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
! e4 x, U3 T6 C0 u9 y" A) T7 K' x. `&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
! K# v% H* y8 \3 U! S3 w, R) X&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>. Y4 q  C) H# i& U1 C& B! g
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
, {6 O/ }  F: z&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>
5 R7 F. L( U% }5 R) B; |& Q' ]% G&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>  j* B" Q4 ?0 J4 \7 r
&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
* t+ u( G: h: O, h0 X; P3 W% G&nbsp; &nbsp;<span class="kw6">run</span>;<br>
3 z8 M' a5 I$ G8 [/ T; J. i<br>+ N* T  y5 T8 x5 o9 t
&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>0 n+ `3 W7 O9 l7 Z' u% r) b; j2 ?, v
&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>
- Z* w& u) a' i$ D& w) S&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
$ }: z( Q; R' X; }2 d4 O&nbsp; &nbsp;ot1<br>
- r: z! q3 Q' U# I! S&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
5 `: g" H/ H+ c# c' D" n, x: c( \&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>' o" g( E* B+ v
&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>8 T/ @, _+ m2 x2 ?7 \3 w* {, p
&nbsp; &nbsp;*/</span><br>
* X. A! y0 l  ]1 g4 b* P0 Z&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>, i) b$ V" `2 d. v
&nbsp; &nbsp;<span class="coMULTI">/* on log<br>
5 ~" ?: ?  D* e. g1 Q* F5 v&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
# H  q: S. M  @% Q( m( u/ t8 ^" R&nbsp; &nbsp;*/</span><br>* N4 I, A. H4 j
&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>- m1 ]. o; x0 ~9 J/ G
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
$ v0 }5 x# H6 k, U: ~3 S+ |&nbsp; &nbsp;ot_<br>
' V. r6 v" n! d7 e7 l&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
) g! T9 F1 i( c* r* V&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>
8 X* T5 z9 j" X' y&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>
; u( E9 c2 L2 ?2 V<hr>4 `3 M: E. ^/ M
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
- ?4 q  x$ O  B& 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></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>; h' T/ V+ N* E( n+ F
&nbsp; <span class="kw3">length</span> code $32767;<br>
0 Y4 `$ H: y% A! N7 n7 S7 Y&nbsp; <span class="kw4">set</span> meta_table;<br>
& @& W7 B  i' K" b&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>
' z8 g% T$ j* W* _  {5 W/ E&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
4 g6 O* i1 j, N& x$ I3 m' y<span class="kw6">run</span>;</div></td></tr></tbody></table></div>, I" V, ~1 K  i7 y  P
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>% p! _/ o1 H, w0 E9 M! `( k
<hr>
0 V6 f" G! |$ C5 x3 S: B; W<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>0 y" F( \! P! A
<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>
  e3 h" B4 I# W&nbsp; <span class="re1">proc sql</span> noprint;<br>
1 V$ d( i% [& j" \( u" L&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>3 L8 Y9 E+ G9 a6 q3 k7 I/ \
&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
, X  _) W5 j, O4 H4 S6 P/ \8 w% {+ I& d* X&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>. ~6 S: W8 ~8 A
&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>" x) O8 x4 _$ u2 G. T
&nbsp; <span class="kw6">quit</span>;<br>
, \8 a* E1 ?  e! o3 E0 R&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>. P6 ?/ c# Q2 E0 k- E& ]  U
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>
* q' k; e: Y2 e, `) ^&nbsp; <span class="kw6">run</span>;<br>' P+ O2 ^4 a) A$ T& x% v1 ^2 \8 v. P  q
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>9 f" p+ S/ s  G! e' p
<p></p><center> <script src="/c2.js"></script></center><p></p>; |1 v/ k* G! y- z( W  U
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>( a9 {' Z' V: s* q
<ul>
7 d* v. a1 h* y& \$ |/ e/ e<li>
# J7 f+ _0 L! E( O' L: j9 \在调用执行方法之外按顺序运行宏?
3 ?1 s1 ~0 P9 V</li>
9 |7 T5 I4 ^% l) x' \) j<li>3 M" a/ p3 e1 H4 ?& G
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
+ n4 ~  x) ]0 C1 C. @</li>
5 H0 F0 {4 w; f# E  T; ?<li>; t9 X4 D6 X  j2 w( o8 Q0 Y( r( S6 j
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?+ u; i* e4 f: L" ]
</li>- X, W3 J4 W' ~; B7 L
</ul>. V8 z; U0 y" V0 \" ^/ {- R. S7 K
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
8 c+ r) I/ b6 o; [; M# B+ k<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>. V0 T8 B  P  N4 M* K
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
1 t7 a. P9 ~+ ?5 B1 O<div class="suo-content"><div style="text-align: right;">% {; q/ q" w6 ^
                <div class="xControl"><i class="fa fa-caret-right"></i>6 M# W0 j) }2 @- ^0 S
                        <span class="xTitle"></span>4 k' p7 m- p3 C9 T
                        相关讨论
( C' Z2 v5 {3 M# R2 z                        <div style="clear: both;"></div>
; d3 D5 z1 l  X& A# Z                </div>7 c8 ]/ ?  X, [
                <div class="xContent" style="display: none;"><p></p>
. @, b8 ~# U* s4 g3 x! y<ul>  U' Z1 L/ |0 u! J  u$ E
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
* K5 E6 Q! f0 ^0 X8 [0 x7 G. j</ul>
3 c! e6 v6 `7 {; V0 }+ H<p></p></div>
3 R3 C, J4 p. W) o- ?  O  H) d        </div><p></p></div>
" e1 m; j9 D9 a# Q2 T& c) Z<hr></div>
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-11-5 14:51 , Processed in 0.069577 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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