Macros 宏增量

Macros 宏增量,macros,sas,Macros,Sas,我有如下表查找值 sno date 1 200101 2 200102 3 200103 4 200104 我在下面写道 %let date=200102 proc sql; select sno into :no from lookup where date=&date.; quit; 我需要一个关于如何将整个表查找转换为宏增量的帮助,方法是先创建s.no和date作为两个宏变量,然后创建increment。这样,我就不需要每次都更新表查找中的日期。因此,如

我有如下表查找值

sno date
1   200101 
2   200102
3   200103
4   200104
我在下面写道

%let date=200102
 proc sql;
 select sno into :no from lookup where date=&date.;
 quit;

我需要一个关于如何将整个表查找转换为宏增量的帮助,方法是先创建s.no和date作为两个宏变量,然后创建increment。这样,我就不需要每次都更新表查找中的日期。因此,如果我查找日期201304,我需要获取其对应的序列号,动态构建一个查找表,并为表中的每一行创建一个宏变量。宏变量将命名为
date\u 200101
date\u 200102
,…等等。它们将包含一个等于相应的
sno
值的值:

data lookup;
  length var_name $20;
  do sno = 1 to intck('month','01jan2001'd,date())+1;
    date = input(put(intnx('month','01jan2001'd, sno-1, 'beginning'),yymmn6.),best.);
    var_name = cats('date_',date);
    call symput(var_name, cats(sno));
    output;
  end;
run;
然后,您可以像这样引用宏变量:

%let date =200103;
%put &&date_&date;
……或者

%put &date_200101;

第一个使用示例是使用双宏分辨率。基本上,宏进程需要对宏标记
和&date\u和&date
执行两次迭代,才能完全解决它。第一次通过时,它被解析为
&date\u 200101
。在第二次传递时,如果要简单地将一个(唯一)值转换为另一个值,宏标记
&date_200101
将解析为
1
。您可以使用(in)格式。他们可以做的不仅仅是改变数据的读取/显示方式。它们易于使用,速度快(内存中),并且不依赖于创建的表。如果工作(=>临时库)不适合您的需要,请将库更改为永久库

options fmtsearch=(formats,work);

data fmt(keep = fmtname type start end label hlo default);
length fmtname $10 type $1 start end $6 label 8 hlo $1 default 8;
fmtname = 'date_to_no';
type = 'I';
label=0;
do y = 2001 to 2099;
    do m = 1 to 12;
        start = put(y,4.) || put(m,z2.);
        end = start;
        label + 1; 
        default=50; /*default length of the string compared when informat is used. Should be higher than both start and end*/
        output;
    end;
end;
/*if you want to assign a value (=label) to inputs not found. In this case it's -2*/
hlo="O";
start = "";
end = start;
label= -2;
output;
run;

proc format library=work cntlin=fmt;
run;

data test;
no = input('200101',date_to_no.); output;
no = input('201710',date_to_no.); output;
no = input('201713',date_to_no.); output;
run;

SNO值是否存在模式?从2001年1月1日开始,你基本上是在计算月份数吗?如果是,则使用
INTCK()
函数

data test;
  input date yymmdd8. ;
  format date yymmdd10. ;
  sno = 1+intck('month','01JAN2001'd,date);
cards;
20010112
20010213
20010314
20010415
;
因此,您可以创建两个宏变量。一个带有基准日期,另一个带有基准SNO值

36   %let basedate='01JAN2001'd ;
37   %let basesno=1;
38   %let date='01JAN2001'd ;
39   %let sno=%eval(&basesno + %sysfunc(intck(month,&basedate,&date)));
40   %put &=date &=sno;
DATE='01JAN2001'd SNO=1
41
42   %let date="%sysfunc(today(),date9)"d;
43   %let sno=%eval(&basesno + %sysfunc(intck(month,&basedate,&date)));
44   %put &=date &=sno;
DATE="16NOV2017"d SNO=203

我不想要查找表。我想创建一个初始值为111,日期为200101的宏,然后执行增量…这样我就可以删除查找表并只使用它macros@suresh您可以在执行
call symput
步骤后删除查找表,它仍然可以工作。查找表只是为了简化宏的创建。哦,我明白了,你根本不想编辑查找表。我会编辑我的答案。你发布的不是宏,只是一些SAS代码。请注意,定义宏变量DATE的
%let
语句缺少结束它的分号。感谢您的代码,它确实起作用了。。。我还需要一个帮助,如何将所有这些sno放在单独的数据集中我不知道单独的数据集是什么意思。您是否有要计算SNO值的日期数据?如果是,则直接在数据步骤中使用
INTCK()
函数。在处理数据时不需要复杂的宏逻辑。也许你可以用细节开始一个新问题。