2015-06-03 43 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