创建宏变量方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建宏变量方法相关的知识,希望对你有一定的参考价值。

参考技术A

方法1:通过宏函数创建宏变量
%let dsid=%sysfunc(open(sashelp.class));
%let nvars=%sysfunc(attrn(&dsid,nvars));
%let nobs=%sysfunc(attrn(&dsid,nobs));
%let dsid=%sysfunc(close(&dsid));
%put &nvars.;
%put &nobs.;

方法2:通过SQL过程用变量值创建一个宏变量
proc sql noprint;
select distinct sex
into : list_a separated by \' \'
from sashelp.class;
quit;
%put &list_a.;

方法3:通过SQL过程用变量值创建多个宏变量
proc sql noprint;
select nvar, nobs
into dictionary.tables
where libname=\'SASHELP\' and memname=\'CLASS\';
/ 注意SASHELP\'和CLASS要大写 /
quit;
%put &nvar.;
%put &nobs.;

方法4:通过CONTENTS和SQL过程用变量名创建宏变量
proc contents data=sashelp.class out=con_class;
run;
proc sql noprint;
select name,put(count(name),5,-1)
into :clist separated by \' \',:charct
from con_class
where type=2;
quit;
%put &clist.;
%put &charct.;

方法5:通过SQL过程用变量名创建宏变量列表
proc sql noprint;
select name
into :clist1-:clist999
from dictionary.columns
where libname=\'SASHELP\' and memname=\'CLASS\';
quit;
%put &clist1.;
%put &clist2.;

方法6:通过SQL过程用变量值创建宏变量列表
proc sql noprint;
select count(distinct sex)
into :n
from sashelp.class;
select distinct sex
into :type1 - :type%left(&n)
from sashelp.class;
quit;
%put &n.;
%put &type1.;

方法7:通过DATA步接口子程序CALL SYMPUTX
data null ;
set sashelp.class nobs=obs;
call symputx(\'m1\',obs);
call symput(\'m2\',obs);
stop;
run;
%put &m1.;
%put &m2.;

使用 __LINE__ 为不同的变量名创建宏[重复]

【中文标题】使用 __LINE__ 为不同的变量名创建宏[重复]【英文标题】:Creating macro using __LINE__ for different variable names [duplicate] 【发布时间】:2012-05-09 22:00:32 【问题描述】:

可能重复:Creating C macro with ## and LINE (token concatenation with positioning macro)

我正在尝试使用__LINE__ 宏来生成不同的变量名。我有一个名为 Benchmark 的范围基准类(位于 utils 命名空间中),它的构造函数接受一个字符串。这是我创建的宏定义:

#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))

不幸的是,这会导致以下错误:

<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization

这使我得出结论,__LINE__ 宏没有得到扩展。我根据this post 创建了我的宏。你知道为什么__LINE__ 没有得到扩展吗?

编辑:可能编译器信息也是相关的。我正在使用 Visual Studio 2010。

【问题讨论】:

嗯。你试过bm## __LINE__(带空格)吗? @Cameron 感谢您的评论,但没有任何改变。 好的,再尝试一个技巧:#define _BENCHMARK_SCOPE(line) utils::Benchmark bm##line(...#define BENCHMARK_SCOPE _BENCHMARK_SCOPE(__LINE__) @Cameron - 仍然无法正常工作。这是 ideone 上的一个示例:ideone.com/5r5l1(试图使其尽可能简单) 【参考方案1】:

您需要使用 2 个宏的组合:

#define COMBINE1(X,Y) X##Y  // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)

然后将其用作,

COMBINE(x,__LINE__);

【讨论】:

您知道我为什么需要为此使用两个宏吗? @izomorphius,实际上你的问题是另一个问题的重复,在那里它得到了很好的解释。我已经对你的问题发表了评论,请检查一下。【参考方案2】:

试试这个代码,我在旧项目中使用过它

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif 


int ANONYMOUS_VARIABLE(var)

编辑:

我认为您应该在 Visual Studio 中使用 COUNTER,前提是还使用预编译的标头。

【讨论】:

它也适用于 LINE【参考方案3】:

您正在使用令牌粘贴。这发生在递归宏之前 扩展(以便您可以标记粘贴以获取您的宏的名称 想调用)。因此:

#define PASTE(a,b) a ## b

将准确的参数粘贴到PASTE,然后尝试展开 生成的新令牌。为了达到你想要的效果,你需要一个 额外的间接级别:

#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)

这里,PASTE 的参数将在 PASTE_HELPER 之前展开 调用。

【讨论】:

以上是关于创建宏变量方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 __LINE__ 为不同的变量名创建宏[重复]

Grafana - 如何为 Mysql 数据源创建 sql 查询部分变量/宏

SAS:如何使用索引来挑选宏数组变量

Swift-Swift中的全局变量和函数的创建

创建 SAS 宏来处理任意数量的变量

创建SAS宏以处理任意数量的变量