我是SAS新手,我正在看这段代码:
libname FINAL 'C:\PERM';
%LET PERM_DB = C:\PERM_DB.ACCDB;
%LET PASS = 1234;
%LET EXTRA1 = _A;
%MACRO PERM(tablename);
PROC IMPORT OUT= FINAL.&tablename&EXTRA1 DATATABLE= "&tableACCESS&EXTRA1"
DBMS=ACCESS REPLACE;
DATABASE="&PERM_DB";
DBPWD="&PASS"; SCANMEMO=YES; USEDATE=NO; SCANTIME=YES; RUN;
%MEND PERM;
%PERM(table1);
%PERM(table2);
%PERM(table3);
%PERM(table4);
%PERM(table5);
%PERM(table6);
%PERM(table7);
%PERM(table8);
%PERM(table9);
%PERM(table10);
我在思考而不是重复那么多次宏,创建一个数组和一个循环来调用它。
Data test;
array perm{*} table1, table2,table3,table4,table5,table6,table7,table8,table9,table10;
max = DIM(perm);
DO i=1 to max;
%PERM(perm(i));
END;
run;
但它不起作用, 我在日志中收到此错误:
> > 1 FINAL.perm(1)_A
> > -
> > 22
> > --
> > 22
> > 202 ERROR 22-7: Invalid option name 1.
>
> > ERROR 22-322: Syntax error, expecting one of the following: ;, DATAFILE, DATATABLE, DBMS, DEBUG,
> FILE, OUT, REPLACE, TABLE, _DEBUG_.
>
> > ERROR 202-322: The option or parameter is not recognized and will be ignored.
我正在使用数组中的值1进行测试。
任何帮助或建议都会很棒。
输出应该是这样的:
FINAL.table1_A
但我正在
FINAL.perm(1)_A
谢谢。
答案 0 :(得分:1)
有一些方法可以解决这个问题。例如,搜索"数据驱动编程"我将展示两个:我喜欢的一个,以及很多人会建议的那个。
首先,流行的解决方案是进行宏循环。正确地说,我会用min和max参数编写一个宏,如下所示:
%macro perm(tablename);
%put &tablename;
%mend perm;
%macro import_data(min=1,max=);
%do _i = &min. %to &max.;
%perm(table&_i.);
%end;
%mend import_data;
%import_data(min=1,max=10);
显然你的真实%perm
不是我的榜样。它循环遍历从%perm
到&min.
的{{1}}来电。
其次,我认为真正的数据驱动在许多情况下是最好的。这假设你有一个表,某个地方每个表要导入一行 - 尽管你可以同样用上面的解决方案。
例如,假设您有一个Excel文件,并且它有一些您要导入的工作表。您可以使用&max.
获取这些工作表的列表,并自动导入每个工作表。
dictionary.tables
(假设libname imports excel "c:\temp\test_import.xlsx";
proc sql;
select cats('%perm(',memname,')')
into :calllist separated by ' '
from dictionary.tables
where libname='IMPORTS';
quit;
&calllist.
知道如何使用工作表名称导入数据。)如果您要从其他来源导入,则可以访问类似的元数据 - 通过SAS连接例如,通过%perm
或Oracle中的本地元数据。