2015-06-03 41 views
1

我试图使用从CSV文件中检索单个值的宏。如果只有一个CSV文件,我已经写了一个完美的MACRO,但是当我不得不针对多个文件运行它时不能提供预期的结果。如果有多个文件,它将返回每次迭代中最后一个文件的值。从CSV文件中导入不适用于SAS的单个值

%macro reporting_import(full_file_route); 


%PUT The Source file route is: &full_file_route; 
%PUT ##############################################################; 

PROC IMPORT datafile = "&full_file_route" 
    out = file_indicator_tmp 
    dbms = csv 
    replace; 
    datarow = 3; 
RUN; 

data file_indicator_tmp (KEEP= lbl); 
    set file_indicator_tmp; 
     if _N_ = 1; 
     lbl = "_410 - ACCOUNTS"n; 
run; 

proc sql noprint ; 
    select lbl 
    into :file_indicator 
    from file_indicator_tmp; 
quit; 

%PUT The Source Reporting period states: &file_indicator; 
%PUT ##############################################################; 

%mend; 

这是我执行宏的地方。每个excel文件的完整路径作为名为“HELPERS.RAW_WAITLIST”的数据集中的单独记录存在。

data _NULL_; 
set HELPERS.RAW_WAITLIST; 
    call execute('%reporting_import('||filename||')'); 
run; 

在我刚刚跑过的一个例子中,一个文件包含01-JUN-2015和另一个02-JUN-2015。但是代码在LOG文件中返回的结果是:

The Source file route is: <route...>\FOO1.csv 
############################################################## 
The Source Reporting period states: Reporting Date:02-JUN-2015 
############################################################## 
The Source file route is: <route...>\FOO2.csv 
############################################################## 
The Source Reporting period states: Reporting Date:02-JUN-2015 
############################################################## 

有没有人明白为什么会发生这种情况?或者,有没有更好的方法来解决这个问题?

UPDATE:

如果我从宏观上删除代码,然后手动为每个输入文件运行它,它完美。所以它必须与MACRO覆盖值有关。

+1

如果您不使用call execute并每次调用宏,会发生什么情况?另外,您是否可以写一个数据步骤来读取CSV文件,而只读取第一行? – Reeza

回答

2

调用execute有棘手的时机的问题。当它调用宏时,如果该宏从数据集变量中生成宏变量,则将宏调用包装在%NRSTR()中是一个好主意。这种方式调用execute会生成宏调用,但并不实际执行宏。因此,请尝试将您的致电执行语句更改为:

call execute('%nrstr(%%)reporting_import('||filename||')'); 

我发布了更长的解释here

+0

这完美地解决了这个问题。谢谢 – Herm

1

我不太清楚你的文件之间的连接。但是,不是导入CSV文件,然后搜索字符串,难道您不能使用pipe command将CSV文件的grep搜索结果保存到数据集中,然后在结果中只读?

更新:

我试图在本地复制您的问题和它的作品对我来说,如果我设置file_indicator与symput调用下面,而不是你的into :file_indicator

data file_indicator_tmp (KEEP= lbl); 
    set file_indicator_tmp; 
    if _N_ = 1; 
    lbl = "_410 - ACCOUNTS"n; 
data _null_ ; 
    set file_indicator_tmp ; 
    if _n_=1 then call symput('file_indicator',lbl) ; 
run; 
+0

这是一个有趣的方法,我一定会调查,但我认为这使得这个非常简单的问题有点太复杂。 – Herm