飞雪团队

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

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

[复制链接]

8560

主题

8648

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
28010
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>
( z9 g3 l( ?! n& z1 a+ A- f<div id="fc">$ D8 _" s% N+ ~+ J0 Q
<p></p><center> <script src="/c1.js"></script></center><p></p>7 h  @& N' ?- K( V7 R1 o
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
7 O# i8 h6 y/ l1 p9 m<p>macro %TWO 需要全局变量</p>3 G( [3 N6 f! T: E6 w
<hr>! N" E0 l. D" y9 q6 Z
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
' K1 O. I5 c% 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>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>
% M7 T! R% Q" x9 n( h; K&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
1 A( ^9 |% k) a: f&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>8 n5 B  Q2 X- p1 T* i0 U
&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
+ r+ C4 A+ V( z- Y% ?- v&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
( U. M$ @2 {( {) y2 X2 U&nbsp; &nbsp;<span class="kw6">run</span>;<br>9 K5 T1 v' Z& f# d  [9 n# o6 b( Z
<br>
  ^( \. X3 c8 o  C* `&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>. x* V5 R" R8 o4 i
&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
4 V6 R* I: ]: R7 C&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>5 T6 Z+ J2 u* [, g% b4 [7 r; b  m
<br>7 B& y2 `  u! z/ H  V: O! ~, f
&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
# J' R" o9 {+ t5 f5 W&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>- M; Z( o( ^1 B) c9 A/ X
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
2 Q1 H4 y6 z. n' o' \/ X! L&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
0 u* p* ~5 V2 |( s&nbsp; &nbsp;<span class="kw6">run</span>;<br>& D5 @1 I0 o' A' U
<br>
$ f: p# k2 D% \& x! l1 N/ r&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
$ M! \5 c. x8 Q$ k5 q  e2 q) H&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>( m5 w, @- Z5 n$ a
&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>' j: w/ `" F1 m9 x" s0 v
&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>
1 x( k! |. z4 f3 h* t3 P) S7 @' O&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>
/ s0 [$ H3 V2 G$ @&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>' v+ J- G2 _+ z' w7 H# u( _
&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>, P5 Y2 R  N$ i* x/ `% D3 T9 d" x& O. i' O
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
. w; h% Q* A6 j+ ]<br>
( x. \& E$ @  J( `. l&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>1 N7 U7 o0 D5 |$ X
&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>6 j6 K, S9 m( p& d4 [6 N0 I
&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>
( X( a, p# P  x* U' s* I&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>2 U, `* C/ Z  ^+ x0 b0 k" s
&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>& B0 j) G5 D+ m6 h
&nbsp; &nbsp;names_agg=a_agg c_agg<br>
( L# e9 ^! f9 q. k+ d&nbsp; &nbsp;names_agg=<br>$ y( L; V8 _1 h# F: A+ U
&nbsp; &nbsp;names_agg=b_agg<br>
$ O/ J' s, C" `5 Z&nbsp; &nbsp;--*;</span><br>) o$ k* I& y) w" p% k8 S; W' Z9 n
<br>
' P" o& p2 @8 n, V, B&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>* n. [4 d; |& R4 i5 _
&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>
# _" V: q. x& k: i' b5 w- L7 k! K! ?5 \&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>! b$ G- y3 C( h: J* h2 K* Q- Y
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
# F- |. l1 x3 {7 |&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>( Q9 E4 w8 k+ l5 G: u. p
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>
( k4 d4 J- ?8 D  U! r  A3 Y&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>0 }# O3 S2 N& v5 u5 F/ O' N7 j) o
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>0 Q* _4 c9 p# q; ~
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
! j, C; f0 J  A) w$ {: }( e<br>1 p  b8 W; Z2 l& t8 b1 E
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
7 L( s* u& g. R; o&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
, d0 u: k  x# \' n8 h&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
6 U: h  ]/ F, M3 s. G" m9 P&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>) l2 S; O/ r/ C5 a
&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>
0 y, H* B) |& Q- H2 q0 ]&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
0 k' X0 `6 e' y- a  m&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
! H5 Z+ T, B8 ~" Y. \&nbsp; &nbsp;<span class="kw6">run</span>;<br>- F  `, N9 W/ D9 W: a
<br>
: G5 z0 I/ f* u1 q1 q) V4 T&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>
1 Z) W( T; e. C0 e' {&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>6 D6 a5 X) Q  n$ [
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>4 e. V* A- S1 l) [
&nbsp; &nbsp;ot1<br>' H' Z# S8 y# B* V
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
2 H( e3 ]# K, F&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>6 m6 n' G9 ^2 ]' D$ d; f' z
&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>
* A6 }. W) l( w5 `9 t6 c&nbsp; &nbsp;*/</span><br># E6 ~" v7 m7 ?* C6 M9 f
&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>
& C( E) s2 n5 e4 e0 N&nbsp; &nbsp;<span class="coMULTI">/* on log<br>3 v$ O6 r( \; e6 ^# C$ ^  i" I" s$ {
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
. v! X3 `8 O- `$ N7 s; l1 @+ ?&nbsp; &nbsp;*/</span><br>; p0 N* d; y+ `8 m
&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>% Q+ E& B# o+ v+ C9 x- |) w' A
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
7 v6 r1 w5 i9 C  i&nbsp; &nbsp;ot_<br>, h, k: u  [0 @( k
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br># I, a; F* f, P" A$ e
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>
0 l# V1 G1 C, {, t3 a' \&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>! A+ q  k, I3 k/ ]
<hr>
1 J) }/ `) ?  V1 Q3 l<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
7 U6 W6 \6 X9 v9 f<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>
1 E: e: ]: I! b1 }' m&nbsp; <span class="kw3">length</span> code $32767;<br>/ g/ w+ O' l0 P0 u: W0 L; J
&nbsp; <span class="kw4">set</span> meta_table;<br>) C$ }+ x' T: r8 J
&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>
. |# K/ c( @- E# N: N: H&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
) P+ c1 B# l- i  e4 t<span class="kw6">run</span>;</div></td></tr></tbody></table></div>) {' y  h1 v% Y2 s
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>$ O. J* L; e$ e* O8 ]9 m
<hr>
: `5 i/ T- F5 T( Q+ @<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
( `, N( `9 L; M" g; s9 z: T( O<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>. n- x2 b& u& [+ I2 ~( m; d( I- Y" h
&nbsp; <span class="re1">proc sql</span> noprint;<br>7 Q4 I4 o# y: F( e1 L. O5 J
&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>5 u1 k( s! }* a: x8 Y. T% S
&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>6 M4 ^* X4 j0 D" |
&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
; }& Y! z0 I  n) _0 r- r; s&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>
1 ]0 U& p3 J& f9 m; ~* y% w* |&nbsp; <span class="kw6">quit</span>;<br>
- j4 W3 d8 [* c&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>: \2 D4 u4 L! K" y
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>: K! j8 k" n3 j  |4 ?3 ^
&nbsp; <span class="kw6">run</span>;<br>
8 X! s, i5 N& O+ x/ }  `) r& F<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
3 T% d1 f' |9 _) f% D5 R<p></p><center> <script src="/c2.js"></script></center><p></p>8 Y3 o/ g. W6 f  {* h8 @5 C
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>: G# Q6 A) i$ k
<ul>5 j$ P" y/ [( e; C
<li>
* W" ~- E+ h2 R# a( t在调用执行方法之外按顺序运行宏?5 l, |# T( j3 h
</li>
8 X/ @1 {% ^6 e<li>
; O$ ~* }/ x5 [" x1 \8 ?在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?2 R7 i1 B! w* m7 \% w0 C
</li>; P% ?( {, S; ]4 P" p7 o
<li>
% }! S2 @; p7 D) D. s2 k+ o* }, W在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?3 P) j3 K" V, {1 S/ k
</li>$ _. [- P/ ?) z2 s. \- _
</ul>. z$ y8 o9 D! j+ X# o
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
9 M% q+ e+ z7 ~8 Y! `; q4 P4 G& X<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>* q+ Y. R4 B7 U  C
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>) d$ [( @' \/ w" D
<div class="suo-content"><div style="text-align: right;">
- D! U. y; F2 @& E: X                <div class="xControl"><i class="fa fa-caret-right"></i>
4 W! I) N1 K5 M. t& o" c* X& ^: P                        <span class="xTitle"></span>; x/ {5 n7 I" u2 J. r- c- F
                        相关讨论8 }+ R% n5 b" e$ Z5 ?( N9 f  W
                        <div style="clear: both;"></div>
- E7 W7 Q2 ~- l4 l  M                </div>
, q4 t4 S2 ]8 L+ x                <div class="xContent" style="display: none;"><p></p>
; e7 @) R4 {  u<ul>
( T2 D* I$ e" p, I- r9 o<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
$ U, H- m% Q6 T* l# {9 G</ul>
' L. O2 h7 |& {6 |  m6 v( J<p></p></div>
8 J" _/ D7 Y$ B! E6 ?8 X        </div><p></p></div>* N. r& n" C( y  I. A1 ?8 A
<hr></div>
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-4-13 01:36 , Processed in 0.409790 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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